在GLM中从轴角度在所有3轴上旋转四元数

时间:2013-04-24 08:23:28

标签: math opengl quaternions

我用于在OpenGL engine.Currently旋转四元数,以创建对于x,y和z旋转创建每轴的四元数rotation.Then我这些相乘得到最终的四元数旋转矩阵:

  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);

 }

现在一切都很好但是我想从所有3个轴角度只创建一个四元数并跳过最后的乘法。其中一个quat构造函数具有对于欧拉角矢量的参数,如下所示:

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

所以,如果我尝试这个最后的旋转是错误的。(也试过季(VEC 3(XR,YR,ZR))).Isn't那里GLM的方式来填补所有3轴的最后四元数的一个实例?

现在,还有一件事: 由于尼科尔流星锤的建议,我可以使用GLM :: eulerAngleYXZ()来填充旋转矩阵就由他看来,这是毫无意义的做中间四元数步..但我发现的是,该功能不能正常工作,至少对我而言。例如:

这:

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

       rotMatrix= ex * ey * ez; 

不会返回相同的内容:

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

从我与正确的旋转状态的比较,第一种方式给出了正确的旋转,而第二种方式错误。

3 个答案:

答案 0 :(得分:3)

与流行的看法相反,四元数并不是神奇的“解决万向节锁”装置,因此四元数的任何使用都会使欧拉角在某种程度上不是欧拉角。

您的RotateTo3函数需要3个欧拉角并将它们转换为旋转矩阵。 如何执行此过程并不重要;是否使用3个矩阵,3个四元数或glm::eulerAngleYXZ。结果仍然是由3个轴向旋转组成的矩阵。它将具有欧拉角的所有属性和失败。因为欧拉角。

使用四元数作为中介是没有意义的。它什么也得不到你;您也可以使用从连续glm::rotate次调用构建的矩阵。

如果你想在没有万向节锁定或其他欧拉角问题的情况下进行定位,那么你需要stop representing your orientation as Euler angles

在回答您实际提出的问题时,您可以使用glm::eulerAngleYXZ来计算

答案 1 :(得分:2)

你的意思是这样的:

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;
}

抱歉,我实际上并不知道你正在使用的quat类,但它仍然应该有一些方法来设置4个维度。资料来源:Quaternion tutorial

答案 2 :(得分:1)

eulerAngleYXZ给出一组可能的欧拉角,如果按照api名称指示的顺序重新组合,将产生与给定四元数相同的方向。 这不是错误的结果 - 它是几个正确结果之一。

使用四元数在内部存储方向 - 旋转方向,将方向四分之一乘以另一个表示旋转量的四分之一,可以从角度/轴构建,以达到您想要的效果。