2D
The transformation matrix is Rotate THEN Translate (and scale)
cosθsinθ0−sinθcosθ0txty1=100010txty1cosθsinθ0−sinθcosθ0001
Note: We always use TR because in this form the translation is applied later and is explicit.
TR=[10t1][r001]=[r0t1]=[r0rt1]=[r001][10t1]=RT
3D
Main difference from 2D is the three rotation matrices along three axes:
Rx(α)=10000cosαsinα00−sinαcosα00001Ry(α)=cosα0sinα00100−sinα0cosα00001Rz(α)=cosαsinα00−sinαcosα0000100001
With the final form:
Rxyz(α)=Rx(α)Ry(α)Rz(α)
Rodrigues' Rotation Formula for rotation along any axis n:
R(n,α)=cosαI+(1−cosα)nnT+sinα0nz−ny−nx0nxny−nx0
ref: https://math.stackexchange.com/questions/237369/given-this-transformation-matrix-how-do-i-decompose-it-into-translation-rotati/417813
ref: https://nghiaho.com/?page_id=846
Code in python:
from scipy.spatial.transform import Rotation as sciRot
def decompose(M):
T = np.eye(4)
T[:3, 3] = M[:3, 3]
rx = np.arctan2(M[2, 1], M[2, 2])
ry = np.arctan2(-M[2, 0], np.sqrt(M[2, 1]**2 + M[2, 2]**2))
rz = np.arctan2(M[1, 0], M[0, 0])
R = np.eye(4)
R[:3, :3] = sciRot.from_euler('xyz', [rx, ry, rz], degrees=False).as_matrix()
M2 = T @ R
assert np.allclose(M, M2)
python