Последовательность преобразований можно реализовать путем свертки отдельных матриц справа налево или слева направо в зависимости от порядка, в котором заданы матричные представления. Разумеется, крайний справа член произведения матриц всегда является первым преобразованием, применяемым к объекту, а крайний слева - последним. Данный порядок нужно использовать, поскольку координаты точек представляются как четырехэлементные векторы-столбцы, на которые слева действует сложная матрица преобразования 4 на 4.

В приведенной ниже программе приводятся примеры процедур построения матрицы трехмерного сложного преобразования. Чтобы получить одну сложную матрицу (инициализируется как единичная), в заданном порядке объединяются три базовых геометрических преобразования. В данном примере вначале выполняется поворот, затем масштабирование, потом трансляция. Сложная матрица вычисляется слева направо, так что преобразования вызываются в порядке их применения. Следовательно, новая построенная матрица присоединяется слева к предыдущей, и в результате обновляется матрица произведения.

class wcPt3D {

public :

GLfloat x, y, z;

} ;

typedef GLfloat Matrix4x4 [4][4]; Matrix4x4 matComposite;

/* Строится единичная матрица 4 на 4. */

void matrix4x4SetIdentity (Matrix4x4 matldent4x4)

{

GLint row, col;

for (row = 0; row < 4; row++)

for (col = 0; col < 4 ; col++)

matldent4x4 [row][col] = (row == col);

}

/* Матрица ml умножается слева на матрицу m2, результат

* записывается в m2.

*/

void matrix4x4PreMultiply (Matrix4x4 ml, Matrix4x4 m2)

{

GLint row, col;

Matrix4x4 matTemp;

for (row = 0; row < 4; row++)

for (col = 0; col < 4 ; col++)

matTemp [row][col] = ml [row][0] * m2 [0][col] +

ml [row][l] * m2 [l][col] + ml [row][2] * m2 [2][col] + ml [row][3] * m2 [3][col];

for (row = 0; row < 4; row++) for (col = 0; col < 4; col++)

m2 [row][col] = matTemp [row][col];

}

/* Процедура генерации матрицы трехмерной трансляции. */ void translate3D (GLfloat tx, GLfloat ty, GLfloat tz)

{

Matrix4x4 matTransl3D;

/* Матрица трансляции инициализируется как единичная. */ matrix4x4SetIdentity (matTransl3D);

matTransl3D [0][3] = tx;

matTransl3D [1][3] = ty;

matTransl3D [2][3] = tz;

/* Выполняется свертка матрицы matTransl3D со сложной

* матрицей.

*/

matrix4x4PreMultiply (matTransl3D, matComposite);

/* Процедура генерации матрицы поворота вокруг кватерниона. */ void rotate3D (wcPt3D pi, wcPt3D p2, GLfloat radianAngle)

{

Matrix4x4 matQuatRot;

float axisVectLength = sqrt ((p2.x - pl.x) * (p2.x - pl.x) +

(p2.y - pl.y) * (p2.y - pl.y) +

(p2.z - pl.z) * (p2.z - pl.z));

float cosA = cosf (radianAngle); float oneC = 1 - cosA; float sinA = sinf (radianAngle);

float ux = (p2.x - pl.x) / axisVectLength;


⇐ вернуться назад | | далее ⇒