4
\$\begingroup\$

In trying to solve this problem, I tracked down the problem to the conversion of the rotation matrix to quaternion. In particular, consider the following matrix:

-0.02099178 0.9997436  -0.008475631 0
 0.995325   0.02009799 -0.09446743  0
 0.09427284 0.01041905  0.9954919   0
 0          0           0           1

SlimDX.Quaternion.RotationMatrix (which calls D3DXQuaternionRotationMatrix gives a different answer than SlimDX.Matrix.Decompose (which uses D3DXMatrixDecompose). The answers they give (after being normalized) are:

                            X            Y             Z            W
Quaternion.RotationMatrix   -0.05244324  0.05137424    0.002209336   0.9972991
Matrix.Decompose             0.6989997   0.7135442    -0.03674842   -0.03006023

Which are totally different (note the signs of X, Z, and W are different). Note that these aren't q/-q (two quaternions that represent the same rotation); they face completely different directions.

I've noticed that with matrices for rotations very close to that one (successive frames in the animation) that the Matrix.Decompose version gives a solution that flips around wildly and occasionally goes into the desired position, while the Quaternion.RotationMatrix version gives solutions that are stable but go in the wrong direction. This is only for the right arm in my animation -- for the left arm, both functions give the correct solution, which is the same quaternion within error tolerances.

This makes me think that there's some sort of numeric instability or weird stuff with signs going on. I tried implementing this and then this, but both gave me a completely incorrect solution (even for the matricies where the SlimDX ones were working correctly) -- maybe the rows and columns are flipped?

\$\endgroup\$

1 Answer 1

6
\$\begingroup\$

The problem is neither of the conversion functions, the problem is the input matrix. It is not an affine transformation matrix, because the rotational part is not a pure rotation matrix, it has one or more flipping/negated axis in it.

Only Rotation matrices can be converted to quaternions. More specifically rotation matrices are orthogonal matrices with determinant 1, other input matrices will give wrong results.

A) The input:

-0.02099178 0.9997436  -0.008475631
 0.995325   0.02009799 -0.09446743 
 0.09427284 0.01041905  0.9954919 

Determinant: -1

B) Which is basically:

0   1   0
1   0   0
0   0   1

Determinant: -1

C) One can never reach this matrix by just rotating the identity matrix:

1   0   0
0   1   0
0   0   1

Determinant: 1

You can see that only the x- and y-axis are swapped in B) compared to C), the z-axis remains the same compared to the identity matrix. This is not possible with a pure rotation, there is also flipping/mirroring involved which makes it no longer a rotation matrix (determinant != 1).

A pure rotation that swaps the x- and y-axis would have to have a negative z-axis like this:

0   1   0
1   0   0
0   0  -1

Determinant: 1

So how did you create this matrix? It is not a valid rotation matrix that you can use as input for a conversion to a quaternion!

\$\endgroup\$
2
  • \$\begingroup\$ +1, maybe the OP mixes right and left handed systems? \$\endgroup\$
    – teodron
    Commented Sep 9, 2012 at 19:02
  • \$\begingroup\$ I figured it out, and indeed the problem is numerical instability. The matrix was created by doing A * inv(B), but somewhere in there, the signs were being screwed up. I was able to solve the problem by orthonormalizing matrices A and B before creating the result matrix. \$\endgroup\$ Commented Sep 10, 2012 at 1:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .