« назад «

Основы 3D преобразовавний и применение их во FLASH.

[ 28 / 04 / 04 ]

Введение.
Вообще говоря, лучше всего почитать любую книжку по линейной алгебре. Здесь же будет только краткий рассказ о 3D преобразованиях.

1. Основы.
Обозначения, которые будут в тексте:
x, y, z - координаты точки
x', y', z' - новые координаты точки
px, py - проецированные координаты точки
dist - дистанция от точки наблюдения (позиции камеры) до центра координат
cnx, cny - координаты центра клипа
sin(A), cos(A), tan(A) - синус, косинус и тангенс угла A
rad = Math.PI/180 - коэффициет перевода градусов в радианы и обратно
1.1 Система координат.
В нашем случае мы будем применять правую систему координат, т.к. она наиболее часто применяется в машинной графике.

1.2 Координаты точки.
Точка в 3D пространстве представляется тремя значениями - (x,y,z), где x,y и z - это расстояние от соответствующих им осей до самой точки. То есть координаты (1, 2, 3) означают, что точка расположена на расстоянии 1 от оси X, на расстоянии 2 от оси Y и на расстоянии 3 от оси Z.

2. Преобразование поворота.
Поворот - занятие уже более интересное.

2.1 Поворот вокруг координатных осей относительно центра координат.
Для примера рассмотрим поворот точки (x,y,z) относительно оси z. В этом случае z не меняется вообще, а (x,y) меняются так же, как и при 2D повороте относительно начала координат.
Посмотрим, какие будут координаты у точки A' в результате поворота A(x,y) на угол alpha.



Пусть r = sqrt(x*x+y*y). Пусть угол AOx равен phi, тогда из рисунка видно, что cos(phi) = x/r, sin(phi) = y/r. Угол A'OA равен по условию alpha. Отсюда
x' = r*cos(alpha+phi) =
= r*(cos(alpha)*cos(phi)-sin(alpha)*sin(phi)) =
= (r*cos(phi))*cos(alpha)-(r*sin(phi))*sin(alpha) =
= x*cos(alpha)-y*sin(alpha)
y' = r*sin(alpha+phi) =
= r*(cos(alpha)*sin(phi)+sin(alpha)*cos(phi)) =
= (r*cos(phi))*sin(alpha)+(r*sin(phi))*cos(alpha) =
= x*sin(alpha)+y*cos(alpha)
Таким образом для трехмерного случая получим
x' = x*cos(alpha)-y*sin(alpha)
y' = x*sin(alpha)+y*cos(alpha)
z' = z
Аналогичные формулы получатся и для других осей поворота (Ox, Oy).

2.2 Поворот вокруг координатных осей относительно произвольной точки.
Смысл поворота вокруг произвольной точки:
- делаем сдвиг начала координат в нужную точку
- производим поворот
- возвращаем центр координат обратно на место

Формулы поворота относительно точки M(x0,y0,z0) на угол alpha
- вокруг оси X
x' = x;
y' = y0+(y-y0)*cos(A)+(z0-z)*sin(alpha);
z' = z0+(y-y0)*sin(A)+(z-z0)*cos(alpha);
- вокруг оси Y
x' = x0+(x-x0)*cos(A)+(z-z0)*sin(alpha);
y' = y;
z' = z0+(x0-x)*sin(A)+(z-z0)*cos(alpha);
- вокруг оси Z
x' = x0+(x-x0)*cos(A)+(y0-y)*sin(alpha);
y' = y0+(x-x0)*sin(A)+(y-y0)*cos(alpha);
z' = z;
2.3 Поворот вокруг произвольной оси относительно центра координат.
Вращение вокруг произвольной оси немного сложнее. Его нужно непременно знать и понимать.
Формулы поворота на угол A вокруг произвольной оси (alpha, beta, gamma)
temp = 1.0-cos(A);
x' = x*(alpha*temp*alpha + cos(A)) + y*(beta*temp*alpha - sin(A)*gamma) + z*(gamma*temp*alpha + sin(A)*beta);
y' = x*(alpha*temp*beta + sin(A)*gamma) + y*(beta*temp*beta + cos(A)) + z*(gamma*temp*beta - sin(A)*alpha);
z' = x*(alpha*temp*gamma - sin(A)*beta) + y*(beta*temp*gamma + sin(A)*alpha) + z*(gamma*temp*gamma + cos(A));
2.4 Поворот вокруг произвольной оси относительно произвольной точки.
Смысл поворота относительно произвольной точки вокруг произвольной оси:
- делаем сдвиг начала координат в нужную точку
- производим поворот вокруг произвольной оси
- возвращаем центр координат обратно на место

Формулы поворота на угол A вокруг произвольной оси (alpha, beta, gamma) относительно точки M(x0, y0, z0)
temp = 1.0-cos(A);
x' = x0 + (x-x0)*(alpha*temp*alpha + cos(A)) + (y-y0)*(beta*temp*alpha - sin(A)*gamma) + (z-z0)*(gamma*temp*alpha + sin(A)*beta);
y' = y0 + (x-x0)*(alpha*temp*beta + sin(A)*gamma) + (y-y0)*(beta*temp*beta + cos(A)) + (z-z0)*(gamma*temp*beta - sin(A)*alpha);
z' = z0 + (x-x0)*(alpha*temp*gamma - sin(A)*beta) + (y-y0)*(beta*temp*gamma + sin(A)*alpha) + (z-z0)*(gamma*temp*gamma + cos(A));
3. Преобразование масштабирования.
Преобразование масштабирования это - изменение размера, изменение масштаба.

3.1 Масштабирование относительно центра координат.
Наипростейшим масштабированием является масштабирование относительно центра координат. Это достаточно часто используемое преобразование.
Sx, Sy, Sz - коэффициенты масштабирования по осям X, Y и Z
Формула масштабирования:
x' = x*Sx;
y' = y*Sy;
z' = z*Sz;
3.2 Масштабирование относительно произвольной точки.
Данное преобразование нужно в основном для увеличения отдельных деталей фигуры. Допустим вам нужно промасштабировать один кубик. Делаем сдвиг центра координат в центр кубика, масштабируем все точки куба, и возвращаем центр координат на место. Вуаля - кубик увеличился в размерах не сдвигаясь со своего места. Смысл масштабирования относительно произвольной точки:
- делаем сдвиг начала координат в нужную точку
- производим масштабирование
- возвращаем центр координат обратно на место
Формула масштабирования относительно произвольной точки M(x0,y0,z0):
x' = x0+(x-x0)*Sx;
y' = y0+(y-y0)*Sy;
z' = z0+(z-z0)*Sz;
4. Преобразование сдвига.
Название говорит само за себя - изменение позиции точки.
4.1 Сдвиг начала координат.
incX, incY, incZ - величина сдвига по осям X, Y и Z;
Формула преобразования сдвига:
x' = x+incX;
y' = y+incY;
z' = z+incZ;
4.2 Сдвиг по произвольной оси.
Произвольная ось задаётся либо единичным вектором либо двумя точками этой оси.
• Движение по произвольной оси (x y,z), проходящей через центр координат, если ось задана единичным (unit_axis) вектором.
inc - величина сдвига
unit_axis.x *= inc;
unit_axis.y *= inc;
unit_axis.z *= inc;
x += unit_axis.x;
y += unit_axis.y;
z += unit_axis.z;
• Движение по произвольной оси, если ось задана двумя точками M1(x1,y1,z1) и M2(x2,y2,z2).
inc - величина сдвига
normal = Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1));
unit_axis.x = (x2-x1) / normal;
unit_axis.y = (y2-y1) / normal;
unit_axis.z = (z2-z1) / normal;
unit_axis.x *= inc;
unit_axis.y *= inc;
unit_axis.z *= inc;
x += unit_axis.x;
y += unit_axis.y;
z += unit_axis.z;
5. Проецирование.
Прошу не путать. Все вычисления производятся исключительно с нормальными координатами. Проецирование производится в самом конце, и оно не запоминается и не заменяет координат точки. Оно лишь нужно для визуально более реального изображения (получения перспективы) и перехода от 3d координат к 2d (монитор-то 2d, а не 3d)!

5.1 Перспективное проецирование.
Формула перспективного проецирования:
rx = cnx + x*dist/(dist+z); ry = cny - y*dist/(dist+z);
6. Комбинирование преобразований.
Последовательное выполнение нескольких преобразований можно представить в виде единого преобразования. Это затрачивает меньше ресурсов машины.

6.1 Последовательное выполнение сдвигов.
Сдвиг аддитивен, т.е. последовательное выполнение сдвигов на расстояние (T1.x, T1.y, T1.z) и (T2.x, T2.y, T2.z) эквивалентно одному сдвигу на расстояние (T1.x + T2.x, T1.y + T2.y, T1.z + T2.z).

6.2 Последовательное выполнение поворотов.
Можно показать, что два последовательных поворота аддитивны. Например повернём точку на угол 45° и после этого повернём на угол -67°. Это эквивалентно повороту на угол (45° + (-67°)) = -22°.

6.3 Последовательное выполнение масштабирований.
Первое масштабирование с коэффициентами (Sx1, Sy1, Sz1) второе с коэффициентами (Sx2, Sy2, Sz2). Следует ожидать, что суммарное масштабирование будет мультипликативным. А именно последовательное выполнение этих масштабирований даст результат, эквивалентный масштабированию (Sx1*Sx2, Sy1*Sy2, Sz1*Sz2).



© 2004 by MAX фотогалерея :: программирование :: flash :: о проекте    
Сайт создан в системе uCoz