在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