Advertisement Jump to content
Sign in to follow this  

Matrix Decomposition - Polar Decomposition

This topic is 2682 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

I have read this topic: and used GPU Gems IV matrix decomposition.

I am usign matrix DX layout (left-handed, row vectors), so I transform it for GPU Gems layout (right handed, column vectors)

For conversion from LH -> RH, I multiply Z values (eg. 3rd col) in 3x3 submatrix by -1

LH To RH Matrix
Transpose Matrix

AffineParts parts
decomp_affine(Matrix, &parts)

Decomposition works for Translation (of course, its logic), scale seemsed to be correct to. But quaternion is wrong. XYZW parts have correct number values ins abs(X), but order and sign is wrong

For example:

Quaternion qt = :Quaternion(-0.75f, 0.2f, -0.1f, 1.0f);
qt.Normalize(); //(-0.59, 0.15, -0.078, 0.78)

world = Matrix4x4::Scaling(1, 2, 3) * Matrix4x4::RotationQuaternion(qt) * Matrix4x4::Translation(0, 0, -64);


and now quternion has values (-0.15, -0.59, 0.78, 0.078)

What am I doing wrong ?

Share this post

Link to post
Share on other sites
Good morning :)

I implemented this algorithm myself yesterday. The polar decomposition doesn't care about handness. But if you are using row vectors like DirectX you want to decompose M = S * Q though (not M = Q * S). Another thing to watch out for is "negative" scale. If one or three elements of your scale vector are negative the rotation matrix contains a reflection (the determinant is negative). You need to factor further Q = (-I) * Q' and the negative identity matrix goes into S. In a real implementation you would use a matrix with say a11 = -1, a22 = a33 = 1. You only need to negate one row and one column. If two elements are negative this is basically a rotation and the decomposition will give you positive scales and a different rotation matrix. It basically moves the rotation into Q.

The algorithm for the polar decomposition is very easy. Essentially (without acceleration) it is a simple fixpoint iteration:

Mat3 X1 = M;
for ( say 32 iterations )
..Mat3 X2 = 0.5 * ( X1 + X1^-T); // Just add the matrix and its inverse transpose
..X1 = X2;

Q = X1;
S = M * Q^T

Here are two very good papers about the topic which I used as reference myself:

I recommend to implement the algorithm yourself as in the second paper *with* the acceleration. It is working great for me and you usually have a result after 3-5 iterations. Your function for the decomposition should also return the determinant which you need for the inversion anyway. Then a user can decide if he wants to factor Q further.


Share this post

Link to post
Share on other sites
Thanks fo reply.. but implementation of function decomp_affine is taken from GPU Gems IV, so I think that should be correct. Output numbers seems correct to.. I just dont understand, why are they in incorrect order.

Share this post

Link to post
Share on other sites
Do you have a link to the code or can you paste it here? I thought you were referening to K. Shoemakes implementation.
You don't need to transpose the input matrix, use S = M * QT.

If you use the Shoemake code the affine parts also contain the determinant f which give you the handness of the rotation

Share this post

Link to post
Share on other sites
I used this code:

I transpose matrix because DX has row vectors, but Shoemaker expect column vectors.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!