Матрицы трансформаций

В данном разделе речь пойдет о классе Matrix3, который описывает матрицы трансформаций в 3ds max. Это матрицы размерностью 4x3 полностью определяют положение, ориентацию и масштаб объекта в трехмерном пространстве, т.е. его трансформацию относительно родительской системы координат (как правило мировой) и содержат в себе локальную систему координат объекта. Проще говоря, используя инструменты Move, Rotate и Scale вы меняете матрицу трансформации объекта. Что из себя представляет данная матрица? Это четыре строки, в каждой содержится по одному вектору. Сверху вниз вектора: ось X, ось Y, ось Z, и координата точки, которая будет являться точкой [0,0,0] в СК матрицы.

Пример использования матрицы в качестве системы координат:
m=matrix3 [1,1,0] [-1,1,0] [0,0,1] [100,0,0]
in coordsys m (
    dummy pos: [1,0,0] boxSize: [0.5, 0.5, 0.5] name: "X_Dummy"
    dummy pos: [0,1,0] boxSize: [0.5, 0.5, 0.5] name: "Y_Dummy"
    dummy pos: [0,0,1] boxSize: [0.5, 0.5, 0.5] name: "Z_Dummy"
    point pos: [0,0,0]
    )


Пример использования матрицы для получения точных координат вершин бокса:
b=box pos: [50,0,0] rotation: (quat 45 [0,1,0]) scale: [1,2,3]
matr=b.transform
m=b.mesh
for i=1 to 8 do (
v=getVert m i
dummy pos: v boxSize: [1,1,1]
dummy pos: (v*matr) boxSize: [3,3,3] -- ЧТОБЫ ТРАНСФОРМИРОВАТЬ ИСХОДНЫЙ ВЕКТОР, НУЖНО УМНОЖИТЬ ЕГО НА МАТРИЦУ
)


Конструкторы:

matrix3 <row1_point3> <row2_point3> <row3_point3> <row4_point3>
Матрица из векторов строк

matrix3 0
Нулевая матрица

matrix3 1
Единичная матрица (диагональные элементы трех верхних строк - единицы, остальные нули)

<quat> as matrix3
<angleaxis> as matrix3
<eulerangles> as matrix3
Матрицы поворота, образованные из соответствующих величин. Под матрицей поворота понимается такая же матрица 4x3, но в которой компонент поворота ненулевой (а компоненты перемещения и масштаба нулевые). Аналогичное правило работает и для матриц перемещения и масштаба, т.е. применение данных матриц к трансформации объекта повлияет только на его перемещение, поворот или масштабирование - одно из трех.

rotateXMatrix <number> -- ВСЕ УГЛЫ В ГРАДУСАХ
rotateYMatrix <number>
rotateZMatrix <number>
Матрицы поворота, образованные вращением единичной матрицы вокруг соответствующих осей

transMatrix <point3>
Матрица перемещения

scaleMatrix <point3>
Матрица масштаба

rotateYPRMatrix <yaw_number> <pitch_number> <roll_number>
Возвращает матрицу, определяющую трансформацию вращения путем задания углов поворота вокруг осей X, Y и Z. Все углы в градусах.

matrixFromNormal <point3>
Возвращает матрицу, у которой вектор локальной оси Z (т.е. нормаль) будет совпадать с заданным вектором <point3>. Компонент перемещения матрицы равен [0,0,0]. Величины компонента масштаба обратны значениям, требуемым для нормализации вектора <point3>.


Например, матрицы:
MatrixFromNormal [0,0,1]
MatrixFromNormal [0,1,1]

возвратят
(matrix3 [1,0,0], [0,1,0], [0,0,1], [0,0,0])
(matrix3 [0,-0.707107,0.707107] [1.41421,0,0] [0,1,1] [0,0,0])


Операторы:

<matrix3> + <matrix3>
<matrix3> - <matrix3>
<matrix3> * <matrix3>
<matrix3> as <class>
Матрицы можно конвертировать в значения Quat, AngleAxis и EulerAngles, используя компонент поворота.

<matrix3>[<integer>]
Возвращает строку, матрицы как величину Point3. Индекс лежит в диапазоне от 1 до 4.

<matrix3>[<integer>] = <Point3>
Устанавливает строку матрицы равной величине Point3. Индекс лежит в диапазоне от 1 до 4.


Свойства:

<matrix3>.row1 : Point3
<matrix3>.row2 : Point3
<matrix3>.row3 : Point3
<matrix3>.row4 : Point3
<matrix3>.translation : Point3
Запись/чтение строк. Четвертая строка row4 равна translation - она является компонентом перемещения.

Примечание: при работе с матрицами трансформации нельзя непосредственно менять значения строк и их элементов. Чтобы изменить строку или элемент строки, необходимо сначала занести всю матрицу в пользовательскую переменную, изменить в этой переменной строку матрицы и потом присвоить эту переменную свойству .transform исходного объекта.

Например, эта строка ничего не изменит:
$Teapot01.transform.row4 = [10.0,20.0,30.0]

А вот эта изменит:
myTransform = $Teapot01.transform
myTransform.row4 = [10.0,20.0,30.0]
$Teapot01.transform = myTransform


<matrix3>.rotationpart : Quat, только для чтения
<matrix3>.translationpart : Point3, только для чтения
<matrix3>.scalerotationpart : Quat, только для чтения
<matrix3>.scalepart : Point3, только для чтения
Различные компоненты трансформации, без учета остальных компонентов.

<matrix3>.determinantsign : Integer, только для чтения
Возвращает знак детерминанта матрицы


Методы:

copy <matrix3>
Создает новую независимую копию исходной матрицы, например: newMatrix3 = copy oldMatrix3

isIdentity <matrix3>
Возвращает истину (true), если матрица единичная.

inverse <matrix3>
Возвращает матрицу, обратную исходной

xformMat <transform_matrix3> <space_matrix3>
Возвращает матрицу трансформации в конкретном пространстве. Например, вы хотите повернуть объект на определенный угол и проделать это в другой, отличной от текущей системе координат. Такой поворот делается элементарно - происходит преобразование в пространство новой СК, применяется трансформация, и затем выполняется возврат к исходной СК. И данный метод трансформирует матрицу transform_matrix3 в пространство матрицы space_matrix3.
Итоговая матрица вычисляется по формуле: space_matrix3 * transform_matrix3 * inverse(space_matrix3)

identity <matrix3> -- mapped function
Устанавливает исходную матрицу или несколько исходных матриц (т.к. у функции есть свойство mapped, поэтому она может применяться сразу ко многим значениям) в единичную матрицу. Если в качестве параметра передается одна единственная матрица, то функция возвращает единичную матрицу, а если вносится массив матриц, то возвращается значение OK. В обоих случаях входящие матрицы matrix3 заменяются на единичную матрицу.

zero <matrix3> -- mapped function
Устанавливает исходную матрицу или несколько исходных матриц (т.к. у функции есть свойство mapped, поэтому она может применяться сразу ко многим значениям) в нулевую матрицу. Если в качестве параметра передается одна единственная матрица, то функция возвращает нулевую матрицу, а если вносится массив матриц, то возвращается значение OK. В обоих случаях входящие матрицы matrix3 заменяются на нулевую матрицу.

orthogonalize <matrix3> -- mapped function
Устанавливает исходную матрицу или несколько матриц в ортогональную(ые). Ортогональной считается матрица, которая представляет собой систему координат с осями, строго перпендикулярными друг другу (угол между осями 90), т.е. абсолютно без наклонов. Если в качестве параметра передается одна единственная матрица, то функция возвращает ортогональную матрицу, а если вносится массив матриц, то возвращается значение OK. В обоих случаях входящие матрицы matrix3 заменяются на ортогональные.

translate <matrix3> <point3> -- mapped function
Применяет трансформацию перемещения с приращением к исходной матрице или матрицам. Эта операция аналогична умножению СПРАВА на матрицу трансформации (исходная матрица * матрица перемещения). Если в качестве параметра передается одна единственная матрица, то функция возвращает трансформированную матрицу, а если вносится массив матриц, то возвращается значение OK. В обоих случаях входящие матрицы matrix3 заменяются на трансформированные.

rotateX <matrix3> <number> -- mapped functions -- ВСЕ УГЛЫ В ГРАДУСАХ
rotateY <matrix3> <number>
rotateZ <matrix3> <number>
rotate <matrix3> <quat>
Эти методы применяют трансформацию поворота с приращением к исходной матрице или матрицам. Операция аналогична умножению СПРАВА на матрицу трансформации (исходная матрица * матрица поворота). Если в качестве параметра передается одна единственная матрица, то функция возвращает трансформированную матрицу, а если вносится массив матриц, то возвращается значение OK. В обоих случаях входящие матрицы matrix3 заменяются на трансформированные.

scale <matrix3> <point3> [ <boolean> ] -- mapped function
Применяет трансформацию масштаба с приращением к исходной матрице или матрицам. Операция аналогична умножению СПРАВА на матрицу трансформации (исходная матрица * матрица масштаба). Если аргумент <boolean> равен true, компонент перемещения масштабируется, если false - компонент перемещения остается неизменым. В исходном коде 3ds Max была ошибка в данном методе, в случае, когда компонент перемещения не масштабировался. Т.е. нижняя строка матрицы не масштабировалась. Таким образом, масштабирование всегда происходило относительно локального центра объекта, а не мировых осей. Когда ошибку нашли, было поздно, т.к. код уже зависел от данной ошибки, алгоритмы обрабатывали матрицы неправильным способом. Поскольку простое исправление ошибки приводило к неправильной работе существующего кода, был добавлен параметр <boolean>. Если его установить равным true, компонент перемещения будет отмасштабирован правильно. Если не задать параметр, то по умолчанию он будет равен false и код заработает по-старому. Если в качестве параметра передается одна единственная матрица, то функция возвращает трансформированную матрицу, а если вносится массив матриц, то возвращается значение OK. В обоих случаях входящие матрицы matrix3 заменяются на трансформированные.

preTranslate <matrix3> <point3> -- mapped function
Применяет трансформацию перемещения с приращением к исходной матрице или матрицам. Эта операция аналогична умножению СЛЕВА на матрицу трансформации (матрица перемещения * исходная матрица). Если в качестве параметра передается одна единственная матрица, то функция возвращает трансформированную матрицу, а если вносится массив матриц, то возвращается значение OK. В обоих случаях входящие матрицы matrix3 заменяются на трансформированные.

preRotateX <matrix3> <number> -- mapped functions -- all angles in degrees
preRotateY <matrix3> <number>
preRotateZ <matrix3> <number>
preRotate <matrix3> <quat>
Эти методы применяют трансформацию поворота с приращением к исходной матрице или матрицам. Операция аналогична умножению СЛЕВА на матрицу трансформации (матрица поворота * исходная матрица ). Если в качестве параметра передается одна единственная матрица, то функция возвращает трансформированную матрицу, а если вносится массив матриц, то возвращается значение OK. В обоих случаях входящие матрицы matrix3 заменяются на трансформированные.

preScale <matrix3> <point3> [ <boolean> ] -- mapped function
Применяет трансформацию масштаба с приращением к исходной матрице или матрицам. Операция аналогична умножению СЛЕВА на матрицу трансформации (матрица масштаба * исходная матрица). Если аргумент <boolean> равен true, компонент перемещения масштабируется, если false - компонент перемещения остается неизменым. Если <boolean> не задан, то по умолчанию он будет равен false. Если в качестве параметра передается одна единственная матрица, то функция возвращает трансформированную матрицу, а если вносится массив матриц, то возвращается значение OK. В обоих случаях входящие матрицы matrix3 заменяются на трансформированные.



Связанные методы:

getEulerMatAngleRatio <matrix3_1> <matrix3_2> <eulerAngles1> <eulerAngles2> [angle:<eulertype_integer>]
При конвертации подряд нескольких матриц matrix3 в величины eulerAngles могут происходить перевороты осей. Это связано с тем, что одна и та же матрица matrix3 может быть представлена целым множеством различных значений eulerAngles. Узнать, произойдет ли переворот, можно через соотношение eulerAngles/matrix3. Это соотношение представляет собой связь разницы углов в пространстве eulerAngles и разницы углов в пространстве matrix3. Если соотношение больше чем PI, то поворот от одной матрицы до другой преобразуется в значение eulerAngles. Данный метод возвращает угловое соотношение eulerAngles/matrix3 между двумя матрицами в значение eulerAngles как величину типа float. Реальное наличие переворота зависит от величины поворота между преобразованиями в eulerAngles. Чем меньше поворот, тем точнее определяется, будет переворот или нет.

Параметры метода:
matrix3_1 и matrix3_2 - предыдущая и текущая матрицы трансформации.
eulerAngles1 и eulerAngles2 - предыдущие и текущие сконвертированные углы поворота.
Дополнительный параметр eulertype_integer задает порядок применения углов по осям. Если параметр не задан, используется порядок XYZ. Другие варианты могут быть следующими:
1 - XYZ
2 - XZY
3 - YZX
4 - YXZ
5 - ZXY
6 - ZYX
7 - XYX
8 - YZY
9 - ZXZ