Масштаб матрицы 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)
Поскольку мы знаем, что это 2D преобразование, получить перевод прост:
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)
Единственное, что я бы добавил, это не избежать «acos», поскольку он игнорирует знак вращения. Лучше использовать 'a = atan2 (sx * m22, sy * m12)' или 'a = atan2 (-sy * m11, sx * m21)'. {Я использую 'atan2 (dx, dy)', но некоторые системы определяют его как 'atan2 (dy, dx)' поэтому будьте осторожны. – ja72
@ ja72: Спасибо, я исправил его. Также удобно предположить, что шкала положительна при вычислении угла. – miloszmaki
Спасибо @miloszmaki. Эти уравнения работали как шарм. –