Опубликован: 02.12.2011 | Доступ: свободный | Студентов: 980 / 117 | Оценка: 5.00 / 4.00 | Длительность: 09:26:00
Специальности: Программист
Теги: .net, open source, opengl
Лекция 6:

Координатные преобразования в OpenGL

< Лекция 5 || Лекция 6: 123456 || Лекция 7 >

Параллельный перенос

Для выполнения параллельного переноса библиотека реализует команду Translate[f d]. Команда имеет три параметра, определяющие координаты вектора параллельного переноса. Команда Translate формирует матрицу параллельного переноса и умножает её на текущую матрицу OpenGL.

При выполнении команды Translate формируется вертикальная матрица:

T=\begin{pmatrix}1 & 0 & 0 & x\\0 & 1 & 0 & y\\0 & 0 & 1 & z\\ 0& 0 & 0 &1\end{pmatrix}

где x, y, z– координаты вектора параллельного переноса.

Полученная матрица (T) умножается на текущую матрицу библиотеки (M), и результирующая матрица (M’) заменяет текущую матрицу OpenGL:

M’ = T * M

В результате преобразование параллельного переноса добавляется к тем преобразованиям, которые выполняла текущая матрица на момент вызова команды Translate.

В библиотеке OpenTK команда реализована как ряд статических методов класса GL (C#):

void Translate(Vector3 trans);
void Translate(Vector3d trans);
void Translate(double x, double y, double z);
void Translate(float x, float y, float z);

В Object Pascal в файле OpenGL.pas объявлено несколько процедур, которые реализуют эту команду, и различаются только типом параметров:

procedure glTranslated (x,y,z: GLdouble); 
procedure glTranslatef (x,y,z: GLfloat); 
procedure glTranslate(x,y,z: GLdouble); overload;
procedure glTranslate(x,y,z: GLfloat); overload;

Масштабирование относительно начала координат

Для выполнения операции масштабирования относительно начала координат используется команда Scale[f d]. Команда имеет три параметра, которые определяют коэффициенты масштабирования для каждой из осей координат. Команда формирует матрицу:

S=\begin{pmatrix}x & 0 & 0 & 0\\0 & y & 0 & 0\\0 & 0 & z & 0\\ 0& 0 & 0 &1\end{pmatrix}

В результате выполнения команды Scale матрица масштабирования (S) умножается на текущую матрицу (M), и результирующая матрица (M’) заменяет текущую матрицу:

M’ = S * M

В результате к преобразованиям, выполняемым текущей матрицей перед вызовом команды Scale, добавляется еще преобразование масштабирования.

В библиотеке OpenTK команда реализована как ряд статических методов класса GL (C#):

void Scale(Vector3 scale);
void Scale(Vector3d scale);
void Scale(double x, double y, double z);
void Scale(float x, float y, float z);

В Object Pascal команда реализуется с помощью процедур, которые различаются типом используемых параметров:

procedure glScaled (x,y,z: GLdouble);
procedure glScalef (x,y,z: GLfloat);
procedure glScale(x,y,z: GLdouble); overload;
procedure glScale(x,y,z: GLfloat); overload;

Поворот вокруг произвольной оси в пространстве

Преобразование поворота вокруг произвольной оси в пространстве может быть выполнено с помощью команды Rotate[f d].

В OpenTK команда реализована как ряд статических методов класса GL (C#):

void Rotate(double angle, Vector3d axis);
void Rotate(float angle, Vector3 axis);
void Rotate(double angle, double x, double y, double z);
void Rotate(float angle, float x, float y, float z);

В Object Pascal команда реализуется с помощью процедур, которые различаются типом параметров:

procedure glRotated (angle, x,y,z: GLdouble); 
procedure glRotatef (angle, x,y,z: GLfloat); 
procedure glRotate(angle, x,y,z: GLdouble); overload;
procedure glRotate(angle, x,y,z: GLfloat); overload;

Параметры x, y, z задают координаты вектора, вокруг которого выполняется поворот. Первый параметр angle определяет угол поворота в градусах вокруг вектора против часовой стрелки, если смотреть вдоль отрицательного направления вектора поворота. Необходимо обратить внимание на то, что угол поворота задается в градусах, в отличие от параметров различных тригонометрических функций в Object Pascal.

Как и при выполнении команд Translate и Scale, при выполнении команды Rotate библиотека формирует матрицу преобразования (R), которая умножается на текущую матрицу (M), результирующая матрица (M’) затем становится текущей матрицей.

M’ = R * M

Преобразование поворота вокруг произвольного вектора в пространстве является сложным преобразованием. На практике часто используют комбинацию преобразований из поворотов вокруг осей координат. Ниже приведены матрицы, выполняющие повороты вокруг осей координат.

\left( \begin{array}{cccc} 
1 & 0 & 0 & 0 \\ 
0 & cos(a) & -sin(a) & 0 \\
0  & sin(a) & cos(a) & 0 \\
0 & 0 & 0 & 1 \\
\end{array} \right) \left( \begin{array}{cccc} 
cos(a) & 0 & sin(a) & 0 \\ 
0 & 1 & 0 & 0 \\
-sin(a) & 0 & cos(a) & 0 \\
0 & 0 & 0 & 1 \\
\end{array} \right) \left( \begin{array}{cccc} 
cos(a) & -sin(a) & 0 & 0 \\ 
sin(a)  & cos(a) & 0 & 0 \\
0 & 0 & 1 & 0 \\
0 & 0 & 0 & 1 \\
\end{array} \right)
glRotated(a, 1,0,0)
GL.Rotate(a, 1,0,0)
glRotated(a, 0,1,0)
GL.Rotate(a, 0,1,0)
glRotated(a, 0,0,1)
GL.Rotate(a, 0,0,1)

Композиция преобразований

Последовательное выполнение нескольких преобразований можно представить в виде единой матрицы суммарного преобразования. Умножение на единственную матрицу выполняется быстрее, чем последовательное умножение координат каждой вершины на несколько матриц.

Матрица суммарного преобразования может быть получена умножением матриц отдельных преобразований. В общем случае результат произведения матриц зависит от порядка их умножения и не является аддитивным. Т. е. результат преобразований, который описывается матрицами, в общем случае зависит от последовательности выполнения преобразований.

При выполнении некоторых однотипных преобразований произведение матриц может быть аддитивной или мультипликативной операцией и результат выполнения таких операций не будет зависеть от порядка их выполнения. К таким преобразованиям, в частности, относятся видовые преобразования: параллельный перенос, масштабирование относительно начала координат, поворот вокруг произвольного вектора.

Две последовательные операции параллельного переноса являются аддитивными. Результат выполнения этих операций не зависит от порядка их выполнения. Например, результат последовательного сдвига точки P0 на расстояние (Tx_1,Ty_1,Tz_1) в точку P1, а затем сдвига точки P1 на расстояние (Tx_2,Ty_2,Tz_2) в точку P2 не зависит от порядка умножения матриц T1 и T2, которые описывают каждую из операций сдвига:

\text{P1 = P0 $\times$ T1;}\\\text{P2 = P1 $\times$ T2   =   (P0 $\times$ T1) $\times$ T2   =   P0 $\times$ (T1 $\times$ T2)   =  P0 $\times$ T}

Суммарный перенос, вычисленный как произведение матриц, аддитивен:

T=\begin{pmatrix}1 & 0 & 0 & Tx_1\\0 & 1 & 0 & Ty_1\\0 & 0 & 1 & Tz_1\\ 0& 0 & 0 &1\end{pmatrix}\times\begin{pmatrix}1 & 0 & 0 & Tx_2\\0 & 1 & 0 & Ty_2\\0 & 0 & 1 & Tz_2\\ 0& 0 & 0 &1\end{pmatrix}=\begin{pmatrix}1 & 0 & 0 & Tx_1+Tx_2\\0 & 1 & 0 & Ty_1+Ty_2\\0 & 0 & 1 & Tz_1+Tz_2\\ 0& 0 & 0 &1\end{pmatrix}

Последовательное выполнение операций масштабирования является мультипликативной операцией. Например, результат последовательного выполнения двух операции масштабирования с коэффициентами (Sx_1,Sy_1,Sz_1) и (Sx_2,Sy_2,Sz_2) не зависит от порядка их выполнения. Если обозначить через S1 и S2 матрицы масштабирования, получим:

\text{P1 = P0 $\times$ S1,}\\\text{P2 = P1 $\times$ S2 = (P0 $\times$ S1) $\times$ S2 = P0 $\times$ (S1 $\times$ S2) = P0 $\times$ S}
S=\begin{pmatrix}Sx_1 & 0 & 0 & 0\\0 & Sy_1 & 0 & 0\\0 & 0 & Sz_1 & 0\\ 0& 0 & 0 &1\end{pmatrix}\times\begin{pmatrix} Sx_2 & 0 & 0 & 0\\0 & Sy_2 & 0 & 0\\0 & 0 & Sz_2 & 0\\ 0& 0 & 0 &1\end{pmatrix}=\begin{pmatrix} Sx_1 \times Sx_2 & 0 & 0 & 0\\0 & Sy_1 \times Sy_2  & 0 & 0\\0 & 0 & Sz_1\times Sz_2  & 0\\0& 0 & 0 &1\end{pmatrix}

Из вычисления видно, что результирующее масштабирование, вычисленное как произведение матриц, мультипликативно и не зависит от порядка умножения матриц.

Аналогичным образом можно показать, что два последовательных поворота вокруг осей координат аддитивны.

< Лекция 5 || Лекция 6: 123456 || Лекция 7 >
Владислав Нагорный
Владислав Нагорный

Подскажите, пожалуйста, планируете ли вы возобновление программ высшего образования? Если да, есть ли какие-то примерные сроки?

Спасибо!

Лариса Парфенова
Лариса Парфенова

1) Можно ли экстерном получить второе высшее образование "Программная инженерия" ?

2) Трудоустраиваете ли Вы выпускников?

3) Можно ли с Вашим дипломом поступить в аспирантуру?