GLM:欧拉角与四元数


12

希望您知道GL数学GLM),因为我遇到了问题,我无法中断:

我有一组欧拉角,我需要在它们之间进行平滑插值。最好的方法是将它们转换为四元数并应用SLERP算法。

我的问题是如何用Euler Angles 初始化 glm :: quaternion?

我一遍又一遍地阅读了GLM文档,但我找不到合适的文档Quaternion constructor signature,那需要三个欧拉角。我找到的最接近的是 angleAxis()函数,该函数获取角度值和该角度的轴。请注意,我正在寻找一种方法,如何解析RotX, RotY, RotZ


供您参考,这是上面提到的angleAxis() 函数签名

detail::tquat< valType > angleAxis (valType const &angle, valType const &x, valType const &y, valType const &z)

Answers:


13

我对GLM不熟悉,但是在没有直接将Euler角度转换为四元数的函数的情况下,您可以自己使用“绕轴旋转”功能(例如“ angleAxis”)。

这是(伪代码):

Quaternion QuatAroundX = Quaternion( Vector3(1.0,0.0,0.0), EulerAngle.x );
Quaternion QuatAroundY = Quaternion( Vector3(0.0,1.0,0.0), EulerAngle.y );
Quaternion QuatAroundZ = Quaternion( Vector3(0.0,0.0,1.0), EulerAngle.z );
Quaternion finalOrientation = QuatAroundX * QuatAroundY * QuatAroundZ;

(或者,您可能需要根据欧拉角旋转的应用顺序切换那些四元数倍数)

或者,通过浏览GLM文档,您似乎可以像这样转换欧拉角->矩阵3->四元数:

toQuat( orient3( EulerAngles ) )

好的答案,因为它对应用程序的顺序不太明确。
理查德·法比安

@Trevor:+1,您好Trevor,谢谢您的答复。这看起来是这里最实用的解决方案。我可以轻松地在旋转乘法顺序之间进行切换。可能的原因是组合的数量,为什么在GLM中无法进行Euler Angle至Querterion转换。
Bunkai.Satori 2011年

尽管所有答案都是不错且有价值的,但我认为是最实用的答案。我想将其标记为“ 接受的答案”
Bunkai.Satori 2011年

@Trevor:在四元数中,finalOrientation = QuatAroundX * QuatAroundY * QuatAroundZ ;,意味着什么乘法?令我惊讶的是,GLM没有operator *为四元数乘法过载,因此可能我将不得不手动执行乘法
Bunkai.Satori 2011年

3
@Bunkai四元数乘法的概念类似于矩阵乘法,既不是点也不是叉积。如果您想了解四元数的用法,然后习惯矩阵并了解轴角,它们的基本概念与四元数非常相似,则数学会更高级,但是一旦您了解了轴角,则四元数就不再更远了。
Maik Semder 2011年

16
glm::quat myquaternion = glm::quat(glm::vec3(angle.x, angle.y, angle.z));

其中angleglm::vec3俯仰,偏转辊分别。

PS。如有疑问,请转到标题并查看。定义可以在glm / gtc / quaternion.hpp中找到:

explicit tquat(tvec3<T> const & eulerAngles) {
        tvec3<T> c = glm::cos(eulerAngle * value_type(0.5));
    tvec3<T> s = glm::sin(eulerAngle * value_type(0.5));

    this->w = c.x * c.y * c.z + s.x * s.y * s.z;
    this->x = s.x * c.y * c.z - c.x * s.y * s.z;
    this->y = c.x * s.y * c.z + s.x * c.y * s.z;
    this->z = c.x * c.y * s.z - s.x * s.y * c.z;    
}

哪里quat有float类型定义tquat


那是非常模棱两可的,这些将适用于什么顺序?Euler是有序的旋转,这里的四元数构造函数似乎并不在乎。
理查德·法比安

函数定义与您的完全相同;如果有问题,我会在答案中发布。
deceleratedcaviar

不是参数的顺序,而是旋转的顺序。我的答案包含从Wikipedia文章中获取的XYZ排序,但是,我们在旧公司中使用应用程序的ZYX排序,而在当前公司中使用YZX。在所有情况下,x角仍然是向量/自变量列表中的第一个值,但实际结果转换并不相同。
理查德·法比安

我固定了rotationQuat的答案,因此您可以看到如何轻松更改顺序。默认情况下,它接受XYZ,但是您可以轻松更改它。
deceleratedcaviar

2
-1未提及轮换顺序,这对于问题非常重要
Maik Semder 2011年

7

解决方案在Wikipedia中:http : //en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles

使用:

sx = sin(x/2); sy = sin(y/2); sz = sin(z/2);
cx = cos(x/2); cy = cos(y/2); cz = cos(z/2);

q( cx*cy*cz + sx*sy*sz,
   sx*cy*cz - cx*sy*sz,
   cx*sy*cz + sx*cy*sz,
   cx*cy*sz - sx*sy*cz ) // for XYZ application order

q( cx*cy*cz - sx*sy*sz,
   sx*cy*cz + cx*sy*sz,
   cx*sy*cz - sx*cy*sz,
   cx*cy*sz + sx*sy*cz ) // for ZYX application order

四元数的构造函数,给定Euler(其中旋转应用为XYZ或ZYX)。但是,这只是欧拉角的六个可能组合中的两个。您真的需要找出转换为变换矩阵时欧拉角的构造顺序。只有这样,才能定义解决方案。

在我工作的老公司中,我们将Z作为前进对象(与大多数图形卡一样),因此应用程序顺序为ZYX,而在我目前的公司中,Y轴为前进方向并且Z向上,因此我们的应用程序顺序为YZX。此顺序是将四元数相乘在一起以生成最终变换的顺序,而旋转的顺序很重要,因为乘法不是可交换的。


1
+1,您好,感谢您的出色回答。当我使用OpenGL时,Z值超出了屏幕。在我的应用程序中,我执行ZYX乘法顺序。最初,我认为GLM可以使用此功能,但是我看到,他们尚未实现此功能,因此一种替代方法是按照您的建议手动创建转换。
Bunkai.Satori 2011年

这是最好的答案。
–plasmcel

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.