Math 如何插值旋转?

Math 如何插值旋转?,math,3d,matrix,rotation,quaternions,Math,3d,Matrix,Rotation,Quaternions,我有两个描述旋转的向量;一个开始旋转a和一个目标旋转B。我最好如何用因子F插值a以接近B 当需要插值多个维度(即产生不需要的旋转)时,在向量上使用简单的lerp无法工作。也许从旋转向量构建四元数并使用slerp是一种可行的方法。但是,那么,我如何从得到的四元数中提取描述新旋转的向量呢 提前感谢。好吧,您的slerp方法可以工作,并且可能是计算效率最高的(尽管它有点难以理解)。要从四元数返回到向量,需要使用一组可以找到的公式 还有一些相关的代码,虽然我不知道它是否与您表示数据的方式相对应。如果您决

我有两个描述旋转的向量;一个开始旋转a和一个目标旋转B。我最好如何用因子F插值a以接近B

当需要插值多个维度(即产生不需要的旋转)时,在向量上使用简单的lerp无法工作。也许从旋转向量构建四元数并使用slerp是一种可行的方法。但是,那么,我如何从得到的四元数中提取描述新旋转的向量呢


提前感谢。

好吧,您的slerp方法可以工作,并且可能是计算效率最高的(尽管它有点难以理解)。要从四元数返回到向量,需要使用一组可以找到的公式


还有一些相关的代码,虽然我不知道它是否与您表示数据的方式相对应。

如果您决定使用四元数(这将非常好地简化),请参阅我在这里关于实现四元数的参考资料的回答:


你应该在那篇文章的链接中找到很多例子。

因为我似乎不理解你的问题,这里有一个使用numpy的python小实现。我使用matplotlib(Axes3D的v.99)绘制了结果。 我不知道您是否可以使用python,但看起来像您的SLERP实现吗?在我看来,这似乎给了很好的结果

from numpy import *
from numpy.linalg import norm

def slerp(p0, p1, t):
        omega = arccos(dot(p0/norm(p0), p1/norm(p1)))
        so = sin(omega)
        return sin((1.0-t)*omega) / so * p0 + sin(t*omega)/so * p1


# test code
if __name__ == '__main__':
    pA = array([-2.0, 0.0, 2.0])
    pB = array([0.0, 2.0, -2.0])

    ps = array([slerp(pA, pB, t) for t in arange(0.0, 1.0, 0.01)])

    from pylab import *
    from mpl_toolkits.mplot3d import Axes3D
    f = figure()
    ax = Axes3D(f)
    ax.plot3D(ps[:,0], ps[:,1], ps[:,2], '.')
    show()
一个简单的LERP(和重新规范化)只有在向量非常接近时才能正常工作,但当向量相距较远时会导致不必要的结果

有两种选择:

简单交叉积:

使用叉积确定与A和B正交的轴n(向量对齐时要小心),并使用点积计算A和B之间的角度A。现在,您可以通过将a从0转到a(这将是新的,并在a上应用关于轴n的新旋转)来简单地接近B

四元数:


计算将A移动到B的四元数q,并使用SLERP使用恒等式四元数I对q进行插值。得到的四元数qNew可以应用于A。

你能更好地解释一下为什么SLERP对你不起作用吗?你说插值多个维度是什么意思,我相信它只从一个点(向量A)开始并以另一个(向量B)结束围绕原点进行最短的旋转。我所说的多个维度是指多个轴,例如,同时围绕X和Y旋转,而不是仅仅围绕单个轴旋转。这就是LERP失败的时候。从根本上说,这没有多大意义,因为围绕多个轴的每一次旋转都相当于一次旋转关于另一个轴。因此,没有理由说线性插值在所有情况下都不起作用。谢谢。我设法从四元数中得到了向量。如果我只在一个轴上插值,使用SLERP的设置效果很好。然而,对我来说,很奇怪,当u唱多个轴,也就是说,旋转有时会疯狂地跳来跳去。有什么想法吗?听起来你好像得到了万向节锁;只有在正确的坐标系下才能将旋转表示为向量:Uhuu,你能澄清一下“绕多个轴旋转”是什么意思吗?当你在四元数a和b之间执行slerp时,你绕一个轴旋转;四元数c的轴,其中c=b*a^-1有没有理由不把所有的东西都除以
,所以
?数值稳定性。。。?