为了能够以任何方式旋转物体,我一直试图绕着四元数,避免流行的万向节锁定问题。
我有一些欧拉角传感器读数,我必须将它们转换为四元数。 或者更确切地说,目前我只是通过向它提供某些角度来模拟读数......无论如何,我必须在所有计算中使用欧拉角作为我的起点。
我发现有很多文章/指南都涉及到这一点,并且所有文章/指南都未能帮助我,有效地指出问题出在键盘和椅子之间......
我发现的第一个指南中有一个http://content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation
我尝试过,同时检查其他一些事情,发现它是将Euler转换为四元数的更流行的方法之一,GLM也是这样做的。
以下是我对此方法的实现:
float x, y, z, w,
c1 = cos(qDegreesToRadians(angle[0]) * 0.5f),
c2 = cos(qDegreesToRadians(angle[1]) * 0.5f),
c3 = cos(qDegreesToRadians(angle[2]) * 0.5f),
s1 = sin(qDegreesToRadians(angle[0]) * 0.5f),
s2 = sin(qDegreesToRadians(angle[1]) * 0.5f),
s3 = sin(qDegreesToRadians(angle[2]) * 0.5f);
x = s1 * c2 * c3 + c1 * s2 * s3;
y = c1 * s2 * c3 - s1 * c2 * s3;
z = s1 * s2 * c3 + c1 * c2 * s3;
w = c1 * c2 * c3 - s1 * s2 * s3;
QQuaternion quat(w, x, y, z);
角度' var是一个包含欧拉角的数组,格式如下:
0:Yaw,1:Pitch,2:Roll
然而,结果并不是我所期待的。
黑色部分未旋转,红色部分表示其旋转。旋转角度为0偏航,-90俯仰和0滚动,这意味着俯仰是侧向的。为什么呢?
"好吧,好吧,让我们换掉轴,我们会看到会发生什么事情" - 我想。 乍一看它有效!我刚刚用 y 交换 x 。 虽然对象是颠倒的,所以我只是否定了其中一个四元数:
QQuaternion quat(w, -y, x, z);
到目前为止看起来不错,对吗?
让我们尝试旋转一下...... 呃!哦!看起来当音高为-90或90时,偏航和滚动结束在同一轴上......万向节锁定。
为什么换轴?即使我使用四元数,为什么会出现万向节锁?是因为我在输入上使用欧拉角吗?如果这是问题,那么我不认为有任何解决方法(考虑到我以欧拉角的形式得到我的数据),是吗?