如何从两个先前的数据包中推导出一个新的四元数旋转?

5

我已经陷入困境了!我正在处理我的第一人称射击游戏的延迟问题,现在只需要添加一些外推功能。 我可以外推位置;从最后两个位置和它们的速度中获取,然后将速度加到现有位置(×delta时间)。 然而,我无法为旋转执行相同的操作。 默认情况下,角度是欧拉角,但我可以(并且会)将它们转换为四元数,因为它们可能会发生万向锁定。 如何从2个先前的方向外推新的方向? 我有数据包之间的时间,2个数据包和当前方向。

2个回答

5
我在这里找到了一个不错的答案: http://answers.unity3d.com/questions/168779/extrapolating-quaternion-rotation.html 我根据自己的需求改编了代码,它运行得非常好!
对于两个四元数qa、qb,这将给出使用相同公式的插值和外推。t是插值/外推的数量,t为0.1表示从qa->qb的0.1处,t=-1表示从qa->qb向后外推一整步,等等。 我使用了自己编写的函数来允许在opencv cv::Mat中使用四元数/axisAngle,但我可能会选择Eigen来代替。
Quat qc = QuaternionMultiply(qb, QuaternionInverse(qa)); // rot is the rotation from qa to qb     
AxisAngle axisAngleC = QuaternionToAxisAngle(qc); // find axis-angle representation

double ang = axisAngleC.angle; //axis will remain the same, changes apply to the angle

if (ang > M_PI) ang -= 2.0*M_PI; // assume rotation to take the shortest path
ang = fmod(ang * t,2.0*M_PI);   // multiply angle by the interpolation/extrapolation factor and remove multiples of 2PI

axisAngleC.angle = ang;

return QuaternionMultiply(AxisAngleToQuaternion(axisAngleC),qa); // combine with first rotation

抱歉打扰这么老的帖子。我正在为同样的问题苦苦挣扎(从Eigen :: Quaterniond获取角速度,并将其与currentQuat + VelocityQuat * time相加)。您是否曾经在c++ / Eigen中使用过它?上面的“fmod”是什么?谢谢! - anti
嗨,是的,我在C++下使用过这个,但没有用Eigen(那时候用了自己的类)。@fmod:http://www.cplusplus.com/reference/cmath/fmod - Oliver Zendel

1

如果你将两个方向表示为向量,它们的向量叉积将给出旋转轴,而向量点积可用于找到旋转角度。

然后,您可以以与计算标量速度相同的方式计算角速度,并使用它来计算围绕先前确定的轴的外推旋转。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接