Are there multiple ways of converting Quaternions to Euler Angles

quaternionsrotations

Today, I discovered something about rotation matrices in in the source code of Blender. There is a function, that returns two different euler angles showing the rotation of a given rotation matrix. They use two different euler calculation methods, to late choose the euler angle that fits best to whatever criteria. Here is the code snippet:

cy = hypotf(mat[i][i], mat[i][j]);
eul1[i] = atan2f(mat[j][k], mat[k][k]);
eul1[j] = atan2f(-mat[i][k], cy);
eul1[k] = atan2f(mat[i][j], mat[i][i]);

eul2[i] = atan2f(-mat[j][k], -mat[k][k]);
eul2[j] = atan2f(-mat[i][k], -cy);
eul2[k] = atan2f(-mat[i][j], -mat[i][i]);

Now I wonder, can we also calculate these two eulers from a Quaternion, instead of a rotation matrix? So far, I know one way of converting quaternions to eulers. Which is …

pitchYawRoll1.y = Atan2 (2f * q.x * q.w + 2f * q.y * q.z, 1 - 2f * (q.z * q.z + q.w * q.w));   // Yaw
pitchYawRoll1.x = Asin (2f * (q.x * q.z - q.w * q.y));                                         // Pitch
pitchYawRoll1.z = Atan2 (2f * q.x * q.y + 2f * q.z * q.w, 1 - 2f * (q.y * q.y + q.z * q.z));   // Roll

I tried to do the conversion the second way (see eul2 from Blender), but the result is not showing the same rotation as the original quaternion q

pitchYawRoll2.y = Atan2 (-(2f * q.x * q.w + 2f * q.y * q.z), -(1 - 2f * (q.z * q.z + q.w * q.w))); // Yaw
pitchYawRoll2.x = -Asin (2f * (q.x * q.z - q.w * q.y));                                           // Pitch
pitchYawRoll2.z = Atan2 (-(2f * q.x * q.y + 2f * q.z * q.w), -(1 - 2f * (q.y * q.y + q.z * q.z))); // Roll

I think pitchYawRoll2.x is calculated incorrectly, because atan2(0.4,-0.3) is not equal to -atan2(0.4.0.3). (I know the result of Asin (2f * (q.x * q.z - q.w * q.y)) and i assume it equals atan2(x,y). But I don't know how to reconstruct atan2(x,-y) from it)

Is there a way to get two the two euler angles from a quaternion as its done in Blender?

Hope the question is not too confusion. I am new to Rotations and the Quaternion representation.

Best Answer

After finding and trying out more, I found the solution. In the blender code you can use any angle axis order if you set i,j,k accordingly. In my case, i need YXZ order, because I'm using Unity (i=1; j=0; k=2). The only thing left to do is converting the Quaternion q to a rotation matrix, and then converting the matrix to the two euler angles as Blender does it. Thank you for your suggestions!