Given this transformation matrix, how do I decompose it into translation, rotation and scale matrices?

I have this problem from my Graphics course. Given this transformation matrix:

$$\begin{pmatrix} -2 &-1& 2\\ -2 &1& -1\\ 0 &0& 1\\ \end{pmatrix}$$

I need to extract translation, rotation and scale matrices. I've also have the answer (which is $TRS$): $$T=\begin{pmatrix} 1&0&2\\ 0&1&-1\\ 0&0&1\end{pmatrix}\\ R=\begin{pmatrix} 1/\sqrt2 & -1/\sqrt2 &0 \\ 1/\sqrt2 & 1/\sqrt2 &0 \\ 0&0&1 \end{pmatrix}\\ S=\begin{pmatrix} -2/\sqrt2 & 0 & 0 \\ 0 & \sqrt2 & 0 \\ 0& 0& 1 \end{pmatrix} % 1 0 2 1/sqrt(2) -1/sqrt(2) 0 -2/sqrt(2) 0 0 %T = 0 1 -1 R = /1/sqrt(2) 1/sqrt(2) 0 S = 0 sqrt(2) 0 % 0 0 1 0 0 1 0 0 1 $$

I just have no idea (except for the Translation matrix) how I would get to this solution.


I am a person from the future, and I had the same problem. For future reference, here's the algorithm for 4x4. You can solve your 3x3 problem by padding out your problem to the larger dimensions.

Start with a transformation matrix:$$ \begin{bmatrix} a & b & c & d\\ e & f & g & h\\ i & j & k & l\\ 0 & 0 & 0 & 1 \end{bmatrix} $$

  1. Extract Translation
    This is basically the last column of the matrix:$$ \vec{t} = <d,h,l> $$While you're at it, zero them in the matrix.

  2. Extract Scale
    For this, take the length of the first three column vectors:$$ s_x = \|<a, e, i>\|\\ s_y = \|<b, f, j>\|\\ s_z = \|<c, g, k>\|\\ \vec{s} = <s_x,s_y,s_z> $$

  3. Extract Rotation
    Divide the first three column vectors by the scaling factors you just found. Your matrix should now look like this (remember we zeroed the translation):$$ \begin{bmatrix} a/s_x & b/s_y & c/s_z & 0\\ e/s_x & f/s_y & g/s_z & 0\\ i/s_x & j/s_y & k/s_z & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} $$This is the rotation matrix. There are methods to convert it to quaternions, and from there to axis-angle, if you want either of those instead.

resource


It appears you are working with Affine Transformation Matrices, which is also the case in the other answer you referenced, which is standard for working with 2D computer graphics. The only difference between the matrices here and those in the other answer is that yours use the square form, rather than a rectangular augmented form.

So, using the labels from the other answer, you would have

$$ \left[ \begin{array}{ccc} a & b & t_x\\ c & d & t_y\\ 0 & 0 & 1\end{array}\right]=\left[\begin{array}{ccc} s_{x}\cos\psi & -s_{x}\sin\psi & t_x\\ s_{y}\sin\psi & s_{y}\cos\psi & t_y\\ 0 & 0 & 1\end{array}\right] $$

The matrices you seek then take the form:

$$ T=\begin{pmatrix} 1 & 0 & t_x \\ 0 & 1 & t_y \\ 0 & 0 & 1 \end{pmatrix}\\ R=\begin{pmatrix} \cos{\psi} & -\sin{\psi} &0 \\ \sin{\psi} & \cos{\psi} &0 \\ 0 & 0 & 1 \end{pmatrix}\\ S=\begin{pmatrix} s_x & 0 & 0 \\ 0 & s_y & 0 \\ 0 & 0 & 1 \end{pmatrix} $$

If you need help with extracting those values, the other answer has explicit formulae.


I come from a more distant future ;-) and this is how I decompose affine matrices:

$H = \begin{bmatrix} 1 & 0 & 1 & 0 \\ 1 & 1 & 1 & 0 \\ 1 & 1 & 0 & 1 \\ 0 & 0 & 0 & 1 \end{bmatrix}$

Translation

Extract translation from last column:

$T = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 1 \\ 0 & 0 & 0 & 1 \end{bmatrix}, L = \begin{bmatrix} 1 & 0 & 1 & 0 \\ 1 & 1 & 1 & 0 \\ 1 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}$

$H = T L$

Rotation

Calculate the polar decomposition of $L$ to obtain rotation $R$ and stretch $S$ matrices:

$L = R S$

$H = T R S$

$R = \begin{bmatrix} 0.707 & -0.5 & 0.5 & 0 \\ 0 & 0.707 & 0.707 & 0 \\ 0.707 & 0.5 & -0.5 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}, S = \begin{bmatrix} 1.414 & 0.707 & 0.707 & 0 \\ 0.707 & 1.207 & 0.207 & 0 \\ 0.707 & 0.207 & 1.207 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}$

When the determinant of $R$ is negative (as in this case) it is necessary to change the sign of the linear part:

$R = \begin{bmatrix} -0.707 & 0.5 & -0.5 & 0 \\ 0 & -0.707 & -0.707 & 0 \\ -0.707 & -0.5 & 0.5 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}, S = \begin{bmatrix} -1.414 & -0.707 & -0.707 & 0 \\ -0.707 & -1.207 & -0.207 & 0 \\ -0.707 & -0.207 & -1.207 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}$

Scale

The stretch matrix $S$ can be further analyzed to obtain up to three scale matrices.

$S = S_1 S_2 S_3$

$H = T R S_1 S_2 S_3$

Each eigenvalue of $S$ represents a scale factor $f_i$ and its corresponding eigenvector $x_i$ represents the scaling axis. Each pair can be used to construct a scale matrix:

$S_i = I + x_i x_i^T (f_i-1)$

$f_1 = -2.414$, $x_1 = \begin{bmatrix} 0.707 \\ 0.5 \\ 0.5 \\ 0 \\ \end{bmatrix}$, $S_1 = \begin{bmatrix} -0.707 & -1.207 & -1.207 & 0 \\ -1.207 & 0.146 & -0.854 & 0 \\ -1.207 & -0.854 & 0.146 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}$

$f_2 = -1$, $x_2 = \begin{bmatrix} 0 \\ -0.707 \\ 0.707 \\ 0 \\ \end{bmatrix}$, $S_1 = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}$

$f_1 = -0.414$, $x_1 = \begin{bmatrix} 0.707 \\ -0.5 \\ -0.5 \\ 0 \\ \end{bmatrix}$, $S_1 = \begin{bmatrix} 0.293 & 0.5 & 0.5 & 0 \\ 0.5 & 0.646 & -0.354 & 0 \\ 0.5 & -0.354 & 0.646 & 0 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix}$

In the future we all use Jupyter Notebooks like this one that implements the method in Python. You can copy and test it.