91

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.

Cameron Buie
  • 102,994
metavers
  • 911

3 Answers3

89

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.

Caveat: the following only works for a matrix containing rotation, translation, and nonnegative scalings. This is the overwhelmingly commonest case, and doubtless what OP was expected to assume. A more-general solution is significantly more complicated and was not provided because OP didn't ask for it; anyone interested in supporting e.g. negative scalings and shear should look at Graphics Gems II §VII.1.

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} = \langle ~d,~h,~l~ \rangle $$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 = \|\langle ~a,~e,~i~ \rangle\|\\ s_y = \|\langle ~b,~f,~j~ \rangle\|\\ s_z = \|\langle ~c,~g,~k~ \rangle\|\\ \vec{s} = \langle s_x,s_y,s_z \rangle $$

  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

geometrian
  • 3,036
  • 6
    It is not precisely true. Matrix obtained in third step has still 6 degrees of freedom, and it is composition of shear and rotation. – peper0 Oct 06 '15 at 18:19
  • The OP did not specify shear was an option. The rotation matrix may produce a degenerate quaternion, but this is easy to detect during the conversion, and you should be doing that anyway. – geometrian Oct 06 '15 at 19:00
  • 9
    This works when scale is positive, however when odd number of scale components were negative, this won't get correct result. Would it help to multiply scale vector by sign of matrix diagonals? – Ondrej Petrzilka Mar 24 '16 at 22:15
  • 2
    But how do we find reflections. sx, sy, sz values can be negative too. – nbsrujan Apr 21 '16 at 09:47
  • At step 3, which guarantee can you have that you indeed have a rotation matrix ? – Florian Ingels Mar 26 '20 at 15:44
  • 1
    This doesn't work for negative scales, how do you find the scale of a negatively scaled transform? – Aaron Franke Mar 28 '20 at 10:10
  • I am sure this is not true. It is obvious in here that claimed sx, sy, sz are positive numbers. However they should not be when mirroring is present in the transformation thus rotation matrix will be wrong in that case. – Marek Basovník Oct 10 '22 at 09:20
  • What is the meaning of sx=∥⟨ a, e, i ⟩∥? Is it sx = sqrt(a^2 + e^2 + i ^2) – Aaron Lee Oct 22 '22 at 03:05
  • @AaronLee Correct; $\langle\cdots\rangle$ creates a vector while $||\cdots||$ takes a vector and returns a norm. Here that's just the Euclidean length, by the distance formula you gave. (One intuition at why it's the L2 norm is that the QR factorization of the $3\times3$ will give $Q$ the rotation matrix and $R$ a diagonal matrix containing scale. Then look at how you compute QR.) We do this three times to get three scalar scaling values $s_x$, $s_y$, and $s_z$, which we can then concatenate into a scaling vector $\vec{s}$. – geometrian Oct 22 '22 at 13:27
28

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.

merv
  • 380
20

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.

  • How would I extract the rotation angle (around z axis) from R? – Nullman Dec 03 '20 at 13:26
  • 1
    You can calculate the rotation angle as $$\theta = \arccos\left(\frac{trace(R) - 1}{2}\right)$$ But you may also need to calculate the rotation axis by finding the eigenvector corresponding to the eigenvalue 1. – aerobiomat Dec 04 '20 at 09:24
  • what do i do with the eigenvector? – Nullman Dec 04 '20 at 22:59
  • The eigenvector is the rotation axis. Well, it’s the direction of the axis that goes through the origin in a pure rotation. – aerobiomat Dec 05 '20 at 11:18
  • I know this post is 9 years old, but an additional detail: The scale matrix can be decomposed into shears and a diagonal, I think. You do the LU decomposition of S, and try to be a little more general and go for an "LUD" decomposition (ie. lower/upper/diagonal) (hard to find anything online on an LUD decomp). Your L and U unit triangular matrices are your shears, and your diagonal matrix D is your scaling factors in the direction of the 3 axes. – Osama Kawish Dec 08 '21 at 04:47