Вы можете разложить матрицу на базовые преобразования: перемещение, масштабирование и вращение. Учитывая эту матрицу:M=TRS
M=⎡⎣⎢⎢⎢a00a10a200a01a11a210a02a12a220a03a13a231⎤⎦⎥⎥⎥
t=(a03,a13,a23)
s=(s0,s1,s2)
s0=∥(a00,a10,a20)∥s1=∥(a01,a11,a21)∥s2=∥(a02,a12,a22)∥
Теперь у вас есть шкала, вы можете избавиться от нее, используя подматрицу , соответствующую , умножив матрицу на обратную шкалу чтобы get3×3RSS−1R
(RS)S−1=⎡⎣⎢a00a10a20a01a11a21a02a12a22⎤⎦⎥⎡⎣⎢s0000s1000s2⎤⎦⎥−1=⎡⎣⎢a00a10a20a01a11a21a02a12a22⎤⎦⎥⎡⎣⎢1/s00001/s10001/s2⎤⎦⎥
Таким образом ( ):(RS)S−1=RI=R
R=⎡⎣⎢a00/s0a10/s0a20/s0a01/s1a11/s1a21/s1a02/s2a12/s2a22/s2⎤⎦⎥
Это окончательная матрица вращения. Вы можете в дальнейшем разложить его разными способами. Это довольно долго, но вы можете найти декомпозицию матрицы вращения .
Этот метод дает только эквивалентные значения в виде перевода, масштабирования и поворота (исходная матрица может быть результатом других типов преобразований). Могут возникнуть проблемы с точностью с плавающей точкой с углами поворота, если вы в дальнейшем будете использовать разложенные углы, ошибки округления могут накапливаться в вычислениях. Вам не следует использовать его, если вы сами не создали матрицу.
Если вы - тот, кто построил матрицу и хотел разложения, чтобы иметь возможность редактировать и отображать перевод, масштабирование и вращение по отдельности и независимо , вероятно, самое чистое, почему хранить компоненты , и в классе преобразования индивидуально как векторы (может быть кватернионом для вращения). Только когда вам нужна матрица преобразования, создайте матрицу из этих компонентов (матрицу можно кэшировать до тех пор, пока какой-либо компонент не будет изменен).tsrTRS