Search code examples
c++rotationquaternionsglm-math

How to convert a quaternion to a polar/azimuthal angle rotation


I have an arcball camera with a rotation defined by two angles (phi/theta, polar/azimuthal) that is controlled with mouse movement.

I convert these two angles (as euler angles) to a quaternion like this:

glm::quat rotation = glm::quat(glm::vec3(phi, theta, 0));

At some point I need to convert a quaternion back to two angles, but I think there is an infinite number of solutions. Is there a way to get back the two angles without any roll?

Or is there a better solution to make an arcball/orbit camera without using euler angles and keeping only the quaternion rotation of the camera?


Solution

  • I found a solution:

    • Start with a unit vector pointing in the Z axis (depends on your engine's handedness and up-vector) glm::vec3 v = glm::vec3(0, 0, 1);
    • Rotate the vector with the quaternion you want to convert v = q*v; glm does this automatically, otherwise rotate a vector like this :
    quat v_quat = quat(v.x, v.y, v.z, 0); // pure quaternion
    v_quat = (q*v_quat)*q.conjugate();
    v = vec3(v_quat.x, v_quat.y, v_quat.z);
    
    float phi = atan2(v.x, v.z);
    float theta = acos(v.y/length(v)));