Silverlight: Создание сложной трехмерной анимации с помощью Silverlight 2.0Добро пожаловать | ВходРоссия - русский Argentina (Español)Australia (English)Brasil (Português)Canada (English)Canada (Français)中国 (简体中文)Colombia (Español)Deutschland (Deutsch)España (Español)France (Français)India (English)Italia (Italiano)México (Español)Perú (Español)Россия (Pусский)United Kingdom (English)United States (English)Дополнительно… | Microsoft.com ПродуктыOfficeWindowsWindows Server SystemДля разработчиковMicrosoft DynamicsРесурсыMicrosoft UpdateOffice UpdateЦентр загрузкиСправка и поддержкаБезопасностьЛицензированиеО корпорации MicrosoftО компанииПресс-службаПолезные ссылкиIT-профессионаламБезопасность домаКрупному бизнесуМалому бизнесуMicrosoft для партнеровВсе продуктыКарта сайта.scopeArrow{margin-top: -1px;padding-top: 2px;padding-right: 18px;}.TabStrip_SearchBox{padding: 0px 2px 0 2px;height: 19px;} Поиск по MSDNПоиск по Microsoft.comПоиск Windows LiveMSDN MagazineHomeSubscribeReader ServicesCommunityCurrent Issue| Topics| Issues| Authors| Columns| Html Help Files| Code Downloads| RSS .tbfont{ font-size: 70%;} версия для печати ОтправитьЩелкните, чтобы оценить и отправить отзыв Отправить отзыв на это содержаниеMSDNГлавная страница MSDNБиблиотека MSDNОбучение MSDNФайлы для загрузки MSDNПоддержка MSDNСообщество MSDNDeveloper Centers.NET FrameworkASP.NETOfficeSQL ServerVisual BasicVisual C++Visual C#Visual StudioVisual Studio ExpressWindows VistaMoreMSDN MagazineHomeSubscribeReader ServicesCommunityHomeCurrent IssueTopicsIssuesAuthorsColumnsHtml Help FilesCode DownloadsRSSIssues2008200720062005200420032002200120002008AprilMarchLaunchFebruaryJanuaryAprilОтвет: Создание потоков работ голос...Производительность: Стратегии масшт...Silverlight: Создание сложной трехм...Интервью++: Бьерн Страуструп об эво...Разработка для Office: Управление м...Поездки: Подготовка мобильных устро...Колонка редактора: Ориентированная ...Инструментарий: Ведение журнала оши...CLR вдоль и поперек: Часто и своевр...Бейсиковые инстинкты: Расширения пр...На переднем крае: Советы и приемы п...Системы Foundation: Разграничение д...Тестовый прогон: Тестирование храни...Станция техобслуживания: Создание м...Windows и C++: Основы компонента об...{ End Bracket }: Магия программного... Silverlight: Создание сложной трехм...Share this PageLive FavoritesDotNet KicksDiggSlashdotdel.icio.usNingTechnoratima.gnoliaredditRelated ArticlesОтвет: Создание потоков работ голосового интерфейса при помощи Speech Server 2007Система Speech Server 2007, объединяя средства Microsoft .NET Framework и Visual Studio, позволяет создавать сложные приложения с голосовым интерфейсом. В статье описано, как это делается.By Michael Dunn (April 2008)Производительность: Стратегии масштабирования для приложений ASP.NETПроблемы с производительностью могут поразить веб-приложения при их масштабировании вверх и, в таком случае, возникает необходимость найти причины этого, а также лучшие стратегии их устранения.By Richard Campbell and Kent Alstad (April 2008)Поездки: Подготовка мобильных устройств.Узнайте, как можно настроить все мобильные устройства в своей компании с помощью нескольких строчек кода и небольшого количества XML – благодаря интерфейсам API подготовки в комплекте SDK для Windows Mobile.By Mike Calligaro (April 2008)Инструментарий: Ведение журнала ошибок веб-приложений, изучение LINQ и многое другое.Познакомьтесь с ведением журнала ошибок веб-приложений в целях улучшения наблюдения за работоспособностью, а также с рекомендуемыми Скоттом в этом месяце блогами и литературой по LINQ.By Scott Mitchell (April 2008)More ...Popular ArticlesПоездки: Подготовка мобильных устройств.Узнайте, как можно настроить все мобильные устройства в своей компании с помощью нескольких строчек кода и небольшого количества XML – благодаря интерфейсам API подготовки в комплекте SDK для Windows Mobile.By Mike Calligaro (April 2008)Увеличение гибкости: Приручите программные зависимости для большей гибкости приложенийДжеймс Ковач представляет читателям темную сторону тесно связанной архитектуры, рассказывает о проблемах, возникающих при тестировании и адаптации, и предлагает некоторые решения.By James Kovacs (March 2008)Первое знакомство с F#: Использование приемов функционального программирования в .NET FrameworkВ данной статье мы затронем основные понятия, лежащие в основе нового языка F#, сочетающего в себе элементы функциональных и объектно-ориентированных языков .NET. Мы напишем первые простейшие программы на F#.By Ted Neward (Launch 2008)Интервью++: Бьерн Страуструп об эволюции языковГовард Дайеркинг разговаривает с создателем языка C++, Бьерном Страуструпом, о приверженцах языка, развитии программирования и его будущем.By Howard Dierking (April 2008)More ...Read the BlogCLR Inside Out: Measure Early and Often for PerformanceMany applications are written with almost no thought given to performance. But when the need for high performance does present itself, do you have the knowledge, skills, and tools to do a good job? In the April 2008 issue of MSDN Magazine, Vance ...Read more!Bjarne Stroustrup interviewRecently, our Editor in Chief Howard Dierking had the pleasure of talking to Bjarne Stroustrup, the creator of C++, about a host of topics, from his thoughts on languages to general industry trends to his own personal reading list. We feature the interview in the April ...Read more!Free tools you may have missedScott Mitchell in our Toolbox column has covered quite a few free tools you’ll love. Here are some you may have missed from Scott and some of our other authors as well. Check back again for more free tools next time. SubSonic is an application toolset that is centered on its ability to completely ...Read more!Building Voice Response WorkflowsNeed an interactive voice response application for your organization's phone system? Office Communications Server (OCS) 2007 Speech Server introduces a .NET Framework API for creating IVR applications, plus a visual IVR application designer based on Windows Workflow Foundation. In the April 2008 issue of MSDN ...Read more!Windows with C++: Windows Imaging Component BasicsThe Microsoft Windows Imaging Component (WIC) is an extensible framework for encoding, decoding, and manipulating images. WIC supports different image formats using an extensible set of imaging codecs. Each codec supports a different image format and typically provides both an encoder and decoder. In the April 2008 issue of MSDN ...Read more!April 2008 issue of MSDN Magazine now onlineThe April 2008 issue of MSDN Magazine is now available online. In the April issue, we take a look at some new technologies like voice apps and Silverlight animations, plus a look back at performance and scaling optimization. ...Read more!More ...Silverlight Создание сложной трехмерной анимации с помощью Silverlight 2.0 Деклан Бреннан (Declan Brennan) В статье рассматривается: Основы XAML Создание элементов в XAML Как сложить многогранник Имитация математики DirectX Продукты и технологии: Silverlight СодержаниеИспользование XAML Несколько примеров XAML Советы по работе с XAML Как сложить многогранник Имитация математики DirectX Что стоит изучить дальше Если, по невероятной случайности, все новости о SilverlightTM за последние несколько месяцев миновали кого-либо из читателей, то позвольте мне напомнить: Silverlight – это подключаемый модуль для набора обозревателей от корпорации Майкрософт, позволяющий применить возможности Microsoft® .NET Framework в области, где ранее господствовали Flash и приложения Java. Silverlight обладает массой полезных встроенных функций. Он поддерживает минимизированную версию .NET Framework 3.5, которая, помимо прочего, включает в себя XML и расширяемый язык разметки приложений (XAML), универсальные коллекции, веб-службы и LINQ. Silverlight также поддерживает набор совместимых с .NET языков, но здесь я сосредоточусь на C#. Я полагаю, что лучший способ освоиться с новой технологией – это проделать с ней что-нибудь интересное. Поэтому, когда была выпущена альфа-версия Silverlight 1.1 и я увидел захватывающую презентацию Тима Снита (Tim Sneath) на конференции IMT в Дублине, я решил соорудить небольшое обучающее приложение, демонстрирующее, как можно собирать различные трехмерные формы (именуемые многогранниками), путем складывания плоского шаблона. По умолчанию Silverlight не поддерживает трехмерность, так что эта работа включила в себя создание имитации библиотек DirectX® для работы с ней. Многогранник – это трехмерный объект с плоскими сторонами. Данный образец Silverlight исследует эти геометрически правильные и частично геометрически правильные многогранники, именуемые платоновыми и архимедовыми многогранниками соответственно. Все стороны этих многогранников являются геометрически правильными многоугольниками (все их стороны имеют одну длину), такими как квадраты или равносторонние треугольники. Они также являются выпуклыми, то есть не имеют выступающих частей. Как можно догадаться по древнегреческим названиям, такие объекты притягивали к себе внимание в течение долгого времени. Те, кто заинтересовался ими, могут найти много дополнительной информации на веб-узле Джорджа Харта (George Hart): georgehart.com/virtual-polyhedra/vp.html. Демонстрационную версию законченного приложения можно увидеть на рис. 1 или на picturespice.com/ps/Polyhedra/default.html. По сути, приложение позволяет выбрать форму (многогранника), наведя на нее курсор. После этого в правом верхнем углу окна появляется некоторая информация о выбранном варианте, а также появляется анимация плоского шаблона, свертывающегося для образования выбранного многогранника. Наконец, в случае нажатия кнопки Cycle («Перебор»), программа автоматически перебирает каждую из форм по очереди. Figure 1 Silverlight Demonstration of Polyhedra (Щелкните изображение, чтобы увеличить его) Использование XAML Подобно многим приложениям Silverlight, Polyhedra активно использует XAML, являющийся языком определения содержимого – своего рода эквивалентом HTML, но более гибким. Продолжая аналогию, хотя и возможно создать страницу HTML, используя только объектную модель документа (DOM) HTML, это редко является разумным способом создания содержимого – написание кода часто отбирает много времени, а получающиеся страницы медленно инициализируются. Почти всегда лучше сохранить настолько большую часть страницы, насколько можно, как разметку HTML и дополнить ее там, где необходима гибкость, используя JavaScript и DOM. Весьма похожий подход применим к XAML. Наиболее быстрым способом внесения содержимого является максимальное использование разметки XAML и дополнение ее там, где необходимо, используя совместимый с .NET язык, такой как C# и API-интерфейсы мультимедиа Silverlight. XAML может запрограммирован вручную, произведен пакетом разработки, таким как Expression BlendTM, создан программой, запускаемой в ходе процесса разработки, или даже динамически создан на сервере. Это может потребовать изменения в привычках. Программист, работающий C#, слишком легко может взяться за кодирование функций в естественной среде, которую лучше всего оставить XAML. Мало-мальски подробное рассмотрение XAML, выходит за рамки этой статьи. Однако, детальнейшее освещение XAML имеется в книге Чарльза Петцолда (Charles Petzold) «Applications= Code+Markup» («Приложения=Программный код+Разметка»). Вот эквивалент примера "Hello World", который все уже привыкли ожидать при изучении новых языков, в XAML: Hello World Корневой элемент – это UserControl. Он содержит элемент Grid («Таблица»), которая в свою очередь, содержит элемент TextBlock с текстом "Hello World". Взгляните на атрибуты UserControl. Не углубляясь в излишние подробности, скажу, что это определяет эквивалент класса фонового кода для XAML. Экземпляр этого класса создается одновременно с анализом и загрузкой XAML. Различные элементы инициализации можно выполнять и в конструкторе, но чтобы добиться более сложного поведения часто необходимо применять обработчики событий. Это ключевой компонент Silverlight. Обработчики событий могут быть присоединены к различным объектам XAML и выполнены в любом, совместимом с .NET, языке по выбору – языке, который, в отличие от JavaScript, скомпилирован и, следовательно, открывает разного рода возможности, которые иначе были бы непрактичны. Возвращаясь к аналогии с HTML, элементы часто группируются внутри различных DIV для размещения их на странице. Точно таким же образом в XAML формы группируются внутри элементов Canvas (или других элементов, таких как Grids, являющихся типами Canvas). Точно так же, как элементы DIV часто вкладываются в HTML, Canvas могут быть вложены в XAML. Большинство элементов в HTML имеют прямоугольную форму. Однако, XAML поддерживает широкий спектр форм, включая TextBlock («Блок текста»), Rectangle («Прямоугольник»), Polygon («Многоугольник»), Ellipse, («Эллипс») и очень гибкий Path («Путь»), допускающий определенные пользователями формы. Элементы в HTML опознаются по атрибуту ID, а эквивалентным атрибутом опознания элемента в XAML является x:Name, где x – это псевдоним пространства имен XAML. XAML отнюдь не ограничивается созданием статичных страниц. Одной из его наиболее мощных функций является использования раскадровок как способа анимировать изменения в первоначальном интерфейсе пользователя, указанном XAML. (Нечто подобное под названием HTML+Time было добавлено в HTML в Internet Explorer® 5.0) Примером может послужить анимация изменения цвета, видимости или прозрачности объекта. При использовании в сочетании с преобразованиями, раскадровки могут также вращать, масштабировать или перемещать объекты. Раскадровки могут создавать все виды анимационных эффектов, задействуя очень немного обычного кода. При использовании их в сочетании с триггерами, теоретически возможно запускать различные анимации автоматически, когда на объекте происходит событие вроде MouseEnter. Увы, в бета-версии Silverlight 2.0 за март 2008 года, единственным событием, обрабатываемым триггером, является Loaded («Загружено»). Чтобы создать обработчики для других событий, необходимо некоторое количество коммуникационного кода. Я думаю, что такое положение скоро изменится, если уже не изменилось. Полезной особенностью раскадровок в Silverlight является их основанность на времени, а не на кадрах. Использование нескольких независимых раскадровок, привязанных к различным временам и событиям, может сделать простой реализацию сложного поведения. В конце концов, реальный мир не работает в кадрах – это остаток от способа, которым движущееся изображение достигалось на целлулоидных лентах. Если независимые объекты реализовывать с независимыми поведениями, это сильно упрощает жизнь. Несколько примеров XAML Анимация складывания в середине приложения Polyhedra создается с использованием кода C#. Однако, основная часть всего прочего определена в XAML. Это включает в себя круг примеров многогранников, способы уделения внимания многограннику, выбранному в настоящий момент и кнопку Cycle («Перебор»), активность которой демонстрируется посредством анимации вращающейся стрелки. Давайте взглянем на ряд исключений из Page.xaml, чтобы увидеть, как достигаются эти анимации, начиная с взгляда на кнопку Cycle, показанную на рис. 2. Взгляните на Path, именуемый Cycle. Атрибут данных указывает ряд операций, включая M для перемещения, A для дуги и L для линии. Поскольку это довольно нехитрый глиф, я просто нарисовал нужную форму на листе бумаги и вручную выработал необходимые операции. В большинстве случаев лучше использовать для этого такие средства, как Expression Design. Figure 2 Кнопка Cycle («Перебор») У этого пути также имеется RotateTransform, именуемый CycleRotate. Первоначально это преобразование не делает ничего, поскольку его угол установлен на 0. Однако, существует раскадровка под названием CycleLatched, которая, когда активна, постоянно изменяет угол на небольшие значения, что ведет к вращению стрелки. Рис. 3 показывает, как определен один из примеров многогранника. Внизу этого XAML можно увидеть пример, состоящий из четырех многоугольников, определяющих тетраэдр. Они находятся внутри собственного полотна («Canvas»), именуемой Model0 и окружены кольцом («Ellipse»), именуемым Ring0, которое первоначально невидимо. Определены две анимации раскадровки, одна для MouseEnter и вторая для MouseLeave. Анимация MouseEnter делает кольцо немедленно видимым, увеличивает размер полотна Model0 и делает его менее прозрачным на 0,7 секунды. Анимация MouseLeave отменяет эти изменения. Figure 3 Пример многогранника Поскольку раскадровки могут работать независимо, все происходит как можно ожидать, вне зависимости от того, насколько быстро пользователь перемещает мышь. Как правило, анимация MouseLeave для одного из образцов будет происходить параллельно анимации MouseEnter для свежевыбранного образца. Однако, это не доставит никаких хлопот, поскольку Silverlight автоматически обработает параллельную работу нескольких раскадровок. Немного отвлекаясь, можно спросить себя, как были вычислены углы каждого из четырех многоугольников в образце тетраэдра, не говоря уже о намного большем числе многоугольников для каждого из прочих образцов в приложении. Я твердо верю в подход лентяя – не делай сам ничего такого, что компьютер мог бы сделать быстрее. Так что в данном случае я просто использовал измененную версию Polyhedra в процессе работы. Эта версия выполняла один кадр центральной анимации для каждого из образцов по очереди – кадр с полностью закрытой формой. Я поместил каждую из получившихся групп многоугольников в набор полотен, которые были равномерно распределены вокруг круга и перекачал все это в файл для использования основной программой. Размещение объектов вокруг круга включило в себя увеличение угла на равные промежутки 2*PI/NumSamples, с последующим указанием центра каждого образца, при помощи координат x= Radius*Cos(Angle), y=Radius*Sin(Angle). Также, поскольку полотна, размещающие объекты, используют свойства Left («Лево») и Top («Верх»), мне требовалось сместить центр на половину ширины и половину высоты, соответственно. Советы по работе с XAML Как можно увидеть, при помощи одного XAML, почти без дополнительного кода, можно создать довольно насыщенный интерфейс пользователя. Инициализация удивительно быстра даже для большого файла, вроде Page.xaml. Но перед тем, как двинуться дальше, я хотел бы дать несколько советов, основываясь на опыте работы с текущей реализацией (бета-версией за март 2008 года) Silverlight 2.0. Как я уже упомянул, в настоящий момент триггеры могут автоматически запустить раскадровку, посредством метода Begin («Начать») только для события Loaded. Чтобы создать обработчики для других событий необходимо некоторое количество коммуникационного кода, вроде следующего: public void MouseEnterHandler( object o, EventArgs e) { this.MouseEnterStoryBoard.Begin(); } Если принять определенную схему наименования для раскадровок, скажем имя объекта, за которым следует имя события, можно серьезно сократить число отдельных обработчиков событий, которые необходимо запрограммировать. Например, этот метод используется в Polyhedra как общий обработчик событий для всех примеров в круге: public void MouseEnterHandler( object o, EventArgs e) { this.triggerStoryboard(o,"MouseEnter"); } private bool triggerStoryboard( object o, string eventType) { Canvas el = o as Canvas; string name= el.GetValue(NameProperty) as String; Storyboard sb = el.FindName(name + eventType) as Storyboard; if (sb != null) sb.Begin(); return (sb != null); } С появлением бета-версии Silverlight 2.0, основная инициализация (именуемая InitComponents) переместилась из обработчика события Loaded в конструктор для объекта фонового кода. Это решение более элегантно, но следует знать, что в конструкторе возможно не все. Например, на раскадровке здесь нельзя вызвать Begin или Pause – это все еще необходимо сделать в обработчике событий. Как я обнаружил благодаря образцу Silverlight от Анди Болье (Andy Beaulieu) Rocks!, посвященному расстрелу астероидов (www.andybeaulieu.com/Home/tabid/67/EntryID/73/default.aspx), хорошим способом создать анимацию на основе кода является использование раскадровки, установленной на короткий временной период и наличия обработчика событий Completed («Завершение»), который выполняет кадр анимации и затем перезапускает раскадровку: public Page() { // Constructor for "code-behind" // Required to initialize variables InitializeComponent(); this.animationTimer.Completed += new EventHandler(animationTimer_Completed); } void animationTimer_Completed(object sender, EventArgs e) { [ Do a frame of animation ] this.animationTimer.Begin(); } Сентябрьское обновление альфа-версии Silverlight 2.0 Alpha изменило требования к раскадровкам, так что анимация теперь должна иметь цель, даже если она не используется: Не пытайтесь разместить много отдельных элементов управления Silverlight на одной странице HTML. Моя первая версия Polyhedra использовала отдельный элемент управления для каждого образца в круге – и просто пожирала память. Во многих случаях это означает перенос содержимого из HTML в XAML для уменьшения числа используемых элементов управления. Одно из преимуществ XAML состоит в том, что он снимает с плеч разработчика значительную часть рутинной работы над интерфейсом пользователя, позволяя сосредоточиться на творческой работе над кодом, требуемым областью задач. В данном случае, область задач включает в себя складывание шаблонов для образования трехмерных форм, что ведет нас к следующему разделу. Как сложить многогранник Я подозреваю, что ранее упомянутая книга Чарльза Петцольда является адаптацией гораздо более старой, появившейся до объектной ориентированности, книги Никласа Вирта (Niklaus Wirth), именуемой «Algorithms+Data Structures=Programs» («Алгоритмы+Структуры данных=Программы»). Даже по прошествии многих лет она остается одной из наиболее повлиявших на меня когда-либо книг, являясь, несмотря на все изменения в языках и парадигмах с тех пор, актуальной по сей день. Основное положение книги заключается в подходе к разработке, состоящем из определения структур данных, способных наилучшим способом смоделировать проблему, с последующим определением того, какие алгоритмы могут обработать или изменить эти структуры данных. Именно такому подходу я обычно следую при работе над нестандартными программами. Я перепробовал различные подходы, прежде чем остановиться, наконец, на использованном в Polyhedra. Я хотел увидеть, с насколько малого объема информации я могу начать, чтобы добиться анимации складывания. Получилось, что в силу равной длинны всех сторон, почти возможно сделать все основываясь лишь на знании, какие стороны присоединены к которым в определенном многограннике. В силу этого напрашивается структура данных в виде графика. Перед достижением итоговых выходящих данных XAML, набор алгоритмов используется для обработки графика через две отдельные структуры данных. Более подробные все это будет изложено ниже. Хотя Windows® Presentation Foundation (WPF) и может поддерживать трехмерность в XAML, Silverlight по умолчанию поддерживает только двухмерность, поскольку совместимости с различными обозревателями гораздо проще добиться, когда не надо беспокоиться о графическом процессоре (Graphics Processing Unit – GPU) компьютера. Само собой, если глядеть в корень, то трехмерное изображение на экране компьютера является иллюзией. Какие бы манипуляции с ним не производились, в конечном итоге на поверхности монитора изображается обычный набор двухмерных многоугольников. Для тех, кто желает заняться работой с трехмерностью в собственном коде для вычисления координат этих многоугольников, доступна обработка трехмерных изображений без аппаратного ускорения. Если оставаться в рамках нескольких десятков многоугольников, производительность остается приемлемой. (По моему субъективному мнению, производительность кадров улучшилась в бета-версии, по сравнению с альфой.) При выборе формы, создается двухмерный, несложенный шаблон, именуемый Net (ничего общего с .NET). Это проделывается в два этапа, как показано на рис. 4. Сперва в памяти выстраивается график, с одним GraphNode соответствующим каждой грани в форме (см. Graph.cs). График создается путем потоковой передачи набора сведений о соединениях (указывающих, какие стороны соединены с какими) из одного из ресурсов .shp, внедренных в сборку приложения. Например, вот содержимое cube.shp: 0) this.src=small; if (current.indexOf(small) > 0)this.src=large;" /> Figure 4 Building the Shape, from Graph to XAML (Щелкните изображение, чтобы увеличить его) 1:3,4,5,2 2:1,5,6,3 3:2,6,4,1 4:3,6,5,1 5:1,4,6,2 6:2,5,4,3 Любой GraphNode в графике может затем быть выбран как первый узел, с которого начинается создание Net (подробности см. Net.cs в прилагающемся к данной статье коде). Затем создается двухмерный FlatFace, с числом сторон, равным числу соседей GraphNode. Любой соседний GraphNode после этого выбирается для повторения процесса, размещая следующий FlatFace, так чтобы он имел общую сторону с текущим. Каждый GraphNode посещается лишь однажды и процесс повторяется, пока не посещены все GraphNodes, приводя к появлению древоподобной структуры FlatFaces. В каждом кадре трехмерной анимации из Net создается трехмерный многогранник (возможно частично закрытый) – подробности операции см. ниже в Polyhedron.cs. Это включает в себя копирование дерева FlatFaces в дерево сторон, с заменой двухмерных угловых точек на трехмерные. (Рис. 5 показывает две системы координат. Поскольку я хочу начать в горизонтальной плоскости, ось Y должна начинаться с нуля. Так что я перевожу двухмерное изображение в трехмерное, устанавливая X=X, Y=0 и Z=Y.) 0) this.src=small; if (current.indexOf(small) > 0)this.src=large;" /> Figure 5 Transforming Points from 2D to 3D (Щелкните изображение, чтобы увеличить его) Наконец, используется рекурсия для посещения каждого соединения в дереве сторон и выполнения складывания. Размах складывания является частью угла (именуемого двугранным углом), под которым стороны будут находиться друг к другу после полного закрытия формы. В теории, двухмерные углы можно вычислять напрямую, используя только информацию о соединениях в файле .shp. Это довольно просто для особых случаев, скажем встречи трех сторон в углу, или встречи в углу любого числа сторон одного типа. Однако, общий случай несколько более сложен, так что я решил сохранить эти углы в отдельных ресурсах .dihedrals. Например, вот отрывок из cube.dihedrals: 1,3:1.5707965056551 1,4:1.57079661280793 1,5:1.57079614793469 1,2:1.57079604078186 2,1:1.57079604078186 2,5:1.57079628466395 2,6:1.57079661280793 2,3:1.57079636892585 3,2:1.57079636892585 3,6:1.57079614793469 3,4:1.57079628466395 .. Мелкие различия в этих цифрах, которые, в данном случае, все должны равняться PI/2, являются просто следствием способа их вычисления. Завершающий процесс включает в себя серию преобразований для проекции представления многогранника на монитор, как набора многоугольников. Можно заметить, что в ходе анимации складывания многогранник также вращается вокруг вертикальной оси. Чтобы добиться этого, я преобразую точку поворота в исходную, выполняю вращение и затем преобразую ее в точку зрения. Затем я выполняю трансформацию перспективы, чтобы сильно удаленные объекты (на оси Z) казались меньше. (В следующем разделе, я объясню, как проделывать трансформации, чуть подробнее.) Наконец, создается набор многоугольников XAML, в соответствии с проекцией трехмерной формы на экран монитора. Silverlight затем принуждается рисовать эти многоугольники задом наперед, посредством установки свойстваXAML ZIndex для каждого многоугольника, используя координату Z центра трехмерного многоугольника (отмасштабированного для помещения float в int). Это довольно простой способ достижения трехмерности, работающий только в случаях если поведение многоугольников не включает, скажем, пересечений – но для данного примера он подходит. Более продуманные формы трехмерности включают механизмы вроде буферов глубины. Поскольку они требуют доступа к GPU, то они выходят за пределы «песочницы» .NET Silverlight. В качестве последнего мазка, XAML позволяет многоугольникам быть частично прозрачными (используя свойство Opacity («Прозрачность»), дающее артистический эффект многоугольника, через который можно что- man man certification microsoft babyliss 2-79 - k800i black decker : . tognana dhl soflens comfort - - xxx shell russia music awards . isdn ariston mobihel