Sign in to follow this  
zhouzhengchun

How to decompose a matrix44 to scale, rotation and translation?

Recommended Posts

Hi, I want to know how to decompose a matrix44 to scale, rotation and translation? Though I know how to compose these to a matrix. But it seems much more difficult to decompose a matrix.

Share this post


Link to post
Share on other sites
Quote:
Original post by zhouzhengchun
I want to know how to decompose a matrix44 to scale, rotation and translation? Though I know how to compose these to a matrix. But it seems much more difficult to decompose a matrix.
If you're using the DirectX library, I think there's a function available for this. Otherwise, if the order of transformation was scale->rotate->translate, it's fairly easy to do manually. The scale factors are the lengths of the basis vectors of the matrix. Once you have the lengths, you can normalize the vectors to get an orthonormal basis (the rotation matrix). The translation is unaffected by the concatenation and can simply be extracted directly from the matrix.

Anyway, I'm pretty sure that's right. You might try it and see if you get the expected results.

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
Otherwise, if the order of transformation was scale->rotate->translate, it's fairly easy to do manually. The scale factors are the lengths of the basis vectors of the matrix. Once you have the lengths, you can normalize the vectors to get an orthonormal basis (the rotation matrix).


If you know you have Y=S*R*X+T, where S is a diagonal matrix of scales, R is a rotation, and T is a translation, then you can figure out S, R, and T as you indicated. The problem is when you have a composition of such transformations. The translation is not a problem to figure out when you have Y=M*X+T. The decomposition of M = S*R, where S is a diagonal matrix and R is an orthogonal matrix, is not always possible. The best you can do is "polar decomposition", where S is a symmetric matrix that represents the scaling, but in a different coordinate system, or "singular value decomposition" M = L*D*R, where L and R are orthogonal and D is a diagonal matrix of nonnegative values (the diagonal terms are positive when M is invertible). The function decomp_affine() mentioned in another follow-up post essentially does this type of decomposition.

Share this post


Link to post
Share on other sites
Quote:
Original post by Wasting Time
Quote:
Original post by jyk
Otherwise, if the order of transformation was scale->rotate->translate, it's fairly easy to do manually. The scale factors are the lengths of the basis vectors of the matrix. Once you have the lengths, you can normalize the vectors to get an orthonormal basis (the rotation matrix).


If you know you have Y=S*R*X+T, where S is a diagonal matrix of scales, R is a rotation, and T is a translation, then you can figure out S, R, and T as you indicated. The problem is when you have a composition of such transformations. The translation is not a problem to figure out when you have Y=M*X+T. The decomposition of M = S*R, where S is a diagonal matrix and R is an orthogonal matrix, is not always possible. The best you can do is "polar decomposition", where S is a symmetric matrix that represents the scaling, but in a different coordinate system, or "singular value decomposition" M = L*D*R, where L and R are orthogonal and D is a diagonal matrix of nonnegative values (the diagonal terms are positive when M is invertible). The function decomp_affine() mentioned in another follow-up post essentially does this type of decomposition.
Yes, my suggestion was just for the simple case of a single scale->rotate->translate sequence - I didn't mean to imply that it was a general solution (I think my post was fairly clear in that regard). In any case, the OP now has some options to choose from :)

Share this post


Link to post
Share on other sites
Why should the order of individual -hardcoded- transformations, matter at all? (in finding the S/R/T components, that is)
And besides, I don't see the need for any sort of matrix decomposition here...

Let this be the world matrix:

[ m11 m12 m13 m14 ]
[ m21 m22 m23 m24 ]
[ m31 m32 m32 m34 ]
[ 0 0 0 1 ]

then the origin (0, 0, 0, 1)T obviously maps to (m14, m24, m34, 1)T
The global X axis gX = (1, 0, 0, 0)T, maps to the scaled global X sgX=(m11, m21, m31, 0)T,

The global Y axis gY = (0, 1, 0, 0)T, maps to the scaled global Y sgY=(m12, m22, m32, 0)T, and similarly for global Z...

It is obvious now, that the scaling values are |sgX|, |sgY|, |sgZ|, the new orientation base is:
{sgX/|sgX|, sgY/|sgY|, sgZ/|sgZ|}, and the translation is {m14, m24, m34}.
The respective S/R/T matrices, can be constructed trivially from the above vectors and values, if they are *that* necessary...

edit:
changed the names of vectors (some were misleading)

Share this post


Link to post
Share on other sites
Quote:
Original post by someusername
Why should the order of individual -hardcoded- transformations, matter at all? (in finding the S/R/T components, that is)
And besides, I don't see the need for any sort of matrix decomposition here...


The order matters because matrix multiplication is not commutative. If you have nonuniform scaling S and rotation R, then generally R*S and S*R are different matrices.

When I said you need to worry about the composition of transformations, I meant the following. The first transformation is Y = S0*R0*X+T0. A second transformation applies to the output of the first, Z = S1*R1*Y+T1 = (S1*R1*S0*R0)X+(S1*R1*T0+T1) = M*X+T. It is easy enough to figure out what T is. However, M = S1*R1*S0*R0 cannot generally be decomposed into M = S*R. This was the point of my previous post. If you use a scene graph management system with a hierarchy of transformations, you run into this decomposition problem quite quickly.

Share this post


Link to post
Share on other sites
Quote:
Original post by someusername
It is obvious now, that the scaling values are |sgX|, |sgY|, |sgZ|, the new orientation base is:
{sgX/|sgX|, sgY/|sgY|, sgZ/|sgZ|}, and the translation is {m14, m24, m34}.
The respective S/R/T matrices, can be constructed trivially from the above vectors and values, if they are *that* necessary...
This is exactly what I described previously. However, it only works for a single (albeit common) case, whereas the decompositions suggested by the other posters are more general.

The OP did specify scale, rotation, and translation. He didn't specify the order, but I think S->R->T is a pretty good bet, which is why the aforementioned shortcut seems like a reasonable suggestion.

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
The OP did specify scale, rotation, and translation. He didn't specify the order, but I think S->R->T is a pretty good bet, which is why the aforementioned shortcut seems like a reasonable suggestion.


jyk's suggestion will work for the given special case. decomp_affine() will work for the general case (including extracting the scale rotation, which can be different from the rotation).

See Ken Shoemake's Matrix Animation and Polar Decomposition paper for more information. A link to this paper would also make a nice addition to the FAQ.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this