我用于在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));
从我与正确的旋转状态的比较,第一种方式给出了正确的旋转,而第二种方式错误。
答案 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名称指示的顺序重新组合,将产生与给定四元数相同的方向。 这不是错误的结果 - 它是几个正确结果之一。
使用四元数在内部存储方向 - 旋转方向,将方向四分之一乘以另一个表示旋转量的四分之一,可以从角度/轴构建,以达到您想要的效果。