Трансформация в SVG.

Лабораторная работа №5 по предмету «Графическая визуализация».

Трансформация

Выполнил студент второго курса математического факультета Фомин В.Л.

Цель работы:

Создать изображение кубика. На каждой грани кубика должна быть изображена окружность и квадратичная кривая Безье, отражённая симметрично оси Ox, относительно оси Oy, относительно осей Ox и Oy, где O - центр квадрата и окружности. Стенки кубика должны иметь некоторую прозрачность.



Рисунок SVG lab05.svg

Соответствующий рисунок имеет ширину 800 пикселей и высоту 600 пикселей.

1. Изображение квадрата, окружности и квадратичной кривой Безье.




Рисунок SVG lab05p1.svg

2. Добавление отражения кривой Безье относительно вертикальной оси.




Рисунок SVG lab05p2.svg

3. Добавление отражения кривой Безье относительно горизонтальной оси.




Рисунок SVG lab05p3.svg

4. Добавление отражения кривой Безье относительно центра.




Рисунок SVG lab05p4.svg

5. Добавление кривой Безье, повёрнутой на 90 градусов относительно центра




Рисунок SVG lab05p5.svg

5. Рисование левой грани кубика.

<g transform=" translate(98,53) skewY(-45) scale(0.353,1) ">

</g>


Рисунок SVG lab05p6.svg

6. Добавление задней грани кубика.

<g transform=" translate(98,53) skewY(-45) scale(0.353,1) ">

</g>
<g transform="translate(88.4, -88.4) skewX(0)">

</g>


Рисунок SVG lab05p7.svg

7. Добавление нижней грани кубика.

<g transform=" translate(98,53) skewY(-45) scale(0.353,1) ">

</g>
<g transform="translate(88.4, -88.4) skewX(0)">

</g>
<g transform=" translate(142,258) skewX(-45) scale(1,0.353) "">

</g>


Рисунок SVG lab05p8.svg

8. Добавление передней грани кубика.

<g transform=" translate(98,53) skewY(-45) scale(0.353,1) ">

</g>
<g transform="translate(88.4, -88.4) skewX(0)">

</g>
<g transform=" translate(142,258) skewX(-45) scale(1,0.353) "">

</g>
<g transform="translate(0,0) skewX(0)">

</g>



Рисунок SVG lab05p9.svg

9. Добавление правой грани кубика.

<g transform=" translate(98,53) skewY(-45) scale(0.353,1) ">

</g>
<g transform="translate(88.4, -88.4) skewX(0)">

</g>
<g transform=" translate(142,258) skewX(-45) scale(1,0.353) "">

</g>
<g transform="translate(0,0) skewX(0)">

</g>
<g transform=" translate(348,53) skewY(-45) scale(0.353,1) ">

</g>


Рисунок SVG lab05p9d.svg

10. Добавление верхней грани кубика.

<g transform=" translate(98,53) skewY(-45) scale(0.353,1) ">

</g>
<g transform="translate(88.4, -88.4) skewX(0)">

</g>
<g transform=" translate(142,258) skewX(-45) scale(1,0.353) "">

</g>
<g transform="translate(0,0) skewX(0)">

</g>
<g transform=" translate(348,53) skewY(-45) scale(0.353,1) ">

</g>
<g transform=" translate(142,8) skewX(-45) scale(1,0.353) ">

</g>



Рисунок SVG lab05.svg

Код SVG-документа.

<svg width="800" height="600">
<g transform=" translate(98,53) skewY(-45) scale(0.353,1) ">
<rect x="150" y="150" width="250" height="250" fill="yellow" fill-opacity="0.9" stroke="red" stroke-width="2"/>
<circle cx="275" cy="275" r="100" fill="red" stroke="red" stroke-width="2"/>
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
<g transform="scale(-1,1) translate(-550,0)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(1,-1) translate(0,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(-1,-1) translate(-550,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="rotate(90, 275, 275)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
<g transform="scale(-1,1) translate(-550,0)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(1,-1) translate(0,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(-1,-1) translate(-550,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
</g>
</g>
<g transform="translate(88.4, -88.4) skewX(0)">
<rect x="150" y="150" width="250" height="250" fill="yellow" fill-opacity="0.9" stroke="red" stroke-width="2"/>
<circle cx="275" cy="275" r="100" fill="red" stroke="red" stroke-width="2"/>
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
<g transform="scale(-1,1) translate(-550,0)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(1,-1) translate(0,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(-1,-1) translate(-550,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="rotate(90, 275, 275)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
<g transform="scale(-1,1) translate(-550,0)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(1,-1) translate(0,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(-1,-1) translate(-550,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
</g>
</g>
<g transform=" translate(142,258) skewX(-45) scale(1,0.353) ">
<rect x="150" y="150" width="250" height="250" fill="yellow" fill-opacity="0.9" stroke="red" stroke-width="2"/>
<circle cx="275" cy="275" r="100" fill="red" stroke="red" stroke-width="2"/>
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
<g transform="scale(-1,1) translate(-550,0)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(1,-1) translate(0,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(-1,-1) translate(-550,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="rotate(90, 275, 275)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
<g transform="scale(-1,1) translate(-550,0)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(1,-1) translate(0,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(-1,-1) translate(-550,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
</g>
</g>
<g transform="translate(0,0) skewX(0)">
<rect x="150" y="150" width="250" height="250" fill="yellow" fill-opacity="0.9" stroke="red" stroke-width="2"/>
<circle cx="275" cy="275" r="100" fill="red" stroke="red" stroke-width="2"/>
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
<g transform="scale(-1,1) translate(-550,0)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(1,-1) translate(0,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(-1,-1) translate(-550,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="rotate(90, 275, 275)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
<g transform="scale(-1,1) translate(-550,0)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(1,-1) translate(0,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(-1,-1) translate(-550,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
</g>
</g>
<g transform=" translate(348,53) skewY(-45) scale(0.353,1) ">
<rect x="150" y="150" width="250" height="250" fill="yellow" fill-opacity="0.9" stroke="red" stroke-width="2"/>
<circle cx="275" cy="275" r="100" fill="red" stroke="red" stroke-width="2"/>
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
<g transform="scale(-1,1) translate(-550,0)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(1,-1) translate(0,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(-1,-1) translate(-550,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="rotate(90, 275, 275)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
<g transform="scale(-1,1) translate(-550,0)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(1,-1) translate(0,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(-1,-1) translate(-550,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
</g>
</g>
<g transform=" translate(142,8) skewX(-45) scale(1,0.353) ">
<rect x="150" y="150" width="250" height="250" fill="yellow" fill-opacity="0.9" stroke="red" stroke-width="2"/>
<circle cx="275" cy="275" r="100" fill="red" stroke="red" stroke-width="2"/>
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
<g transform="scale(-1,1) translate(-550,0)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(1,-1) translate(0,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(-1,-1) translate(-550,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="rotate(90, 275, 275)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
<g transform="scale(-1,1) translate(-550,0)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(1,-1) translate(0,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
<g transform="scale(-1,-1) translate(-550,-550)">
<path d="M 175, 275    q    0,   70   100,    0"   style="fill: blue"/>
</g>
</g>
</g>
</svg>

Ссылка на рисунок.

Пояснение. При рисовании боковых граней, правой и левой используется skewY(-45), которая оставляет размер по горизонтальной оси неизменным. При этом само боковое ребро, расположенное под углом 45 градусов, возрастает в 1.4142 раза по длине. Поскольку его длина должна быть в два раза меньше исходной длины, то его следует уменьшить в 2*1.4142 раза, для чего применяется команда scale(0.353,1). Аналогично для skewX(-45) применяется scale(1,0.353).при рисовании нижней и верхней граней куба

Вывод. Неудобство заключается в необходимости подбирать соответствующее смещение параллельного переноса translate при использовании команд skewX, skewY. Это было сделано методом проб в данной работе. Однако, всё изображение на одной грани кубика может быть трансформировано на все другие его грани при помощи skewX(x, y), skewY(x,y), scale(x,y) , translate(x, y). Особенно удобной для трансформации поворота является команда rotate(Φ, X, Y) поворота на угол Φ относительно точки с координатами (X,Y).

На главную страницу.