Is there a way to convert a quaternion to angles?

4.2k Views Asked by At

I have a (world) matrix, and it applies translation, rotation and scale into an 3D object. It is created with the function XMMatrixTransformation (DirectXMath) and the parameter RotationQuaternion is made by a call to XMQuaternionRotationRollPitchYaw. Then it is stored in a file along with other data.

Then I need to recover the values, so I can use this function to decompose it to each component:

XMMatrixDecompose(&Scale, &RotationQ, &Translation, Matrix);

Scale and translation are vectors and rotation is a quaternion. If the matrix rotates the object in a single axis I could use this to convert the quaternion back to the angles:

XMQuaternionToAxisAngle(&Axis, &Angle, RotationQ);

It works fine. But when it rotates in two or more axes how can I do the same? Is there a way to do that?

PS: I don't care if the output angles aren't the same as the input. They just need to be equivalent.

PS2: Okay, so I followed Gene's link (I had already looked there but didn't found what I needed that time). I made this code based in this equation I found in Wikipedia: equation

float Roll = atan2(2.0*(F.x*F.y + F.z*F.w), 1 - 2 * (F.y*F.y + F.z*F.z));
float Pitch = asin(2.0*(F.x*F.z - F.w*F.y));
float Yaw = atan2(2.0*(F.x*F.w + F.y*F.z), 1 - 2 * (F.y*F.y + F.z*F.z));

In the output I have different angles. The output seems to be equivalent for (90°, 0°, 90°), but not for (45°, 45°, 45°).

1

There are 1 best solutions below

5
On BEST ANSWER

You have two options.

You can still use the XMQuaternionToAxisAngle() function, and it'll use an axis other than the cardinal axes. Any rotation can be represented as a single angle rotating around a given axis.

On the other hand, if you really need to get it as Euler angles, there's no good function to do this for you. The formulas are readily available though. From Wikipedia:

Quaternion to Euler formula

Per Wikipedia's definition, phi is the angle around the global Z axis, theta is the angle around the "normal axis" N (an axis that goes through the local origin and is orthogonal to the plane of the global Z axis and the final local Z axis -- yeah, it's kinda weird), and psi is the angle around the local (i.e. rotated) Z axis.

If I were a better mathematician, I could help you translate that into just a global-space X, Y, Z rotation, but unfortunately that's beyond the scope of my ability.

Just know that there's not a strict 1-1 correlation between quaternions and Euler angles; gimbal lock means that there are certain angles that share the same Euler angle, for example. Really consider whether you truly need Euler angles -- most of the time an axis-angle rotation would work in the same way, without the significant problems of Euler angles.