Skip to content

Transformation

Transformation

2D

The transformation matrix is Rotate THEN Translate (and scale)

[cosθsinθtxsinθcosθty001]=[10tx01ty001][cosθsinθ0sinθcosθ0001]

Note: We always use TR because in this form the translation is applied later and is explicit.

TR=[1t01][r001]=[rt01][rrt01]=[r001][1t01]=RT

3D

Main difference from 2D is the three rotation matrices along three axes:

Rx(α)=[10000cosαsinα00sinαcosα00001]Ry(α)=[cosα0sinα00100sinα0cosα00001]Rz(α)=[cosαsinα00sinαcosα0000100001]

With the final form:

Rxyz(α)=Rx(α)Ry(α)Rz(α)

Rodrigues' Rotation Formula for rotation along any axis n:

R(n,α)=cosαI+(1cosα)nnT+sinα[0nxnynz0nxnynx0]

Decompose 3D transformation

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):
    # M: [4, 4], assuming NO scaling.

    # translation 
    T = np.eye(4)
    T[:3, 3] = M[:3, 3]

    # rotation at different axes
    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)