Оглавление
5. XSLT-генераторы X3D-моделей ПВСТ
6. Анимация ПВСТ по минимаксным значениям относительных
углов поворота тел
7. Анимация ПВСТ по таблице программных движений
Web-разработки можно разделить на три уровня сложности.
На первом уровне используются декларативные языки (X3D, XHML, SVG и др.). На
втором уровне применяются скрипты, например, JavaScript, позволяющие в языках разметки использовать фрагменты
кода для увеличения его функционала, т.е. решения задач, не свойственных
конкретному языку разметки. На третьем уровне используются высокоуровневые
языки программирования (Java, C++ и др.). Язык XSLT предназначен для разработок 1-го уровня (уровня
разметки), так как он обеспечивает декларативное решение для большинства задач
описания данных и их визуализации.
Преобразование данных и их визуализация – разные
задачи. Во-первых, преобразованные данные используются в программах их дальнейшей
обработки. Они могут быть входными данными для очередного этапа (шага)
преобразования. Во-вторых, в преобразуемых данных должно быть минимальное
количество элементов разметки с короткими именами. В-третьих, визуализация
предназначена для пользователя (человека). В данных, подготовленных к
публикации, как правило, много текса, элементов оформления, включая мультимедийные.
1. Основы XML
В 60-е годы прошлого столетия корпорация IBM приступила к созданию и в 1981 году был создан
обобщенный язык разметки GML (Generalized Markup Language), т.е. новый способ
описания различной информации и обмена документами, независимый от платформ и
устройств. В 1986 году появился стандарт ISO 8897, где международная организация по стандартизации
(International Standards Organization)
одобрила одну из версий языка GML, который
стал называться стандартным обобщенным языком разметки SGML (Standard
Generalized Markup Language). SGML предоставил пользователям гибкий способ создания
собственных форматов документов. Это метаязык (язык описания языков),
позволяющий создавать новые языки разметки информации. Он используется в армии
и правительстве США, в аэрокосмическом секторе и других отраслях. Авторский
(корпоративный, отраслевой и т.д.) язык разметки документов создается путем
определения набора элементов (тегов) с атрибутами, а также установлением
"родственных" взаимоотношений между элементами. Каждый новый язык
разметки, созданный при помощи метаязыка SGML, называется SGML-приложением.
Ему, как правило, дают собственное имя и аббревиатуру. Например, в начале 90-х
годов консорциум W3C (World
Wide Web Consortium) создал язык разметки
гипертекстов HTML (Hypertext Markup Language), который является SGML-приложением, предназначенным для разметки гипертекстовой
информации с целью ее визуализации при помощи браузера (специальной программы)
в виде Web-страниц.
Создать на метаязыке SGML свой собственный язык разметки очень сложно. Официальная
спецификация SGML занимает более 150 страниц
технического описания с множеством особых случаев и маловероятных вариантов их
использования. Поэтому в 1996 году группа специалистов из W3C приступила к
созданию облегченной версии SGML с сохранением большинства широко используемых и
мощных средств SGML и отбрасыванием редко
используемых и сложных в применении средств. Так в 1988 году появился расширяемый
язык разметки XML (eXtensible Markup Language). Это не SGML-приложение, это упрощенный аналог (вариант, подмножество)
SGML. Официальная спецификация XML занимает менее 50 страниц. Изложить основы метаязыка XML (на 80%) можно за один академический час. XML позволяет создавать авторские языки разметки, называемые
XML-реализацией. В W3C создано несколько XML-реализаций, которым даны собственные имена и аббревиатуры:
1. Язык описания схемы XML-документа – XSD (XML Schema Definition Language).
2. Язык ссылок (связей между документами) – XLink.
3. Язык указателей (связей между элементами и
символами) – XPointer.
4. Язык разметки двухмерной графики (масштабируемая
векторная графика) – SVG (Scalable Vector Graphics).
5. Язык разметки форм ввода информации – XForms.
6. Язык интеграции синхронизированной
мультимедиа-информации – SMIL (Synchronized Multimedia Integration Language).
7. Язык разметки математических формул – MathML.
8. Язык размеки химической информации – CML (Chemical
Markup Language).
9. Расширяемый язык таблиц стилей для трансформации – XSLT (eXtensible Stylesheet Language for Transformation).
10. Расширяемый язык таблиц стилей объектов
форматирования – XSL-FO (eXtensible Stylesheet Language for Formatting Objects).
11. Расширяемый язык гипертекстовой разметки (HTML, удовлетворяющий XML-правилам) – XHTML.
12. Расширяемый язык разметки 3D-графики – X3D (eXtensible 3D).
Эти и другие XML-реализации,
а также не XML-реализации (например, язык
путей XPath, язык запросов XQuery и другие) лежат в основе XML-технологий, развивающихся с начала нынешнего
столетия. Характерными свойствами XML-технологий
являются: независимость от платформ; полная стандартизация и открытые
спецификации (размещенные на сайтах W3C); максимальное разделение моделей данных от их
визуализации и управления; повторное использование; доступность;
многоязычность; масштабируемость; расширяемость; переносимость и другие достоинства.
XML-платформа – это совокупность взаимосвязанных
стандартов, разрабатываемых под эгидой W3C. Цель XML – создавать форматы для структурирования, поиска,
обеспечения целостности и безопасности процесса обмена документами в
автоматическом режиме.
XML (eXtensible Markup Language, расширяемый язык
разметки) – это метаязык, в котором описываются общие правила создания новых
(корпоративных, отраслевых, предметно-ориентированных) языков разметки информации.
Если язык уже разработан и описан, то пользователь может применять и расширять
его по XML-правилам.
На примере X3D-кода в листинге 1 рассмотрим только те
XML-правила, которые используются в настоящей работе. Начнем с правила составления пролога. Согласно
ему любой xml-документ может начинаться с объявления XML-разметки, которое
заключается между символами <? и ?>, содержит имя xml и несколько
параметров (номер XML-версии, используемую кодировку и т.д.). В 1-й строке
листинга 1 использовано простейшее объявление. Необязательность этого
правила обусловлена тем, что к
настоящему времени в Web накопилось
огромное количество документов HTML и SGML, фактически являющихся хорошо сформированными XML-документами.
Листинг 1. X3D-разметка зеленого куба с длинами ребер 0.1 м. на
белом фоне.
<?xml version=''1.0'' encoding=''UTF-8''?>
<X3D version=''3.2''>
Разметим сцену
<Scene> <Background skyColor=''1
1 1''/>
<!-- разметка куба -->
<Shape>
<Box
size=''0.1 0.1 0.1''/>
<Appearance> <Material
diffuseColor=''0 1 0''/> </Appearance>
</Shape>
</Scene>
</X3D>
В правиле записи
элементов говорится, что размечаемая информация (контент) заключается между
открывающим (начальным) и закрывающим (конечным) тегами и вместе с ними называется
элементом, например, <Scene>...</Scene>. Тег состоит из имени, заключенного
в угловые скобки. Идентификатор имени открывающего и соответствующего ему
закрывающего тега должен полностью совпадать, например, имена Scene и scene не
совпадают. Перед именем закрывающего тега должен стоять слеш (наклонная черта).
После имени открывающего тега через пробельный символ могут располагаться
атрибуты элемента, например, <X3D version=''3.2''>. То, что находится
между тегами, называется содержимым элемента. Одни элементы могут входить в
содержимое других элементов, например, <X3D version=''3.2''>
<Scene> ... </Scene> </X3D>. Здесь элемент <Scene> называют
потомком или подэлементом элемента <X3D>. Элемент <X3D> называют
предком или надэлементом для элемента <Scene>. Самый первый элемент,
внутри которого размещаются все остальные элементы xml-документа, называется
корневым элементом документа. Имя тега корневого элемента, как правило,
совпадает с именем соответствующего языка разметки (в листинге 1 – это имя
X3D). Для записи элемента, не имеющего потомков, используется укороченная
(стенографическая) форма, например, <Box size=''0.1 0.1 0.1''/>.
Правило
записи атрибутов говорит о том, что
элемент может иметь один или несколько атрибутов, отделенных друг от друга
пробельным символом. Атрибут состоит из имени и значения, отделенных друг от друга
знаком равно (=). Значение атрибута помещается либо в двойные, либо в одинарные
кавычки. Элемент не может иметь атрибуты с одинаковым именем.
Отличие атрибутов и элементов чисто функциональное:
элементы содержат данные, а значения атрибутов – то, что в большей степени
может быть отнесено к свойствам данных.
Из правила правильного
вложения элементов следует, что содержимое одного элемента не должно
пересекаться с содержимым другого элемента, т.е. последнему открывающему тегу соответствует
первый закрывающий тег. Например, следующий фрагмент разметки не правильный
<X3D version='3.2'>
<Scene> ... </X3D> </Scene>.
Теги XML всегда
должны закрываться в последовательности, обратной последовательности
открывающих тегов. Тег, открытый первым, всегда должен быть закрыт последним.
Первым вошел – последним вышел. Это простое правило довольно легко соблюдать. Закрывая
любой элемент, необходимо лишь убедиться, что все вложенные в него элементы уже
закрыты.
Можно привести много примеров иерархического описания
объектов. Люди всегда классифицируют объекты и компоненты в терминах иерархических
структур, как, например, в научных классификациях растений и животных. Все, что
делится на части, может быть представлено в виде иерархической структуры.
Пример наиболее простой (линейной) иерархии – русские матрешки, вложенные одна
в другую.
Вложение элементов – единственный механизм создания
логической структуры XML-документа.
В рекомендациях
именования элементов и атрибутов указывается, что эти имена должны
записываться на языке основных пользователей. Поэтому имена элементов и
атрибутов расширения, а также текстовые значения (кроме предопределенных) всех
атрибутов будем задавать на русском языке. Каждую новую часть составного имени
условимся начинать с заглавной буквы и аббревиатуры записывать заглавными
буквами.
XML разработан таким образом, чтобы его реализации были
легко расширяемыми. Расширяемость – важнейшее свойство XML. В XML-разметку
можно вставлять комментарий, записывая его между символами “<!--” и
“-->”.
Итак, мы рассмотрели следующий синтаксис разметки XML
Таблица 1.1. Синтаксис XML-разметки
Объявление
XML |
<?xml версия кодировка ?> |
Открывающий
тег |
<имяЭлемента атрибуты> |
Закрывающий
тег |
</имяЭлемента> |
Тег
пустого элемента |
<имяЭлемента атрибуты/> |
Атрибут |
имя=”значение” |
Комментарий |
<!-- комментарий --> |
Любой XML-документ
может содержать следующие семь типов узлов: корневой узел; узел элемента; текстовый узел;
узел атрибута; узел комментария; узел
инструкции обработки; узел
пространства имен. В листинге 1
использованы следующие узлы:
1-ая строка – узел инструкции обработки;
2-я строка – корневой узел;
3-я строка – текстовый узел;
4-я строка – начальный тег узла <Scene> и узел <Background> с узлом атрибутом;
5-я строка – узел комментария.
Листинг 2.1.
Зеленый конус высотой 0.1 м. и радиусом основания 0.1 м.
<Shape> <Cone bottomRadius='0.1' height='0.1' />
<Appearance> <Material
diffuseColor=''0 1 0''/> </Appearance>
</Shape>
Листинг 2.2.
X3D-разметка
структуры двойного маятника
<X3D version="3.2"> <Scene><Background
skyColor="1 1 1"/><Viewpoint position="0 0 4"/> <Transform
DEF="тело_0"><Inline url="тело_0.x3d"/> <Transform
DEF="тело_1" translation="0,0,0"><Inline
url="тело_1.x3d"/> <Transform
DEF="тело_2" translation="0,-0.3,0"><Inline
url="тело_2.x3d"/> </Transform> </Transform> </Transform> </Scene> </X3D> |
|
Листинг 2.3.
X3D-разметка тела
0 двойного маятника
<X3D version="3.2"> <Scene><Background
skyColor="1 1 1"/><Viewpoint position="0 0 4"/> <Transform
translation="0,0.2,0" rotation="0 0 1 0"> <Shape><Box
size="0.5,0.005,0.5"/>
<Appearance><Material diffuseColor="1,1,0"/></Appearance> </Shape> </Transform> <Transform
translation="0,0.1,0" rotation="0 0 1 0"> <Shape><Box
size="0.05,0.2,0.05"/>
<Appearance><Material diffuseColor="1,1,0"/></Appearance> </Shape> </Transform> </Scene> </X3D> |
|
Листинг 2.4. X3D-разметка тела
1 двойного маятника
<X3D version="3.2"> <Scene><Background
skyColor="1 1 1"/><Viewpoint position="0 0 4"/> <Transform
translation="0,0,0" rotation="1 0 0 1.57077"> <Shape><Cylinder
radius="0.04" height="0.1"/>
<Appearance><Material
diffuseColor="1,0,0"/></Appearance> </Shape> </Transform> <Transform
translation="0,-0.15,0" rotation="0 0 1 0"> <Shape><Box
size="0.05,0.3,0.05"/>
<Appearance><Material
diffuseColor="0,1,0"/></Appearance> </Shape> </Transform> </Scene> </X3D> |
|
Листинг 2.5. X3D-разметка
тела 2 двойного маятника |
|
<X3D version="3.2">
<Scene><Background
skyColor="1 1 1"/><Viewpoint position="0 0 4"/>
<Inline url="тело_1.x3d"/>
</Scene>
</X3D>
2. Основы X3D
X3D является XML-реализацией. Предшественником X3D является язык
моделирования виртуальных миров VRML (VirtualRealityModelingLanguage), который
появился в 1994 г. В 1999-2001 годах в процессе превращения VRML-97 в
XML-ориентированный язык разметки информации из-под пера W3C появился
расширяемый (eXtensible) язык разметки 3D-графики (X3D).
X3D используется в различных областях от физики, математики,
химии до мультипликации и создания игр. К основным достоинствам языка можно
отнести следующее: совместная работа с web-технологиями; работа в сетях;
гибкость языка (возможность создавать свои стандарты, вплоть до создания
собственного языка); размах платформ (от настольных ПК до мобильных телефонов);
стандартизация; работа в реальном времени; легкость освоения; безлицензионность
использования; XML-ориентация; постоянное развитие (появление новых стандартов);
взаимодействие с различными языками программирования (JavaScript, ECMAScript,
Java, C, C++, PHP, Python); возможность конвертирования данных из САПР в формат
X3D для дальнейшего использования 3D-информации.
X3D-элементы принято называть узлами (nodes), а их
атрибуты полями (fields). За редким исключением имена узлов начинаются с
большой буквы, имена полей – с маленькой. X3D-узлы хранят свои свойства в
полях. В описании узла для многих его полей определены значения по умолчанию.
Поэтому если значение такого поля в X3D-файле не задано, то используется значение
по умолчанию. Например, значением по умолчанию поля size узла Вох является
тройка вещественных чисел size=''2.0 2.0 2.0''. Значение каждого поля относится
к одному из допустимых типов данных.
Реальные тела СТ будем моделировать следующими графическими
объектами (ГО): Box (прямоугольный параллелепипед), Cylinder (цилиндр), Cone
(конус) и Sphere (сфера).
Большинство узлов могут содержать дочерние узлы и их
группы. Каждый такой узел определяет для своих потомков невидимую систему координат
(СК), относительно которой можно задавать положения этих потомков. В X3D
используется правая декартова СК OXYZ, где ось Z перпендикулярна плоскости экрана монитора и
направлена к наблюдателю, ось Y – вертикальна.
Например, с узлом Scene связана СК с началом в центре окна браузера. Длины
измеряются в метрах, углы в радианах, положительным считается поворот против
хода стрелки часов.
В следующих строках приведены размети ГО с значениями
атрибутов по умолчанию
<Box size="2 2
2"/> <Cylinder radius="1" height="2"/>
<Cone
bottomRadius="1" height="2"/> <Sphere
radius="1"/>
Условимся помещать в начале сцены узел <Background skyColor='1
1 1'/>, который задает однотонный белый фон. Узел Background (фон) позволяет размечать отдельно небо, землю, а
также текстуру фона в целом. Но нам достаточно наблюдать за СТ в сцене на белом
фоне, находясь на некотором удалении от сцены. Поэтому условимся за узлом Background размещать узел Viewpoint (точка зрения) со свойством position='a b c', где
числа a, b, c – координаты наблюдателя относительно СК сцены.
В дальнейшем (с целью сокращения текста листингов) мы
будем приводить только код разметки, заключенный между следующим начальным
текстом
<?xml version=''l.0''
encoding=''UTF-8''?>
<X3D
version='3.2'><Scene><Background skyColor='1 1 1'/>
<Viewpoint position='a b
c'/>
и
концовкой </Scene> </X3D>, где вместо а, b, c должны стоять конкретные
вещественные числа – координаты (в метрах) точки наблюдателя относительно СК
сцены. Эти числа желательно подобрать так, чтобы ГО X3D-мира не вышли за
пределы экрана монитора.
Любой из рассмотренных ГО должен быть потомком
(дочерним узлом) узла Shape (форма). Вторым потомком узла Shape является узел
Appearance (внешность), размечающий внешний вид ГО. Информация о внешности ГО
содержится в узлах Material, ImageTexture и других потомках узла Appearance.
Поэтому правильная разметка конуса имеет вид, представленный в листинге 2.1.
Листинг 2.1. Зеленый конус высотой 0.1 м. и радиусом основания 0.1
м.
<Shape> <Cone
bottomRadius='0.1' height='0.1' />
<Appearance> <Material
diffuseColor=''0 1 0''/> </Appearance>
</Shape>
Это типовая структура разметки ГО, которая содержит
одну форму (Shape), состоящую из ГО, внешность (Appearance) которого
описывается свойствами материала (Material). Цвет материала задается значением
свойства diffuseColor в формате RGB. Узел Shape может содержать только один ГО
и один узел Appearance. Если ГО отсутствует, то ничего не отобразится. Если
отсутствует узел Appearance, то по умолчанию цвет ГО будет светло-серым.
В X3D можно использовать следующие типы преобразований
(трансформаций) ГО: перенос (translation), поворот (rotation) и масштабирование
(scale). Эти преобразования описываются в полях узла трансформации (УТ) Transform, который содержит трансформируемые ГО, например,
<Transform scale='1 1 2' rotation='0 0 1 1.57'
translation='2 0 0'>...</Transform>
Здесь вместо троеточия могут располагаться формы
трансформируемых ГО. Поле translation отвечает за перенос содержимого (всех
потомков) УТ из одного места в другое. Значением этого поля являются три
вещественных числа x-, y- и z- координаты
(положительные или отрицательные), которые задают величины переноса СК УТ
(вместе со своим содержимым) вдоль осей X, Y, Z СК его предка. Масштабирование умножает размеры потомков
УТ на значения поля scale в соответствующем измерении. Масштабирование с коэффициентом
нуль сделает ГО бесконечно тонким в выбранном направлении. Чтобы ГО не
изменился в выбранном направлении, коэффициент масштабирования в этом
направлении должен быть равен единице. Поле rotation УТ содержит четыре
вещественных числа. Первые три из них задают направляющие косинусы оси
поворота, а четвертый определяет угол поворота в радианах. Например, чтобы повернуть
потомков УТ на 45 градусов вокруг оси X,
следует написать: <Transform rotation=''1
0 0 0.78''>. УТ может иметь вложенные УТ, что создает последовательности
преобразований. Порядок, в котором выполняются преобразования, влияет на
результат. Преобразования осуществляются в следующем порядке: сначала
масштабирование (scale), затем поворот (rotation), и в конце – перенос (translation). Поля УТ (и других x3d-узлов) могут располагаться в
любом порядке.
Для повторного использования кода применяется узел
Inline. Он берет код из внешнего X3D-файла и вставляет его в X3D-мир на свое
место. Если X3D-модель расположена в файле ''модель.x3d'', то ее можно вставить
в сцену следующим образом: <Inline url='модель.x3d'/>. Включаемый таким образом файл должен быть
синтаксически правильным Х3D-файлом, т.е. иметь заголовок и другие разделы. Если
файл не загружается в браузер самостоятельно, то его Inline-вставка в другой
X3D-файл приведет к ошибке. В качестве примера в листинге 2.2 размечена система
координат (СК).
Листинг 2.2. X3D-разметка СК
<Transform translation="0.1 0 0"> <Shape> <Box size="0.2
0.04 0.04"/> <Appearance> <Material
diffuseColor="1 0 0"/> </Appearance> </Shape> </Transform> <Transform translation="0 0.1 0"> <Shape> <Cylinder
radius="0.03" height="0.2"/> <Appearance>
<Material diffuseColor="0 1 0"/> </Appearance> </Shape> </Transform> <Transform translation="0 0 0.15" rotation="1 0 0
1.57"> <Shape> <Cone
bottomRadius="0.03" height="0.3"/> <Appearance>
<Material diffuseColor="0 0 1"/> </Appearance> </Shape> </Transform> |
|
|
Листинг 3.1.
HTML-разметка параметров двойного маятника <html><table> <tr><td>0</td><td>0,0,0</td><td>-100</td><td>100</td> <td>первое звено двойного
маятника</td></tr> <tr><td>1</td><td>0,-0.3,0</td><td>-160</td><td>160</td> <td>второе звено двойного
маятника</td></tr> </table></html> |
Рис. 3.1. КС двойного маятника |
|
Таблица 3.1. ТПСТ.
Таблица структурных, геометрических и кинематических параметров двойного
маятника
X3D-код 3.1. Структура и геометрия двойного маятника <X3D version="3.2"> <Scene><Background
skyColor="1 1 1"/> <Viewpoint position="0
0 4"/> <Transform
DEF="тело_0"><Inline url="тело_0.x3d"/> <Transform
DEF="тело_1" translation="0,0,0"> <Inline
url="тело_1.x3d"/> <Transform
DEF="тело_2" translation="0,-0.3,0"> <Inline
url="тело_2.x3d"/> </Transform> </Transform> </Transform> </Scene> </X3D> |
|
|
Листинг 3.2.
HTML-разметка параметров манипулятора с ангулярной СК в
горизонтальной плоскости <html><table>
<tr><td>0</td><td>0,0,0</td><td>-180</td><td>180</td> <td>первое тело
манипулятора</td></tr> <tr><td>1</td><td>0.3,0,0</td><td>-160</td><td>160</td> <td>второе тело
манипулятора</td></tr> <tr><td>2</td><td>0.2,0,0</td><td>-30</td><td>30</td> <td>третье тело
манипулятора</td></tr> </table></html> |
Рис. 3.1. КС манипулятора с ангулярной СК в горизонтальной
плоскости |
|
Таблица 3.2.
ТПСТ. Таблица структурных, геометрических и кинематических параметров манипулятора
с ангулярной СК в горизонтальной плоскости
X3D-код 3.2. Структура манипулятора с ангулярной СК в горизонтальной
плоскости <X3D version="3.2"> <Scene><Background
skyColor="1 1 1"/> <Viewpoint position="0
0 4"/> <Transform DEF="тело_0"><Inline url="тело_0.x3d"/> <Transform DEF="тело_1" translation="0,0,0"> <Inline url="тело_1.x3d"/> <Transform DEF="тело_2" translation="0.3,0,0"> <Inline url="тело_2.x3d"/> <Transform DEF="тело_3" translation="0.2,0,0"> <Inline url="тело_3.x3d"/> </Transform> </Transform> </Transform> </Transform> </Scene> </X3D> |
|
|
Листинг 3.3.
HTML-разметка параметров шагающего аппарата в вертикальной
плоскости <html><table>
<tr><td>0</td><td>0,0,0</td><td>0</td><td>180</td> <td>голень опорной ноги</td></tr> <tr><td>1</td><td>0.4,0,0</td><td>0</td><td>180</td> <td>бедро опорной ноги</td></tr> <tr><td>2</td><td>0.4,0,0</td><td>-160</td><td>160</td> <td>бедро переносной
ноги</td></tr> <tr><td>3</td><td>0.4,0,0</td><td>-180</td><td>0</td> <td>голень переносной
ноги</td></tr> <tr><td>4</td><td>0.4,0,0</td><td>-45</td><td>45</td> <td>стопа переносной
ноги</td></tr> <tr><td>2</td><td>0.4,0,0</td><td>-180</td><td>180</td> <td>корпус</td></tr> </table></html> |
Рис. 3.3. КС модели шагающего аппарата в одноопорной фазе
ходьбы в вертикальной плоскости |
|
Таблица 3.3.
ТПСТ. Таблица структурных, геометрических и кинематических параметров шагающего
аппарата в вертикальной плоскости
X3D-код 3.3. Структура шагающего аппарата в вертикальной
плоскости <X3D version="3.2"> <Scene><Background
skyColor="1 1 1"/> <Viewpoint
position="0 0 4"/> <Transform
DEF="тело_0"> <Inline
url="тело_0.x3d"/> <Transform
DEF="тело_1" translation="0,0,0"> <Inline
url="тело_1.x3d"/> <Transform
DEF="тело_2" translation="0.4,0,0"> <Inline
url="тело_2.x3d"/> <Transform
DEF="тело_3" translation="0.4,0,0"> <Inline
url="тело_3.x3d"/> <Transform
DEF="тело_4" translation="0.4,0,0"> <Inline
url="тело_4.x3d"/>
<Transform DEF="тело_5"
translation="0.4,0,0">
<Inline url="тело_5.x3d"/>
</Transform>
</Transform>
</Transform> <Transform DEF="тело_6"
translation="0.4,0,0"> <Inline
url="тело_6.x3d"/>
</Transform> </Transform> </Transform> </Transform> </Scene> </X3D> |
|
Рис. 3.1. КС ПКП |
Рис. 3.2. КС ВКП |
|
Рис. 3.4. Фрагменты КС с совмещенными полюсами тел |
Объектами математического и 3D-моделирования в ПС "СистемаТел" являются
манипуляционные системы роботов, шагающие аппараты, подъемно-транспортные
машины, роботизированные технологические комплексы и другие управляемые системы
тел (СТ). В 1-й версии ПС "СистемаТел" рассматриваются СТ со
структурой дерева (СТД), в которой тела могут образовывать друг с другом и с
землей связи, моделируемые комбинацией поступательных (ПКП) и вращательных
(ВКП) кинематических пар (КП). К ПКП и ВКП относятся сочленения двух тел,
допускающих относительные поступательные движения вдоль или вращения вокруг
осей, жестко связанных с телами сочленений. Эти оси называют осями КП. Все известные
в технической механике сочленения двух тел можно представить в виде ПКП, ВКП
или их комбинаций. В настоящей работе рассматриваются и формально описываются
СТД, в которых оси соседних КП параллельны или перпендикулярны друг другу.
Этому ограничению удовлетворяют более 80% известных нам СТ. Произвольную
ориентацию осей соседних, т.е. следующих друг за другом КП, можно моделировать
путем включения между ними фиктивных ВКП с постоянными углами поворота.
Формальное описание СТ рекомендуется начинать с построения
ее кинематической схемы (КС). На рис. 1 приведены КС ПКП, на рис. 2 ВКП, на
рис. 3 СТ, которые рассматриваются в настоящей работе. В КС СТ тела всех ВКП
должны быть изображены в исходном положении. Все тела СТ должны быть мысленно
пронумерованы. Рекомендуется осуществлять подсистемную нумерацию тел СТД. Для
этого необходимо проверить наличие в СТ циклов, т.е. цепочек тел, у которых
существует более одного пути к телу отсчёта (к земле). Циклы необходимо
мысленно разорвать, т.е. перейти к СТ со структурой открытого дерева (СТОД). Каждое тело СТОД
имеет единственное предшествующее тело на пути к земле (это тело называют базой)
и одно, несколько или ни одного следующего за ним тела. Эти тела называют
смежными. Тело является концевым, если не имеет смежных.
В СТОД земле присваивается номер 0. Подсистемная
нумерация тел СТОД выполняется сначала от земли вдоль любой цепочки связанных
тел до концевого тела, а затем от тела с наибольшим номером среди уже занумерованных
тел и имеющих незанумерованные смежные тела к следующему концевому телу и так
далее.
С каждым телом СТОД мысленно связывается СК, оси
которой должны быть параллельны соответствующим осям СК X3D-сцены, т.е.
ось абсцисс направлена горизонтально вправо, ось ординат – вертикально вверх,
ось аппликат – в сторону к исследователю. Начало связанной СК (ССК) тела
располагается в полюсе этого тела. В ВКП полюс, т.е. неподвижная точка тела,
выбирается на оси этой ВКП. В ПКП полюс выбирается в любом месте его смежного
тела, т.е. тела с большим порядковым номером. Базовым телом КП является тело с
меньшим порядковым номером.
Полюса тел рекомендуется выбирать так, чтобы как можно
большее их количество размещалось в одной точке. На рис. 4 изображены фрагменты
КС СТОД, в которых эта рекомендация выполняется максимально. Полюс i-го тела обозначается через Oi.
В ПС "СистемаТел" все СТ разбиты на классы.
Простейшим является класс ПВСТ, т.е. СТ с ВКП на плоскости. Тела ПВСТ образуют
друг с другом только ВКП, оси которых параллельны друг другу.
X3D-разметка СТ
генерируется на основе таблицы параметров системы тел (ТПСТ). Количество строк
ТПСТ равно количеству тел СТОД. Одна строка описывает одну КП. Для ПВСТ ТПСТ
имеет следующие пять столбцов: НБ – номер базы; КПТ – координаты (в метрах)
полюса тела в ССК его базы (ССКБ) (три вещественных числа); min, max – минимальное
и максимальное значения угла поворота (в градусах) или величины перемещения (в
метрах); имя смежного тела КП или дополнительная информация (ДИ). Оси ВКП у
ПВСТ параллельны оси Oz СК сцены.
В качестве примера в листингах 3.1, 3.2, 3.3 приведены
ТПСТ двойного маятника, манипулятора с ангулярной СК и шагающего аппарата в
вертикальной плоскости. В таблицах 3.1-3.3 приведены соответствующие им ТПСТ.
Каждой ТПСТ можно поставить в соответствие X3D-разметку
структуры, геометрии и кинематики СТ. В X3D-кодах 3.1, 3.2,
3.3 приведены разметки параметров двойного маятника, манипулятора и шагающего
аппарата. Между ТПСТ (таблица 3.1) и его X3D-разметкой (X3D-код 3.1) существует
следующее взимнооднозначное соответствие. Каждой строке ТПСТ ставится в
соответствие один узел <Transform>.
Число в первом столбце каждой строки ТПСТ указывает на трансформатор, в который
будет вложен данный узел <Transform>.
Значению столбца КПТ соответствует значение поля translation узла <Transform>
этого тела.
С каждым телом связана ССК. X3D-разметка ССК
приведена в X3D-коде 3.4. Ось X изображена красным боксом, вытянутым горизонтально.
Ось Y отображается вертикальным зелёным цилиндром. Ось Z – синим конусом, вершина которого направлена в сторону
наблюдателя. Код ССК размещён внутри Inline-подключаемых
внутри каждого узла <Transform>
файлов моделей тел.
Листинг 4.1.
XML-разметка текста приветствия
<?xml version="1.0"
encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="Приветствие.xsl"?>
<Приветствие> Здравствуй, Мир XML-технологий. </Приветствие>
XSLT-код 4.1. Код преобразования XML в HTML
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template
match="/">
<html>
<head>
<title> Наш первый пример </title> </head>
<body>
<p> <xsl:value-of select="Приветствие"/>
</p> </body>
</html>
</xsl:template>
</xsl:stylesheet>
Листинг 4.2.
HTML-документ приветствия
<html>
<head>
<title> Наш первый пример </title> </head>
<body>
<p> <xsl:value-of select="Приветствие"/>
</p> </body>
</html>
XSLT-код 4.2. Код преобразования HTML-данных в текстовый формат
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template
match="/">
<xsl:value-of
select="p"/>
</xsl:template>
</xsl:stylesheet>
4. Основы XSLT
X3D-разметку
СТОД можно генерировать автоматически на основе её ТПСТ. В ПС «СистемаТел»
такую генерацию осуществляет XSLT-код. Он выполняет
преобразование ТПСТ в X3D-разметку СТ, описанную в
этой ТПСТ. Любой XSLT-код состоит из шаблонов
и образцов. Шаблоны описывают, как
преобразовывать входной документ (ВД). Образцы описывают что преобразовывать,
т.е. описывают последовательность узлов ВД, которые нужно преобразовывать по
соответствующему шаблону в узлы выходного файла (ВФ).
На рис. 1 представлена
диаграмма XSLT-преобразования ВД.
Рис. 1. Диаграмма XSLT-преобразования ВД в ВФ
Язык XSLT – это
XML-реализация. Как и любой другой XML-ориентированный язык, он
содержит элементы и атрибуты, которые подчиняются правилам их записи и
вложения. Рассмотрим примеры XSLT-преобразований.
Пример 1. В качестве ВД рассмотрим XML-документ, содержащий текст
приветствия, который размечен на нашем (авторском) XML-языке (см. листинг 1). Этот
язык состоит из единственного элемента,
который является корневым.
Документ приветствия
расположен в файле «Приветствие.xml». XSLT-код 1, расположенный в файле
«Приветствие.xsl», выведет на странице браузера текст «Здравствуй,
мир XML-технологий». Окно браузера названо «Наш первый пример». Объясним, как
это происходит.
Так как XSLT-код
является XML-документом, то он имеет первую стандартную строку
(см. первую строку XSLT-кода 1), в которой указывается, что это XML-документ
версии 1.0, и используется кодировка utf-8. Во второй строке записан
корневой XSLT-элемент, указывающий на то, что данный документ содержит
лист стилей версии 2.0. Значение атрибута xmlns:xsl указывает на то, что для XSLT-элементов
используется префикс xsl.
В третьей строке элемент <tamplate>
определяет шаблонное правило. Его
атрибут match="/" указывает,
что это правило применяется к корневому элементу ВД. Значением атрибута match является XPath-выражение.
Выражение "/" языка XPath описывает (задает) корневой
узел XML-документа. Шаблонное правило (шаблон) – это содержимое элемента <xsl:template>.
В рассматриваемом примере – это <html> ... <body>
<p> ... </p> </body>
</html>. Тег <html> указывает, что
формируется XHTML-документ. Теги <head> и <title>
с содержимым "Наш первый пример" описывают заголовок страницы. Теги
<body> и <p> указывают, что на странице будет отображен
абзац текста, который содержится в элементе <p>. XSLT-инструкция
<xsl:value-of> требует копировать содержимое
узла, заданного значением атрибута select,
в выходной элемент <p>.
XPath –
это вспомогательный язык, используемый в языках XSLT, XPointer, XQuery, XForms и др. XPath-выражения
используют для числовых расчетов, обработки строк, проверки логических условий
и так далее. Но чаще всего его используют (отсюда и название языка) в описании
пути к частям ВД, подлежащего обработке. Например, если в ВД размечена СТОД, то
инструкция
<xsl:value-of select="sum(//Тело/@масса)
div count(//Тело)"/>
выводит среднюю массу всех тел.
Здесь атрибут select содержит XPath-выражение,
которое вычисляет сумму значений атрибутов масса
всех элементов <Тело> ВД и делит ее на число элементов <Тело> этого
ВД.
XSLT –
это декларативный, а не процедурный язык. Его семантика является аддитивной,
т.е. позволяет создавать XSLT-код путем добавления новых деталей к существующему
XSLT-коду.
Пример 2. Текст приветствия «Здравствуй, мир!», записан в теге <p> html-файла
«Приветствие.html». XSLT-код 2 на основе ВД
генерирует обычный текст приветствия.
5. XSLT-генераторы X3D-моделей ПВСТ
Для описания моделей тел
ПВСТД будем использовать таблицу параметров моделей тел (ТПМТ). Здесь
рассматриваются X3D-модели тел ПВСТД, состоящие
из цилиндров и боксов.
Одна ТПМТ описывает X3D-модель
одного тело ПВСТОД и имеет следующий формат. Каждая строка ТПМТ соответствует
одному графическому объекту (ГО), входящему в состав X3D-модели тела. Свойства ГО описываются
следующими столбцами ТПМТ: ГО
– тип графического объекта, который может быть боксом (Б) или цилиндром (Ц);
КЦГО – координаты центра ГО в ССК тела; ПГО – параметры ГО (для бокса это
длина, высота и ширина, для цилиндра – радиус оснований и высота); имя или
назначение детали. Количество ТПМТ равно числу тел в описываемой СТ. К этому
числу добавляется тело 0, в котором описываются неподвижные ГО, т.е. внешняя
среда.
Каждой ТПМТ можно поставить в соответствие X3D-разметку модели
тела СТ. В X3D-кодах 1, 2, 3 приведены разметки тел двойного
маятника. Между ТПМТ_0, ТПМТ_1, ТПМТ_2 (таблицы 1, 2, 3) и X3D-разметкой тел
(X3D-коды 1, 2, 3)
существует взимнооднозначное соответствие. Каждой строке ТПМТ ставится в
соответствие один узел <Transform>. Внутрь
<Transform> всегда вложен элемент <Shape>. Внутри <Shape> содержится узел отображения <Appearance> и узел материала <Material>, а также узел ГО – <Box> (бокс) или <Cylinder> (цилиндр). Вид ГО указывается в первом столбце
ТПМТ. Значению столбца КЦГО соответствует значение поля translation узла <Transform>
этого ГО. Столбец ПГО определяет геометрические размеры ГО.
ВКП(1) чаще всего имеет вид:
Пример 1. Даны три ТПМТ, описывающие тела двухзвенного маятника, записанные в html-файлах
в листинге 1, 2, 3. Надо из ТПМТ
получить X3D-файлы с разметкой моделей
тел маятника. Соответствующий XSLT-код 1 получает HTML
файл с разметкой таблицы. На выход генерируется X3D-код тела.
XSLT-код
1 содержит один шаблон с именем "получитьРазметкуТела".
Шаблон вызывается с параметром, определяющим номер тела и номер соответствующей
ТПМТ. Открывается файл, содержащий html-разметку
ТПМТ. Файлы ТПМТ имеют имя в формате ТПМТ_i.html, где i – номер тела. При помощи цикла <xsl:for-each> последовательно обрабатываются данные строк
таблицы <tr>. В результате генерируется
разметка каждого ГО, входящих в состав тела. Результаты генерации приведены в X3D-кодах 1, 2, 3.
Для формального описания СТ создан расширяемый язык
разметка систем тел XsysTel. Это наша XML-реализация. Язык XsysTel предназначен
для формального описания СТ и постановки задач, возникающих в процессе их исследования.
Этот язык изучим от простого к сложному. По мере необходимости будем вводить в
рассмотрение новые узлы и атрибуты. В XsysTel корневым является
узел <СистемаТел>. Здесь используются два его атрибута: версия и класс. Второй атрибут содержит аббревиатуру класса, к которому относится
исследуемая СТ. Для разметки структуры, геометрии и кинематики СТ из класса
ПВСТ используется узел <Тело> с атрибутами номер, КПТ, min, max.
Основными входными документами в ПО «СистемаТел»
являются разметки СТ на языке XsysTel, разметки
ПД и постановок задач на авторских XML-языках.
На основе этих документов генерируются X3D-разметки моделей
СТ и анимации, MathML-разметки уравнений динамики и
решения задач, XForms-разметки для ввода
начальных условий и параметров задач динамики, а также XSL-FO-разметки
представления результатов решения задач.
На рис. 3.1, 3.2, 3.3 приведены КС двойного маятника,
манипулятора с ангулярной СК и шагающего аппарата в вертикальной плоскости. В
листингах 4, 5, 6 представлены XsysTel-коды
этих ПВСТ. Очевидно соответствие между ТПСТ и XsysTel-кодом любой ПВСТ. Каждой строке ТПСТ соответствует
узел <Тело>. Порядковый номер строки является значением атрибута номер узла <Тело>. Значение
второго столбца ТПСТ равно значению атрибута КПТ. Третий и четвёртый столбцы ТПСТ содержат значения атрибутов min
и max.
Структуре ПВСТ соответствует структура вложенности
узлов <Тело>. Например, в листинге 4 в узел <Тело номер="1">
вложен узел <Тело номер="2">, т.к. первое тело двойного маятника
является базовым для второго. В листинге 5 в узел <Тело номер="1">
вложен узел <Тело номер="2">, а в него вложен узел <Тело
номер="3">, т.к. все тела манипулятора вкладываются друг в друга
по цепочке от первого к концевому. В листинге 6 в узел <Тело номер="1">
вложен узел <Тело номер="2">, а в узел <Тело номер="2">
одновременно вложены два узла <Тело номер="3"> и <Тело номер="6">,
т.к. бедро опорной ноги ША является базовым телом для бедра переносной ноги и
корпуса.
Число в первом столбце указывает на номер узла <Тело>, в который
вложен данный узел <Тело>. Значение 0 в этом столбце означает, что родителем
текущего узла является корневой узел <CиситемаТел>. Порядок вложенности дочерних узлов
определяется номером тела так, чтобы тела следовали по возрастанию своих
номеров в соответствии с подсистемной нумерацией СТОД.
Сравнительный анализ X3D-кодов
с XsysTel-кодами указывает на взаимно однозначное
соответствие между XsysTel-кодом и X3D-разметкой СТ. Каждому узлу
тело <Тело> соответствует свой узел <Transform> с тем же уровнем
вложенности. Атрибуту КПТ соответствует атрибут translation.
XsysTel-разметка
ПВСТ генерируется на основе html-разметки её ТПСТ. Для этого
применяется XSLT-код 1. В XSLT-коде 1 используются два
шаблона <xsl:template>. Первый шаблон создает корневой
узел, который присутствует в любом XsysTel-коде структуры СТ лишь
однажды. Тег <xsl:apply-templates> применяет шаблон к
узлам, заданным в атрибуте select, т.е. к строкам, во втором
столбце которых записан ноль. Второй шаблон генерирует разметку подвижных тел,
соблюдая структуру вложенности, заданной в первом столбце ТПСТ. Для этого
объявляется переменная <xsl:variable> с идентификатором td. XPath-функция
index-of() возвращает позицию элемента, переданного вторым аргументов, во
множестве, переданным первым аргументом. С помощью этой функции определяется номер
строки в таблице по порядку их следования. Далее этот номер отыскивается среди
значений номеров базовых элементов тела во втором столбце ТПСТ, и к строкам,
содержащим этот номер, применяется второй шаблон. ВФ преобразования является
"структура.xml".
Для получения X3D-разметки
из XsysTel-кода применяется XSLT-код 3 и 4. Эти преобразования
применяются последовательно к ВД "структура.x3d". ВД "структура.x3d" содержит
корневые теги X3D-разметки структуры любой
СТ. Код ВД приведён в X3D-коде 1. XSLT-код
2 использует два шаблона <template>. Первый шаблон копирует
ВД. Второй шаблон копирует внутрь корневого узла <Transform> ВД XsysTel-разметку
ПВСТ. Инструкция <xsl:copy>
сообщает XSLT-процессору о том, что в ВФ
должен присутствовать сам корневой узел <Transform>, <xsl:copy-of select="@*"/> копирует атрибуты узла<Transform>, <xsl:copy-of select="Inline"/>
копирует узел Inline. XSLT-код 2 применяется после XSLT-кода
3 и так же использует два шаблона <template>. Первый шаблон копирует
ВД. Второй шаблон переименовывает теги <Тело> на <Transform>,
не меняя структуры их вложенности, и генерирует атрибуты узлов трансформации.
Также внутрь <Transform> вкладываются узлы Inline для подключения моделей тел.
Пример 2. В качестве ВД для генератора XsysTel-разметки в XSLT-коде
1 используем html-разметку ТПСТ параметров
двойного маятника
из листинга 3.1. В результате получим ВФ, совпадающий с XsysTel-кодом
в листинге 1. Используем этот ВФ в качестве ВД для генератора в XSLT-коде
3. Получим ВФ с X3D-разметкой в X3D-коде 4.
Листинг 5.1.
HTML-разметка параметров основания двойного маятника
<tr><td>Б</td><td>0,0.2,0</td><td>0.5,0.005,0.5</td><td>Основание</td></tr>
<tr><td>Б</td><td>0,0.1,0</td><td>0.05,0.2,0.05</td><td>Основание</td></tr>
Листинг 5.2.
HTML-разметка параметров первого тела двойного маятника
<tr><td>Ц</td><td>0,0,0</td><td>0.04,0.1</td>
<td>Шарнир первого звена
двойного маятника</td></tr>
<tr><td>Б</td><td>0,-0.15,0</td><td>0.05,0.3,0.05</td>
<td>Первое звено двойного маятника</td></tr>
Листинг 5.3.
HTML-разметка параметров второго тела двойного маятника
<tr><td>Ц</td><td>0,0,0</td><td>0.04,0.1</td>
<td>Шарнир второго звена двойного маятника</td></tr>
<tr><td>Б</td><td>0,-0.15,0</td><td>0.05,0.3,0.05</td>
<td>Второе звено двойного маятника</td></tr>
Таблица 5.1. ТПМТ_0.
Таблица модели основания двойного маятника
Таблица 5.2. ТПМТ_1.
Таблица модели первого тела двойного маятника
Таблица 5.3. ТПМТ_2.
Таблица модели второго тела двойного маятника
X3D-код 5.1. X3D-разметка основания
двойного маятника <X3D version="3.2"> <Scene><Background
skyColor="1 1 1"/> <Viewpoint position="0
0 4"/> <Transform
translation="0,0.2,0"> <Shape><Box
size="0.5,0.005,0.5"/>
<Appearance><Material diffuseColor="0 1
0"/></Appearance> </Shape> </Transform> <Transform
translation="0,0.1,0"> <Shape><Box
size="0.05,0.2,0.05"/>
<Appearance><Material diffuseColor="0 1
0"/></Appearance> </Shape> </Transform> </Scene></X3D> |
|
X3D-код 5.2. X3D-разметка первого
и второго тел двойного маятника <X3D version="3.2"> <Scene><Background
skyColor="1 1 1"/> <Viewpoint position="0
0 4"/> <Transform
translation="0,0,0" rotation="1 0 0 1.57"> <Shape><Cylinder
radius="0.04" height="0.1"/>
<Appearance><Material diffuseColor="0 1
0"/></Appearance> </Shape> </Transform> <Transform
translation="0,-0.15,0"> <Shape><Box
size="0.05,0.3,0.05"/>
<Appearance><Material diffuseColor="0 1
0"/></Appearance> </Shape> </Transform> </Scene> </X3D> |
|
XSLT-код 5.1. Код генератора модели тела ПВСТД
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template
name="получитьРазметкуТела">
<xsl:param
name="текущееТело"/>
<X3D
version="3.2"> <Scene> <Background skyColor="1 1
1" />
<Viewpoint
position="0 0 4" />
<xsl:variable name="ТПМТ"
select="document(concat('ТПМТ_',$текущееТело,'.html'))"/>
<xsl:for-each
select="$ТПМТ//tr">
<xsl:variable name="КГО"
select="td[1]" />
<Transform>
<xsl:attribute name="translation">
<xsl:value-of
select="td[2]" /></xsl:attribute>
<xsl:if
test='$КГО="Ц"'><xsl:attribute name="rotation">
<xsl:value-of select="'1 0 0 1.57'"
/></xsl:attribute></xsl:if>
<Shape> <xsl:choose>
<xsl:when
test='$КГО="Б"'>
<Box> <xsl:attribute
name="size">
<xsl:value-of select="td[3]" /></xsl:attribute>
</Box>
</xsl:when>
<xsl:when
test='$КГО="Ц"'>
<Cylinder> <xsl:attribute name="radius">
<xsl:value-of select="substring-before(td[3],',')"
/></xsl:attribute>
<xsl:attribute name="height">
<xsl:value-of
select="substring-after(td[3],',')" /></xsl:attribute>
</Cylinder> </xsl:when>
</xsl:choose>
<Appearance> <Material> <xsl:attribute
name="diffuseColor">
<xsl:value-of
select="0,1,0" /></xsl:attribute>
</Material> </Appearance>
</Shape>
</Transform>
</xsl:for-each>
</Scene>
</X3D>
</xsl:template>
</xsl:stylesheet>
XSLT-код 5.2. Генератор моделей всех тел СТ
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="получитьТела" match="/">
<xsl:param name="количествоТел" select="count(//tr)"/>
<xsl:if test="0 <= $количествоТел">
<xsl:result-document href="{concat('тело_', $количествоТел,
'.x3d')}">
<xsl:call-template name="получитьРазметкуТела">
<xsl:with-param name="текущееТело"
select="$количествоТел" />
</xsl:call-template>
</xsl:result-document>
<xsl:call-template
name="получитьТела">
<xsl:with-param
name="количествоТел" select="$количествоТел - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:include href="генераторМТ.xsl"/>
</xsl:stylesheet>
Листинг 5.4. XsysTel-разметка двойного маятника
<СистемаТел
версия="1.0" класс="ПВСТОВ">
<Тело номер="1"
КПТ="0,0,0" min="-100"
max="100">
<Тело
номер="2" КПТ="0,-0.3,0" min="-160" max="160"/>
</Тело>
</СистемаТел>
Листинг 5.5. XsysTel-разметка манипулятора с ангулярной СК
<СистемаТел
версия="1.0" класс="ПВСТОВ">
<Тело номер="1"
КПТ="0,0,0" min="-180"
max="180">
<Тело
номер="2" КПТ="0.3,0,0" min="-160" max="160">
<Тело номер="3" КПТ="0.2,0,0"
min="-30" max="30"/>
</Тело>
</Тело>
</СистемаТел>
X3D-код 5.3. Разметка
корневых узлов структуры СТ
<X3D version="3.2">
<Scene> <Background skyColor="1 1
1" /> <Viewpoint position="0 0 4" />
<Transform DEF="тело_0"><Inline url="тело_0.x3d"/></Transform>
</Scene>
</X3D>
Листинг 5.6. XsysTel-разметка шагающего аппарата в вертикальной плоскости
<СистемаТел
версия="1.0" класс="ПВСТОД">
<Тело номер="1"
КПТ="0,0,0" min="0"
max="180">
<Тело
номер="2" КПТ="0,0.4,0" min="0" max="180">
<Тело номер="3" КПТ="0,0.4,0"
min="-160" max="160">
<Тело номер="4" КПТ="0,-0.4,0"
min="-180" max="0">
<Тело номер="5"
КПТ="0,-0.4,0" min="-45"
max="45"/>
</Тело>
</Тело>
<Тело номер="6" КПТ="0,0.4,0"
min="-180" max="180"/>
</Тело>
</Тело>
</СистемаТел>
XSLT-код 5.3. Код
генератора XsysTel-разметки ПВСТД
<?xml version="1.0"
encoding="utf-8"
?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template
match="table">
<СистемаТел
version="1.0" класс="ПВСТОВ">
<xsl:apply-templates
select="tr[td[1] eq '0']" /></СистемаТел>
</xsl:template>
<xsl:template
match="tr">
<xsl:variable
name="td" select="string(index-of(//tr, .[position()]))"
/>
<Тело>
<xsl:attribute
name="номер">
<xsl:value-of
select="$td" /></xsl:attribute>
<xsl:attribute
name="КПТ">
<xsl:value-of
select="td[2]" /></xsl:attribute>
<xsl:attribute name="min">
<xsl:value-of
select="td[3]" /></xsl:attribute>
<xsl:attribute name="max">
<xsl:value-of
select="td[4]" /></xsl:attribute>
<xsl:apply-templates
select="//tr[td[1] eq $td]" /> </Тело>
</xsl:template>
</xsl:stylesheet>
XSLT-код 5.4. Код генератора X3D-структуры
ПВСТД по его XsysTel-разметке
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template
match="node() | @*">
<xsl:copy>
<xsl:apply-templates
select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template
match="Transform">
<xsl:copy><xsl:copy-of
select="@*"/><xsl:copy-of select="Inline"/>
<xsl:copy-of
select="document('структура.xml')//СистемаТел/*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XSLT-код 5.5. Код генератора X3D-структуры
ПВСТД по его XsysTel-разметке
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template
match="node() | @*">
<xsl:copy>
<xsl:apply-templates
select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Тело">
<Transform>
<xsl:attribute
name="DEF">
<xsl:value-of
select="concat('тело_',@номер)" /></xsl:attribute>
<xsl:attribute
name="translation">
<xsl:value-of
select="@КПТ"
/></xsl:attribute>
<Inline
><xsl:attribute name="url">
<xsl:value-of
select="concat('тело_',@номер,'.x3d')"
/></xsl:attribute></Inline>
<xsl:apply-templates
select="*"/>
</Transform>
</xsl:template>
</xsl:stylesheet>
X3D-код 5.4. ВФ разметки структуры двойного маятника
<X3D version="3.2">
<Scene><Background skyColor="1 1
1"/><Viewpoint position="0 0 4"/>
<Transform DEF="тело_0"><Inline url="тело_0.x3d"/>
<Transform DEF="тело_1" translation="0,0,0"><Inline
url="тело_1.x3d"/>
<Transform DEF="тело_2" translation="0,-0.3,0"><Inline
url="тело_2.x3d"/>
</Transform>
</Transform>
</Transform>
</Scene>
</X3D>
Для формального описания СТ создана XML-реализация XsysTel –
расширяемый язык разметка систем тел. Язык XsysTel предназначен
для формального описания СТ и постановки задач, возникающих в процессе
исследования СТ. Этот язык будем изучать от простого к сложному. По мере необходимости будем вводить в
рассмотрение новые узлы и атрибуты. Здесь отметим, что в XsysTel корневым
является элемент <СистемаТел>. Здесь используются атрибуты версия и класс корневого элемента. Второй атрибут содержит аббревиатуру
класса СТ, к которому относится исследуемая СТ. Начнём с рассмотрения простейшего
класса ПВСТ. В этом разделе будем использовать элемент <Тело> с
атрибутами номер, КПТ, min, max.
6. Анимация
ПВСТ по минимаксным значениям относительных углов поворота тел
Анимацией СТ называется
процесс визуализации на экране монитора ПК X3D-сцены, в которой с течением
времени изменяются положения тел СТ. В ПВСТ каждое тело может вращаться
относительно своего базового тела. Текущее значение угла поворота тела хранится
в поле rotation узла <Transform>, содержащего узел <Inline>
с url-адресом X3D-разметки этого тела. Этот
угол является относительным, так как узел <Transform> тела вложен в узел <Transform>
его базы. Поэтому для осуществления анимации поворота тела ПВСТ необходимо с течением
времени менять четвёртое число в значении поля rotation его узла <Transform>. Существует несколько
способов изменения этого значения. Здесь рассмотрим простейший способ. Он
позволяет осуществлять анимацию по двум значениям угла поворота тела, например,
от минимального значения угла поворота тела до максимального значения этого
угла. Для создания такой анимации в конец X3D-кода разметки ПВСТ нужно
добавить для каждого тела следующую пару X3D-узлов:
<OrientationChaser
DEF=”аниматор_i” initialValue=”0 0 1 min”
initialDestination=”0
0 1 max”
durarion=”5”/>
<ROUTE
fromNode=”аниматор_i ” fromField=”value_changed”
toField=”set_rotation”
toNode=”тело_i”/>
Здесь i – номер тела, min,
max – минимальное и максимальное значения угла поворота
тела. В приведённом фрагменте X3D-кода используется узел <OrientationChaser> для автоматического изменения значений полей rotation с течением времени. Поля initialValue и initialDestination содержат начальное и конечное значения
изменяемой величины. Первые три числа этих значений задают ось вращения. По
умолчанию в ПВСТ оси поворота всех тел параллельны оси аппликат НСК OXYZ. Поэтому
первые три числа в значении поля rotation равны “0 0 1”. Поле duration содержит время анимации, т.е.
общее время изменения угла поворота тела от минимального до максимального значения.
По умолчанию анимация длится 5 с. Промежуточные значения углов поворота вычисляются
автоматически по формулам линейной интерполяции и обозначены через value_changed как значения поля fromField узла <OrientationChaser>. Изменяемые значения value_changed перенаправляются узлом
<ROUTE> в поле rotation узла <Translation>
вращаемого тела. При воспроизведении анимации наблюдается поворот тела в
направлении кратчайшего пути между минимальным и максимальным значением угла.
В X3D узел <ROUTE>
используется для присвоения значения выходного поля узла источника данных (УИД)
входному полю узла приемника данных (УПД). Он обеспечивает связь полей УИД и
УПД. Узел <ROUTE> можно записать в следующем общем виде
<ROUTE fromNode=''значение DEF-поля
УИД''
fromField=''имя
out-поля УИД''
toNode=''значение
DEF-поля УПД'' toField=''имя
in-поля УПД''/>
Здесь следует отметить, что
язык X3D строго типизирован, т.е. значения всех полей относятся к тому или иному
типу. Кроме этого поле имеет один из четырёх возможных типов доступа: inputOnly
(только вход), outputOnly (только выход), inputOutput (вход-выход) и initialize
(инициализация).
Если поле имеет тип доступа initializeOnly, то поле является закрытым, т.е. содержит неизменяемые исходные
значения свойств узла. Поле, у которого тип доступа inputOnly, называют in-полем
(входным полем). Это поле является контейнером для изменяемых данных, которые
могут поступать в это поле от выходных полей других узлов. Для выходного (out-) поля
тип доступа outputOnly. Оut-поле содержит значения,
которые можно отправить в in-поля других узлов. Если тип
доступа inputOutput, то имеет место inOut-поле, в которое можно
записать новые значения и прочитать изменившиеся значения, т.е. inOut-поле
является одновременно in-полем и оut-полем.
В узле <ROUTE> имя in-поля
можно использовать только в качестве значения поля toField. Имя out-поля
используется в качестве значения поля fromField узла <ROUTE>.
Значение out-поля одного узла можно отправить в in-поля
других узлов. inOut-поле имеет одновременно свойства как in-поля,
так и out-поля. Если inOut-поле в <ROUTE> рассматривается как in-поле,
то к началу нового значения этого поля добавляется префикс set_.
Если же inOut-поле выступает в роли оut-поля, то к концу его
значения приписывается суффикс _changed. К in-полям и inOut-полям
обращаются как к полям ввода (input – ввод), так как в них
можно ввести (направить в in-поле) новое значение. К оut-полям
и inOutполям обращаются как к полям вывода (output – вывод), так как к ним
можно обратиться и взять (вывести из этого out-поля) значение, например,
переадресовать это значение в in-поле (или inOut-поле)
УПД при помощи <ROUTE>. Можно смотреть на <ROUTE> как на
объектно-ориентированный оператор присваивания (объект1.свойствоА=объект2.свойствоВ)
в виде toNode. toField = fromNode. fromField.
Значения полей с типом
доступа Initialize нельзя изменить после загрузки
X3D-сцены.
В нашем случае значение out-поля
value_changed узла <OrientationChaser> пересылается в inOut-поля узла <Translation> при помощи <ROUTE>.
В момент изменения значений
полей узла наступает событие. X3D использует модель dataflow
(поток данных) для изменения значений полей во время выполнения кода. Например, в узле
<ROUTE
fromNode=''q1'' fromField=''value_changed''
toNode=''тело_1''
toField=''set_rotation''/>
значение DEF-поля УИД равно 𝑞1, имя выходного поля УИД равно value_changed, значение DEF-поля УПД равно тело_1, имя входного поля УПД равно set_rotation. Последнее имя является именем поля rotation
УТ дополненное префиксом set_.
В качестве примера в X3D-коде 1
приведён код анимации маятника. В этом коде разметка структуры, полученная
генератором, описанном в предыдущем разделе, дополнена узлами <OrientationChaser> и <ROUTE>. Начальное и конечное значения угла поворота
взяты из двух последних столбцов ТПСТ. Эти значения из градусов переведены в
радианы и записаны четвёртым числом в поля initialValue и initialDestination узла <OrientationChaser>. Такую разметку легко генерировать автоматически, дописывая к разметке
структуры СТ N пар узлов <OrientationChaser> и <ROUTE>,
где N – количество тел СТ, т.е. число строк ТПСТ.
Для автоматической генерации
X3D-кода анимации ПВСТОД используется генератор,
представленный в XSLT-коде 1. На вход XSLT-генератору передаётся X3D-код
структуры ПВСТОД. В XSLT-коде 1 содержатся два шаблона <template>.
Первый шаблон копирует весь X3D-код ВД. Во втором шаблоне
открывается внешний XsysTel-документ “структура.xml”. Цикл <for-each>
для каждого узла <Тело> XsysTel-документа генерирует узел <OrientationChaser>, в поля initialValue и initialDestination которых записываются минимальное
и максимально значения угла поворота тела относительно своей базы, выраженные в
радианах при помощи переводного множителя. Значения угла воворота берутся из
атрибутов min и max узлов <Teло>
XsysTel-документа. Здесь же генерируется узел <ROUTE>,
осуществляющий коммутацию полей узлов <OrientationChaser> и <Transform>.
X3D-код 6.1. Код
анимации маятника
<X3D version="3.2"> <Scene> <Background
skyColor="1 1 1"/> <Viewpoint
position="0 0 4"/> <Transform DEF="тело_0"> <Inline
url="тело_0.x3d"/> <Transform
DEF="тело_1" translation="0,0,0"> <Inline
url="тело_1.x3d"/> </Transform> </Transform> <OrientationChaser
duration="5" DEF="аниматор1" initialValue="0 0 1 -1.57077" initialDestination="0 0 1
1.57077"/> <ROUTE fromNode="аниматор1" fromField="value_changed"
toField="set_rotation"
toNode="тело_1"/> </Scene> </X3D> |
|
XSLT-код 6.1. Код генератора X3D-анимации ПВСТД
по XsysTel-коду
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:template
match="node() | @*">
<xsl:copy>
<xsl:apply-templates
select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template
match="Transform">
<xsl:copy-of
select="." />
<xsl:for-each
select="document('структура.xml')//Тело">
<OrientationChaser
duration="5">
<xsl:attribute
name="DEF">
<xsl:value-of
select="concat('аниматор',position())" /></xsl:attribute>
<xsl:attribute
name="initialValue">
<xsl:value-of
select="concat('0 0 1 ',@min*0.017453)" /></xsl:attribute>
<xsl:attribute
name="initialDestination">
<xsl:value-of
select="concat('0 0 1 ',@max*0.017453)" /></xsl:attribute>
</OrientationChaser>
<ROUTE
fromField="value_changed" toField="set_rotation">
<xsl:attribute
name="fromNode">
<xsl:value-of
select="concat('аниматор',position())" /></xsl:attribute>
<xsl:attribute
name="toNode">
<xsl:value-of
select="concat('тело_',position())" /></xsl:attribute>
</ROUTE>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
7. Анимация
ПВСТ по таблице программных движений
Анимация ПВСТОД по
экстремальным значениям относительных углов поворота тел имеет ряд существенных
ограничений. Во-первых, анимировать можно только монотонные (возрастающие или
убывающие) изменения углов. Во-вторых, направление изменения угла определяется
по направлению кратчайшего поворота, например, поворот от 1° до 180° будет осуществляться в
направлении против часовой стрелки, а от -1° до 180° – в противоположном. В-третьих, скорость
угла поворота постоянна и определяется по умолчанию условием линейной интерполяции
промежуточных значений углов поворота. Поэтому такая анимация используется в основном
для просмотри или демонстрации X3D-модели СТ в динамике. Одним
из способов, позволяющих осуществлять произвольную анимацию ПВСТ, является
задание относительных углов поворота тел при помощи таблицы программных
движений (ТПД), состоящей из N+1 столбцов, где N – количество
тел ПВСТ. Первый столбец имеет имя t и содержит моменты времени в
секундах, для которых в остальных столбцах содержатся значения обобщённых координат
(qi), описывающих относительные углы поворота тел ПВСТ.
ТПД может иметь произвольное количество строк, каждая из которых описывает
положение СТ в данную секунду анимации.
Для создания такой анимации
в конец X3D-кода разметки ПВСТ нужно
добавить X3D-узел:
<TimeSensor DEF="таймер" loop="true"
cycleInterval="T"/>
Здесь T – общее время анимации. <TimeSensor>
используется для запуска анимации в заданный момент времени, выдачи абсолютного
и относительного времени и временных квантов. Он необходим для реализации анимации
с течением времени, регулирования скорости анимации. По умолчанию после
загрузки сцены <TimeSensor> сразу начинает генерировать новые выходные
временные значения. В поле fraction_changed
записываются относительные значениия степени завершенности цикла. В начале цикла fraction_changed='0', в конце цикла fraction_changed='1'. Циклов работы у <TimeSensor>
один (loop='false') или бесконечно много (loop='true'). Длительность цикла задаётся
в поле cycleInterval. По умолчанию loop='false'.
Для того, чтобы определить,
как должны изменяться углы поворота тел с течением времени, нужно после <TimeSensor>
добавить для каждого тела следующую тройки X3D-узлов:
<OrientationInterpolator DEF="аниматор_i"
key="набор точек разбиения временного интервала на
части"
keyValue="набор значений углов поворота,
соответствующий
точкам в поле key"/>
<ROUTE
fromField="value_changed" toField="set_translation"
fromNode="аниматор_i" toNode="тело_1"/>
<ROUTE fromNode="таймер" fromField="fraction_changed"
toField="set_fraction" toNode="аниматор_i"/>
Узел <OrientationInterpolator> называется интерполятором угла поворота. В каждом интерполяторе в
поле key записаны кванты (части,
сотые доли процента) времени, в течение которых угол поворота тела принимает
соответствующие значения из списка в поле keyValue.
Первый узел <ROUTE> связывает out-поле value_changed узла <OrientationInterpolator> inOut-полем rotation узла <Transform>. Второй узел <ROUTE> связывает out-поле fraction_changed узла <TimeSensor> inOut-полем set_fraction узла <OrientationInterpolator>. Таким образом, при запуске
анимации узел интерполяции начнёт получать от узла <TimeSensor> текущие значения времени.
Общее время анимации, записанное в поле cycleInterval узла <TimeSensor>
будет разбито на кванты в соответствии со значениями в поле key узла <OrientationInterpolator>. В соответствующие моменты времени
Описанный механизм удобно
использовать для осуществления анимации на основе ТПД. Общее время анимации T (значение
поля cycleInterval таймера) можно брать из последней
строки первого столбца ТПД. Поле key
интерполятора формируется на основе значений первого столбца ТПД по формуле ki = ti / T, где ki – очередное значение поля key, ti – значение из i-й
строки первого столбца ТПД, T – общее время анимации.
Поле keyValue формируется на основе
значений столбца qi., т.е. в него записываются
значения углов поворота тела. В ТПД эти значения записываются в градусах и их
нужно перевести в радианы.
Пример 1. Пусть необходимо осуществить анимацию тел двойного маятника. В течение
двух секунд после начала анимации первое звено поворачивается на угол 30°. В следующие две секунды второе звено
вращается на -30°. В последние две секунды
оба звена возвращаются в исходное положение. Соответствующая ТПД имеет вид:
Код X3D-анимации представлен в
листинге 1. Здесь в первом интерполяторе весь временной интервал разбит на четыре
части, которым соответствуют четыре значения угла поворота первого тела маятника.
Значения поля key определены следующим образом
0/6=0, 2/6=0.3333, 4/6=0.6666, 6/6=1. Первые три значения поля keyValue определяют ось поворота
тела и постоянны для ПВСТ, а четвертое значение равно углу поворота в радианах.
В результате первое тело к концу второй секунды анимации повернётся на угол 30°. В этом положении оно будет оставаться
следующие две секунды, а затем вернётся в исходное положение за две секунды.
Аналогично сформированы поля key
и keyValue второго <OrientationInterpolator>.
Если в узле <OrientationInterpolator> количество значений в поле keyValue
не соответствует количеству значений в поле key,
то <OrientationInterpolator> работать не будет. Промежуточные значения
поля keyValue интерполируются линейно
и в процессе анимации записываются в поле value_changed.
Если необходимо организовать более гладкое движение тел, то нужно ввести большее
количество точек в поле key (и соответственно
в поле keyValue), т.е. добавить
промежуточных строк в ТПД.
Для автоматической генерации
X3D-кода анимации ПВСТОД используется генератор,
представленный в XSLT-коде 1. Входным документом для генератора является
ТПД, например, ТПД двойного маятника в листинге 1. Генератор состоит из трёх
шаблонов <template>. В первом шаблоне из файла с анимацией СТ по
экстремальным значениям угла поворота тел копируются корневые X3D-узлы,
разметка структуры СТ, т.е. все узлы <Transform>. Затем для каждого тела
генерируется узел <OrientationInterpolator>, содержащий поля key и keyValue. Для вычисления этих полей
вызываются именованные шаблоны “получить_key” и “получить_keyValue”.
Оба шаблона вызываются рекурсивно, чтобы дописать в строковую переменную новое
значение на каждом шаге рекурсии. В шаблоне “получить_key” для вычисления очередного
значения значение времени из первого столбца текущей строки ТПД делится на
общее время анимации. В шаблоне “получить_keyValue” для получения нового
значения к строке “0 0 1” дописывается новый угол поворота, переведённый в
градусы, содержащийся в одном из столбцов ТПД.
X3D-код 7.1. Код
анимации двойного маятника
<X3D><Scene><Background skyColor="1 1
1"/><Viewpoint position="0 0 4"/> <Transform
DEF="тело_0"><Inline url="тело_0.x3d"/> <Transform
DEF="тело_1" translation="0,0,0"> <Inline
url="тело_1.x3d"/> <Transform
DEF="тело_2" translation="0,-0.3,0"> <Inline
url="тело_2.x3d"/></Transform> </Transform> </Transform> <TimeSensor
DEF="таймер" loop="true" cycleInterval="6"/> <OrientationInterpolator
DEF="аниматор1" key="0, 0.3333, 0.6667,
1.0000" keyValue="0 0 1 0, 0 0 1
0.52359, 0 0 1 0.52359, 0 0 1 0"/> <OrientationInterpolator
DEF="аниматор2" key="0, .3333, .6667,
1.0000" keyValue="0 0 1 0, 0 0 1
0, 0 0 1 -0.52359, 0 0 1 0"/> <ROUTE
fromField="value_changed" toField="set_rotation" fromNode="аниматор1"
toNode="тело_1"/> <ROUTE
fromNode="таймер" fromField="fraction_changed"
toField="set_fraction" toNode="аниматор1"/> <ROUTE
fromField="value_changed" toField="set_rotation" fromNode="аниматор2"
toNode="тело_2"/> <ROUTE
fromNode="таймер" fromField="fraction_changed" toField="set_fraction"
toNode="аниматор2"/> </Scene></X3D> |
|
Листинг 1.
ТПД анимации двойного маятника
<html><table>
<tr><td>0</td><td>0</td><td>0</td><td>Начальное
положение</td></tr>
<tr><td>2</td><td>30</td><td>0</td>
<td>Первое звено
развёрнуто на угол 30 градусов</td></tr>
<tr><td>4</td><td>30</td><td>-30</td>
<td>Втрое звено
развёрнуто на угол -30 градусов</td></tr>
<tr><td>6</td><td>0</td><td>0</td>
<td>Звенья в исходном
положении</td></tr>
</table></html>
XSLT-код 7.1. Код генератора X3D-анимации ПВСТД
по ТПД
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:param name="path" />
<xsl:param name="TP" />
<xsl:variable name="анимация" select="document(concat($path,'/анимация0.x3d'))"
/>
<xsl:variable name="ТП"
select="document($TP)" />
<xsl:variable name="ТППД"
select="." />
<xsl:variable
name="колПереходов" select="count(//html/table/tr)" />
<xsl:variable name="время"
select="number($ТППД//html/table/tr[last()]/td[1])" />
<xsl:template match="/">
<X3D>
<Scene>
<Background skyColor="1 1
1" />
<Viewpoint position="0 0
4" />
<xsl:copy-of
select="$анимация//X3D/Scene/Transform" />
<TimeSensor DEF="таймер"
loop="true">
<xsl:attribute
name="cycleInterval">
<xsl:value-of
select="$время" /></xsl:attribute>
</TimeSensor>
<xsl:variable
name="key">
<xsl:call-template
name="получить_key" /> </xsl:variable>
<xsl:for-each
select="$ТП//html/table/tr">
<xsl:variable name="keyValue">
<xsl:call-template
name="получить_keyValue">
<xsl:with-param
name="номерТела" select="position()" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="поз"
select="position()" />
<xsl:element
name="{name($анимация//X3D/Scene/(PositionInterpolator|OrientationInterpolator)[$поз])}">
<xsl:attribute
name="DEF">
<xsl:value-of
select="concat('аниматор',$поз)" /></xsl:attribute>
<xsl:attribute
name="key">
<xsl:value-of select="$key" /></xsl:attribute>
<xsl:attribute
name="keyValue">
<xsl:value-of
select="$keyValue" /></xsl:attribute>
</xsl:element>
</xsl:for-each>
<xsl:copy-of select="$анимация//X3D/Scene/ROUTE"
/> </Scene>
</X3D>
</xsl:template>
<xsl:template
name="получить_keyValue">
<xsl:param
name="номерСтрокиТППД" select="$колПереходов" />
<xsl:param name="номерТела"
/>
<xsl:if test="1 <= $номерСтрокиТППД">
<xsl:variable name="тело"
select="$ТП//html/table/tr[$номерТела]" />
<xsl:variable name="ОК">
<xsl:variable name="q" select="$ТППД//html/table/tr[$номерСтрокиТППД]/td[$номерТела+1]"
/>
<xsl:choose>
<xsl:when test='$тело/td[3]="В"'>
<xsl:variable
name="НК">
<xsl:choose>
<xsl:when
test='$тело/td[4]="X"'>
<xsl:value-of
select="'1 0 0'" /> </xsl:when>
<xsl:when
test='$тело/td[4]="Y"'>
<xsl:value-of
select="'0 1 0'" /> </xsl:when>
<xsl:when
test='$тело/td[4]="Z"'>
<xsl:value-of
select="'0 0 1'" /> </xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:value-of
select="concat($НК,' ',string(number($q)*0.017453))" />
</xsl:when>
<xsl:when
test='$тело/td[3]="П"'>
<xsl:variable name="x"
select="tokenize($тело/td[5],',\s*')[1]" />
<xsl:variable name="y"
select="tokenize($тело/td[5],',\s*')[2]" />
<xsl:variable name="z"
select="tokenize($тело/td[5],',\s*')[3]" />
<xsl:choose>
<xsl:when
test='$тело/td[4]="X"'>
<xsl:value-of
select="concat($q,' ',$y,' ',$z)" /> </xsl:when>
<xsl:when
test='$тело/td[4]="Y"'>
<xsl:value-of
select="concat($x,' ',$q,' ',$z)" /> </xsl:when>
<xsl:when
test='$тело/td[4]="Z"'>
<xsl:value-of
select="concat($x,' ',$y,' ',$q)" /> </xsl:when>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:call-template
name="получить_keyValue">
<xsl:with-param
name="номерСтрокиТППД" select="$номерСтрокиТППД - 1" />
<xsl:with-param
name="номерТела" select="$номерТела" />
</xsl:call-template>
<xsl:value-of select="concat(',
',replace($ОК,'--',''))" /> </xsl:if>
</xsl:template>
<xsl:template
name="получить_key">
<xsl:param
name="номерСтрокиТППД" select="$колПереходов" />
<xsl:if test="1 <= $номерСтрокиТППД">
<xsl:variable name="доля"
select="format-number(number($ТППД//html/table/tr[$номерСтрокиТППД]/td[1])
div $время,'#.0000')" />
<xsl:call-template
name="получить_key">
<xsl:with-param
name="номерСтрокиТППД" select="$номерСтрокиТППД - 1" />
</xsl:call-template>
<xsl:value-of select="concat(',
',$доля)" /> </xsl:if>
</xsl:template>
</xsl:stylesheet>
8. Вычислительная анимация
Если существует
функциональная зависимость между значениями относительных углов поворота тел и
временем движения, то ТПД может быть вычислена автоматически. В этом случае рекомендуется
выразить все значения углов поворота выразить через время движения t и
установить для t диапазон изменения от 0 до T и шаг приращения времени dt.
Для программирования формул
вычисления углов поворота q1(t), q2(t), можно использовать
любой удобный пользователю язык. В ПО «СистемаТел» используются JS-шаблоны
кодов для вычисления углов поворота через время движения и автоматического
заполнения ТПД.
В листинге 1 приведена
заготовка JS-кода для ввода программы вычисления ОК. В первой строке кода
записывается комментарий, характеризующий вид движения. Во второй и последующих
строках вместо многоточия записываются параметры анимации: время движения,
время перехода (шаг по времени), формулы вычисления угла поворота. Для перевода
радиан в градусы и обратно объявлены коэффициенты rg и gr. После объявления
переменных следует цикл, вычисляющий значения ОК в моменты времени t. Вычисленные
значения хранятся в массивах и используются при формировании ТППД. t меняет
значения от 0 до T, увеличиваясь на dt при каждой итерации цикла. i – номер
перехода.
Пример 1. В качестве примера рассмотрим колебания двойного маятника. Пусть необходимо
осуществить анимацию тел двойного маятника. Время движения T=5 cекнуд,
приращение времени движения dt=1 секунда. Для задания
гармонических колебаний маятника используем формулы q1=2*sin(3*t) и q2=3*sin(2*t). JS-код вычисления ТПД приведена
в листинге 2. Соответствующая ТПД примет вид:
Рассчитанная ТПД
используется для генерации анимации. Код анимации сгенерированный по
вычисленной таблице приведён в X3D-коде 1.
Листинг 8.1.
JS-шаблоны кодов для вычисления углов поворота через время
движения
//
Комментарий вида движения
var
T=... , // время движения
dt=...
, // приращение времени движения
//
коэффициент перевода радиан в градусы
gr=0.01745,
//
коэффициент перевода градусов в радианы
rg=57.2959,
q1=[],q2=[]...;
// описание массивов ОК
for(var t=0.0,i=0; t<=T;
t+=dt, i++){
q1[i]=... ;
q2[i]=…;
}
Листинг 8.2. JS-код кодов для вычисления углов поворота двойного
маятника через время движения
//
колебания двойного маятника
var
T=5 , // время движения
dt=1
, // приращение времени движения
//
коэффициент перевода радиан в градусы
gr=0.01745,
//
коэффициент перевода градусов в радианы
rg=57.2959,
q1=[],q2=[];
// описание массивов ОК
for(var t=0.0,i=0; t<=T;
t+=dt, i++){
q1[i]=2*Math.sin(3*t) ;
q2[i]=3*Math.sin(2*t) ;
}