Преобразование 3D матрицы вращения 4x4 в 2d

Скажем, у нас есть матрица 4x4 с такими индексами:

00 01 02 03
10 11 12 13
20 21 22 23
30 31 32 33

Как преобразовать данные вращения (игнорируя ось z, если это помогает), содержащиеся в этой матрице, в один двумерный угол поворота (в радианах)?

Предыстория: у меня есть 3D-анимация .dae, экспортированная из Blender в формат Collada. Анимация технически 2d, все значения оси z равны 0. Я пытаюсь преобразовать матрицы 4x4 в 2d данные перемещения, поворота и масштабирования.


person Nathanael Weiss    schedule 17.05.2012    source источник


Ответы (2)


Матрица масштабов S выглядит так:

sx 0  0  0
0  sy 0  0
0  0  sz 0
0  0  0  1

Матрица перевода T выглядит так:

1  0  0  0
0  1  0  0
0  0  1  0
tx ty tz 1

Матрица вращения оси Z R выглядит так:

 cos(a) sin(a)  0  0
-sin(a) cos(a)  0  0
   0      0     1  0
   0      0     0  1

Если у вас есть матрица преобразования M, это результат ряда умножений матриц R, T и S. Глядя на M, порядок и количество этих умножений неизвестны. Однако, если мы предположим, что M=S*R*T, мы можем разложить его на отдельные матрицы. Сначала посчитаем S*R*T:

        ( sx*cos(a) sx*sin(a) 0  0)       (m11 m12 m13 m14)
S*R*T = (-sy*sin(a) sy*cos(a) 0  0) = M = (m21 m22 m23 m24)
        (     0         0     sz 0)       (m31 m32 m33 m34)
        (     tx        ty    tz 1)       (m41 m42 m43 m44)

Поскольку мы знаем, что это двухмерное преобразование, получить перевод очень просто:

translation = vector2D(tx, ty) = vector2D(m41, m42)

Чтобы рассчитать поворот и масштаб, мы можем использовать sin(a)^2+cos(a)^2=1:

(m11 / sx)^2 + (m12 / sx)^2 = 1
(m21 / sy)^2 + (m22 / sy)^2 = 1

m11^2 + m12^2 = sx^2
m21^2 + m22^2 = sy^2

sx = sqrt(m11^2 + m12^2)
sy = sqrt(m21^2 + m22^2)

scale = vector2D(sx, sy)

rotation_angle = atan2(sx*m22, sy*m12)
person miloszmaki    schedule 17.05.2012
comment
Единственное, что я бы добавил, он не исключает acos, поскольку игнорирует знак поворота. Лучше использовать a=atan2(sx*m22,sy*m12) или a=atan2(-sy*m11,sx*m21). {Я использую atan2(dx,dy), но некоторые системы определяют его как atan2(dy,dx), так что будьте осторожны}. - person John Alexiou; 17.05.2012
comment
@ ja72: Спасибо, исправил. При вычислении угла также удобно предположить, что масштаб положительный. - person miloszmaki; 17.05.2012

в этой библиотеке есть процедуры для преобразования матрицы 4x4 в ее 5 компоненты - вращение, перемещение, масштаб, сдвиг и перспектива. Вы должны иметь возможность взять формулы и просто отбросить 3-й компонент трехмерных векторов.

person jterrace    schedule 17.05.2012
comment
вычисление собственного значения - действительно умный метод. - person xiaoyi; 17.05.2012
comment
Плюсы: выглядит многообещающе. Минусы: зависит от NumPy, поэтому кажется немного запутанным. Что-нибудь подобное написано на C ++? - person Nathanael Weiss; 17.05.2012
comment
Алгоритм и реализация на C опубликованы в (1) Разложение матрицы на простые преобразования. Спенсер Томас. В Graphics Gems II, pp 320-323. Morgan Kaufmann, 1991. См. Также (2) Восстановление данных из матрицы преобразования. Рональд Гольдман. В Graphics Gems II, стр. 324-331. Морган Кауфманн, 1991. - person cgohlke; 17.05.2012
comment
Я ничего не знаю о c / c ++ - person jterrace; 17.05.2012