# 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.

## Recommended Posts

I have read this topic: http://www.gamedev.net/topic/375401-matrix-decomposition-non-uniform-scaling/ 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); Decompose() and now quternion has values (-0.15, -0.59, 0.78, 0.078) 

What am I doing wrong ?

##### 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:
http://www.cs.wisc.edu/graphics/Courses/838-s2002/Papers/polar-decomp.pdf
http://eprints.ma.man.ac.uk/694/01/covered/MIMS_ep2007_9.pdf

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.

HTH,
-Dirk

##### 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 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 on other sites
I used this code:
http://users.soe.ucsc.edu/~pang/160/f98/Gems/GemsIV/polar_decomp/Decompose.c
http://users.soe.ucsc.edu/~pang/160/f98/Gems/GemsIV/polar_decomp/Decompose.h

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

##### Share on other sites
We use row vectors as well and I don't transpose. The reason is that the polar decomposition is coordinate independent (see paper).

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 28
• 16
• 10
• 10
• 11
• ### Forum Statistics

• Total Topics
634113
• Total Posts
3015571
×