用另一个的偏航部分修正一个四元数的偏航部分

时间:2011-05-30 12:18:53

标签: math angle quaternions euler-angles

我有以下问题:来自运动捕捉装置的四元数(q1)需要通过由第二个被跟踪物体导出的另一个方位四元数(q2)的偏航角(并且仅偏航!)进行校正,以便q1的俯仰和滚动与之前相同,但q1具有q2的偏航。

工作解决方案是将quat转换为矩阵,然后我进行计算以提取旋转角度,然后进行航向修正。但是这直接在某个轴的方向上(例如在0°-359°之后)导致“翻转”。还尝试了其他不方便的转换。

是否有可能直接对四元数进行数学运算而不转换为矩阵或欧拉角(即我可以将修正后的四元数设置为被跟踪对象的四元数)?

如上所述 - 校正应仅包括围绕上轴(偏航)的旋转。我对数学课程的编程可能性不多(不幸的是,Virtools的VSL Script在这个方向上非常有限)。有人有什么建议吗?

4 个答案:

答案 0 :(得分:1)

对于这个任务,欧拉角是最好的选择,因为它们的优点(唯一的优点)在于围绕正交轴分离成单独的旋转。因此,将四元数转换为符合您需要的欧拉角度约定,并将q1的偏航角度替换为q2。

当然你需要使用匹配的欧拉角度约定,其中一个其他旋转不依赖于偏航角度(因此在转换点时首先应用偏航旋转?),这样你就可以改变角度不影响其他轴。将生成的euler angle triple转换回四元数时,你应该再次得到一个独特的表示,或者我错过了什么?

答案 1 :(得分:0)

简短回答:是的,这是可能的。您可以制定旋转(关于任意轴)并使用四元数操作执行它。

答案很长:见Wikipedia article on Quaternions and rotations。我想你描述的问题是万向节锁。

答案 2 :(得分:0)

如果你有四元数 Q1 Q2 而你的'向上'方向是 y ,那么如果你取出 y Q1 的组件并重新规范化,然后得到一个没有偏航组件的四元数。同样,如果您取出 Q2 x z 组件,那么您将获得仅使用 的四元数偏航部件。将第二个乘以第一个(使用四元数乘法),然后就在那里。

Q1[2] = 0;
normalize4d(Q1);
Q2[1] = 0;
Q2[3] = 0;
normalize4d(Q2);
Q3 = quatMult(Q2,Q1);

当然,您可能需要检查旋转精确(或接近)180度的特殊情况,因为当您尝试将幅度非常小的矢量标准化时,这会使数值不稳定。

答案 3 :(得分:0)

您可以通过计算偏航部分,然后应用其反转来移除四元数的偏航部分。我们假设您的四元数为proxy_pass,并且围绕Z轴定义偏航(来自this paper的euler 123或213)。

请注意,在这些帧中,围绕Z轴的quat(w,x,y,z) == w + xi + yj + zk)旋转用四元数yaw表示。

将四元数分解为欧拉角,我们有偏航:

quat(cos(yaw/2), 0, 0, sin(yaw/2))

我们可以从中得出

yaw = atan2(-2*x*y + 2*w*z, +w*w +x*x -y*y -z*z); // 123 angles (page 24)
yaw = atan2(-2*x*y + 2*w*z, +w*w -x*x +y*y -z*z); // 213 angles (page 28)

将四元数角度减半的简单方法是将其添加到标识四元数并进行标准化:

quat quat_2yaw = quat(w*w +x*x -y*y -z*z, 0, 0, -2*x*y + 2*w*z).normalize(); // 123 angles
quat quat_2yaw = quat(w*w -x*x +y*y -z*z, 0, 0, -2*x*y + 2*w*z).normalize(); // 213 angles

要回答您原来的问题 - 我们希望从quat quat_yaw = (1 + quat_2yaw).normalize(); 开始偏航,并用它替换q1偏航。我们可以这样做:

q2