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!