Rotate quaternion on all 3 axis from axis angle in GLM

I use quaternions for rotations in OpenGL engine.Currently , in order to create rotation matrix for x ,y and z rotations I create a quaternion per axis rotation.Then I multiply these to get the final quaternion:

  void RotateTo3(const float xr ,const float yr ,const float zr){

    quat qRotX=angleAxis(xr, X_AXIS); 
    quat qRotY=angleAxis(yr, Y_AXIS);
    quat qRotZ=angleAxis(zr, Z_AXIS);

    quat resQuat=normalize(qRotX * qRotY * qRotZ);
    resQuat=normalize(resQuat);
    _rotMatrix= mat4_cast(resQuat);

 }

Now it's all good but I want to create only one quaternion from all 3 axis angles and skip the final multiplication.One of the quat constructors has params for euler angles vector which goes like this:

quat resQuat(vec3(yr,xr,zr))

So if I try this the final rotation is wrong.(Also tried quat(vec3(xr,yr,zr)) ) .Isn't there a way in GLM to fill the final quaternion from all 3 axis in one instance ?

Now , one more thing: As Nicol Bolas suggested , I could use glm::eulerAngleYXZ() to fill a rotation matrix right away as by his opinion it is pointless to do the intermediate quaternion step.. But what I found is that the function doesn't work properly , at least for me .For example :

This :

          mat4 ex=  eulerAngleX(radians(xr));
      mat4 ey=  eulerAngleY(radians(yr));
      mat4 ez=  eulerAngleZ(radians(zr));

       rotMatrix= ex * ey * ez; 

Doesn't return the same as this :

   rotMatrix= eulerAngleYXZ(radians(yr),radians(xr),radians(zr));

And from my comparisons to the correct rotation state ,the first way gives the correct rotations while the second wrong .


Do you mean something like this:

quat formQuaternion(double x, double y, double z, double angle){
     quat out;
     //x, y, and z form a normalized vector which is now the axis of rotation.
     out.w  = cosf( fAngle/2)
     out.x = x * sinf( fAngle/2 )
     out.y = y * sinf( fAngle/2 )
     out.z = z * sinf( fAngle/2 )
     return out;
}

Sorry I don't actually know the quat class you are using, but it should still have some way to set the 4 dimensions. Source: Quaternion tutorial


Contrary to popular belief, quaternions are not magical "solve the Gimbal lock" devices, such that any uses of quaternions make Euler angles somehow not Euler angles.

Your RotateTo3 function takes 3 Euler angles and converts them into a rotation matrix. It doesn't matter how you perform this process; whether you use 3 matrices, 3 quaternions or glm::eulerAngleYXZ . The result will still be a matrix composed from 3 axial rotations. It will have all of the properties and failings of Euler angles. Because it is Euler angles.

Using quaternions as intermediaries here is pointless. It gains you nothing; you may as well just use matrices built from successive glm::rotate calls.

If you want to do orientation without Gimbal lock or the other Euler angle problems, then you need to stop representing your orientation as Euler angles.

In answer to the question you actually asked, you can use glm::eulerAngleYXZ to compute


eulerAngleYXZ gives one possible set of euler angles which, if recombined in the order indicated by the api name, will yield the same orientation as the given quaternion. It's not a wrong result - it's one of several correct results.

Use a quaternion to store your orientation internally - to rotate it, multiply your orientation quat by another quat representing the amount to rotate by, which can be built from angle/axis to achieve what you want.

链接地址: http://www.djcxy.com/p/81794.html

上一篇: Android OpenGL 3x3矩阵到四元数

下一篇: 在GLM中从轴角开始在所有3轴上旋转四元数