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

我使用四元数在OpenGL引擎中进行旋转。目前,为了创建x,y和z旋转的旋转矩阵,我创建了每个轴旋转的四元数。然后,我将它们相乘以得到最终的四元数:

  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构造函数具有参数euler角矢量,如下所示:

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

所以如果我尝试这样做,最后的旋转是错误的(也试过quat(vec3(xr,yr,zr)))。GLM中没有办法在一个实例中填充所有3轴的最终四元数?

现在,还有一件事:正如Nicol Bolas所说,我可以使用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));

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


你的意思是这样的:

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教程


与流行的观点相反,四元数并不是神奇的“解决万向锁”的设备,因此任何四元数的使用都会使欧拉角变得不是欧拉角。

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

在这里使用四元数作为中介是毫无意义的。 它没有获得任何东西; 你也可以使用由连续的glm::rotate调用构建的矩阵。

如果你想做没有万向节锁或其他欧拉角问题的方向,那么你需要停止表示你的方向为欧拉角。

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


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

使用四元数在内部存储您的方向 - 旋转它,将您的方向quat乘以另一个代表旋转量的四元数,这可以从角度/轴构建,以实现您想要的效果。

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

上一篇: Rotate quaternion on all 3 axis from axis angle in GLM

下一篇: Why are quaternions used for rotations?