Sign in to follow this  

How can I find the rotation part of a transformation matrix?

This topic is 4379 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I have a 4x4 transformation matrix, combined from translation (easy to decouple), scaling, and rotation. Note that there's no shearing. How can I seperate rotation and scaling? I googled (of course) and searched in gamedev, but didn't find any clue. Thank you. btw Happy Holidays! - xinvar

Share this post


Link to post
Share on other sites
given


float m[4][4]; // tranformation matrix. m[3][0] == translateX

// to get scale
float scaleX = sqrt(m[0][0]*m[0][0] + m[0][1]*m[0][1] + m[0]*m[2]*m[0][2]);
float scaleY = sqrt(m[1][0]*m[1][0] + m[1][1]*m[1][1] + m[1]*m[2]*m[1][2]);
float scaleZ = sqrt(m[2][0]*m[2][0] + m[2][1]*m[2][1] + m[2]*m[2]*m[2][2]);

// to convert to 3x3 rotation matrix...
float rotmat[3][3] = {
{ m[0][0]/scaleX , m[0][1]/scaleX , m[0][2]/scaleX },
{ m[1][0]/scaleY , m[1][1]/scaleY , m[1][2]/scaleY },
{ m[2][0]/scaleZ , m[2][1]/scaleZ , m[2][2]/scaleZ }
};



convert rotmat to quaternion or whatever representation you need.

Share this post


Link to post
Share on other sites
If you know a priori that your matrix is a combination of rotation and scaling, then all you have to do is divide the matrix by the determinant (to make it have unit determinant). That gets rid of the scaling effect. Then whatever you have left is your rotation matrix, R.

If you take the eigenvector of R which corresponds to the only real eigenvalue (you'll only have one real eigenvalue in most cases - in the other cases, you'll have a permutation matrix), this will be the axis around which R rotates stuff.

Finally, you can recover the angle of rotation by observing that for all rotation matrices (around any axis), the trace of the matrix is equal to twice the cosine of the angle.

Share this post


Link to post
Share on other sites
Quote:
Original post by yellowjon
If you know a priori that your matrix is a combination of rotation and scaling, then all you have to do is divide the matrix by the determinant (to make it have unit determinant). That gets rid of the scaling effect. Then whatever you have left is your rotation matrix, R.

Perhaps I miss something. But if
R := [ Rx Ry Rz]
are the column vectors of the rotation basis, and
sx, sy ,sz
are the 3 scaling factors, so that
det(S) = sx*sy*sz
and the product (the reverse order of trafos will proove similar)
R*S = [ Rx*sx Ry*sy Rz*sz ]
what should express the scaled column vectors of the rotation basis, and
det(R*S) = det(R) * det(S) = 1 * sx*sy*sz
so that
R*S / det(R*S) = [ Rx*sx/(sx*sy*sz) Ry*sy/(sx*sy*sz) Rz*sz/(sx*sy*sz) ] != R

If, on the other hand, looking at RobTheBlokes solution, there is something like
[ Rx*sx/sx Ry*sy/sy Rz*sz/sz ] == R
computed.

So I don't agree that making the matrix unit determinat is a solution in general. Please correct me if I'm wrong.

Share this post


Link to post
Share on other sites
Thanks haegarr. Actually I tried solutions from both RobTheBloke and yellowjon, neither gives the correct answer. Maybe I missed something too.

[edit]: Sorry, RobTheBloke's solution is correct. The matrix is column major but I used row major.

Share this post


Link to post
Share on other sites
IMHO, the solution to your problem may as simple as RobTheBloke said, or else relatively complicated. A question: do you have a more or less random order of many particular transformations you want to decompose, or is it the result of a fixed standard formula like (in colum vector form)
M := T * R * S
(say, first to scale, then to rotate, then to translate)?

In the former case you may need to use heavier math like Polar decomposition.

Quote:
Original post by xinvar
Actually I tried solutions from both RobTheBloke and yellowjon, neither gives the correct answer.

If you have a simple form like T*R*S I expected RobTheBloke's answer being correct in principle. However, it may be an indexing problem only... You should investigate the indexing and perhaps transpose the scale divisors part.


EDIT: Ok, haven't read your Edit until this post was already ready :) Bye.

Share this post


Link to post
Share on other sites

This topic is 4379 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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