View Full Version : Is it possible to extract rotation,translation,scale given a matrix?

04-16-2004, 06:27 AM
Hi all,

I'm thinking about calculating the transformations I applied to my modelview matrix at a certain point of the elaboration... is there a clean way to find rotation, translation and scale given a matrix retrieved with glGet(GL_MODELVIEW_MATRIX)?

The real question is: is it possible? I mean, I can think that the solution won't be unique, but I need only a good one!



04-16-2004, 08:03 AM
Yes, do a search for matrix decomposition.

The way I do it that I assume the transforms are in a certain order which leads to that matrix :


something like that.
It works fine but for other more complex transforms, it's simply not possible to solve.

04-16-2004, 08:53 AM
I found the code of Graphic Gems... but I wonder if it works always, or just in some cases... what do you think?


04-17-2004, 05:48 PM
V-man is right. You have to make certain assumptions about the order of transformations; but even then, rotations are inherently ambiguous, as there is always more that one sequence of rotations to achieve a desired basis. This is where your knowledge of the order of transforms comes in handy.

Here's some code that assumes the order is
yaw(z), pitch(y), roll(x):

void columnMatrixToAngles( Angles& angles, float colMatrix[4][4] )
double sinPitch, cosPitch, sinRoll, cosRoll, sinYaw, cosYaw;

sinPitch = -colMatrix[2][0];
cosPitch = sqrt(1 - sinPitch*sinPitch);

if ( abs(cosPitch) > EPSILON )
sinRoll = colMatrix[2][1] / cosPitch;
cosRoll = colMatrix[2][2] / cosPitch;
sinYaw = colMatrix[1][0] / cosPitch;
cosYaw = colMatrix[0][0] / cosPitch;
sinRoll = -colMatrix[1][2];
cosRoll = colMatrix[1][1];
sinYaw = 0;
cosYaw = 1;

angles.yaw = atan2(sinYaw, cosYaw) * 180 / PI;
angles.pitch = atan2(sinPitch, cosPitch) * 180 / PI;
angles.roll = atan2(sinRoll, cosRoll) * 180 / PI;

04-18-2004, 08:45 AM
I'm not understanding...

This is what I need to do:

I'm displaying a hierarchy of objects, and to do this I push matrixes in the stack while I'm going down in the hierarchy, and pop then when I go up.

Then (let's say I'm in a leaf of my hierarchy), I want to take the accumulated matrix and store it, then retrieve the translation or the rotation or the scale in that matrix.

I need to do this because I have to perform some calculation with this info (like I have 3 matrixes, and I want to find the baricenter of their translation).

Another way to achieve my goal is to accumulate the transformation while I go through the hierarchy, but it looks even more difficult, and I don't really know how to do it.

So, I was thinking if there is a way to retrieve the info I need from the final matrix.

I tried with the algorithm of Graphic Gems
Graphic Gems (http://http://www1.acm.org/pubs/tog/GraphicsGems/gemsii/unmatrix.c)
but the matrix come out to be singular... that shouldn't be!

So... no idea... :(
Thank you,

04-18-2004, 09:35 AM
say M is your matrix, then M has the form:

[sXr11 r12 r13 t1]
|r21 sYr22 r23 t2|
|r31 r32 sZr33 t3|
[ 0 0 0 1]extracting the translate is easy, you multiply M by a matrix A and add the Identity Matrix, A is of the form

[ 0 0 0 1]
| 0 0 0 1|
| 0 0 0 1|
[ 0 0 0 0]extracting the scale and rotate is a little more difficult. Instead of trying to treat the rotate as 3 individual rotates in the component axises, treat it as a single rotation about an arbitrary axis. That's all I have for now, check out mathworld (http://mathworld.wolfram.com)

04-19-2004, 12:17 AM
That sounds good! :)

I check the math website, but I found nothing useful to retrieve the rotation and scale transformation... I will go on checking.

However this is exactly what I need!

If you have any hints about rotation and scale, just let me know.

Thank you,

04-19-2004, 05:02 AM
like I said, extracting the rotate and the scale from the matrix is a problem of a whole different level. To begin, your scale matrix is of the form

[sx 0 0 0]
| 0 sy 0 0|
| 0 0 sz 0|
[ 0 0 0 1]which is simple enough, however, your rotation has the form:

[ ax*ax*(1-c)+c ax*ay*(1-c)+az*s ax*az*(1-c)-ay*s 0]
|ax*ay*(1-c)-az*s ay*ay*(1-c)+c ay*az*(1-c)+ax*s 0|
|ax*az*(1-c)+ay*s ay*az*(1-c)-ax*s az*az*(1-c)+c 0|
[ 0 0 0 1]where (ax, ay, az) defines a unitized axis of rotation, and c and s are the cosine and sine of the angle of rotation.
Now, depending on the order in which you originally multiplied your matrix, this could result in two different matrices:

|SxRyx SyRyy SzRyz 0|
|SxRzx SyRzy SzRzz 0|
[ 0 0 0 1]


[SxRxx SxRxy SxRxz 0]
|SyRyx SyRyy SyRyz 0|
|SzRzx SzRzy SzRzz 0|
[ 0 0 0 1]I hope you can see and appreciate the subtle difference between the two.

The problem is, there are so many unknown values in the equations (i.e. ALL of them). With the translate, it was sitting out their all by itself, only one unknown value. But here, there are so many more, it's probably impossible.

04-19-2004, 06:15 AM
Searching in the net I found a couple of interesting things:

This is an algorithm to do exactly what I need, as you suggested it extract first the translation info and then decompose the scale and rotation:

Matrix decomposition (http://www.geocrawler.com/archives/3/297/1998/10/50/1668476/)

The algorithm uses a well known algebrical decomposition called Singular Value Decomposition.
I found many link about that, the most interesting are the following:
MathWorld (http://mathworld.wolfram.com/SingularValueDecomposition.html)
Math (http://www.uwlax.edu/faculty/will/svd/svd/index.html)
SVDCode (http://www.cs.caltech.edu/~arvo/software.html)
The last link is great, there is a lot of math code, I'm trying to check if it works.

So, I think I need to implement (or to use) the SVD algorithm.
It would be great! :)

Maybe this is the solution...