如何插值旋转?

Posted

技术标签:

【中文标题】如何插值旋转?【英文标题】:How to interpolate rotations? 【发布时间】:2011-02-22 04:39:17 【问题描述】:

我有两个描述旋转的向量;一个起始旋转 A 和一个目标旋转 B。我最好如何将 A 插值 F 以接近 B?

当需要对多个维度进行插值(即产生不希望的旋转)时,对向量使用简单的 lerp 无法正常工作。也许从旋转向量构建四元数并使用 slerp 是要走的路。但是,那么,我怎样才能从得到的四元数中提取一个描述新旋转的向量呢?

提前致谢。

【问题讨论】:

你能解释一下为什么 SLERP 不适合你吗?插入多个维度是什么意思,我相信它只是从一个点(向量 A)开始并在另一个点(向量 B)结束,围绕原点进行最短的旋转。 一维以上是指多个轴,例如同时围绕 X 和 Y 旋转,而不是仅围绕单个轴旋转。这就是 LERP 失败的时候。 从根本上说,这没有多大意义,因为无论多轴的每次旋转都等价于 到某个其他轴的旋转。所以真的没有理由为什么线性插值在所有情况下都不起作用。 【参考方案1】:

由于我似乎不明白你的问题,这里有一个小SLERP 在 python 中使用 numpy 实现。我使用 matplotlib (v.99 for Axes3D) 绘制了结果。 我不知道你是否可以使用 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()

【讨论】:

你有什么理由不把所有的东西都除以so?数值稳定性...?【参考方案2】:

一个简单的 LERP(和重整化)仅在向量非常接近时才能正常工作,但当向量距离较远时会导致不需要的结果。

有两种选择:

简单的叉积:

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

四元数:

计算将 A 移动到 B 的四元数 q,并使用 SLERP 用身份四元数 Iq 进行插值。然后可以将生成的四元数 qNew 应用于 A.

【讨论】:

【参考方案3】:

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

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

【讨论】:

谢谢。我设法从四元数中取回向量。如果我只在一个轴上插值,则使用 SLERP 的设置可以正常工作。然而,对我来说非常奇怪的是,当使用多个轴时,SLERP 产生的行为与简单向量 LERP 大致相同,也就是说,旋转有时会疯狂地跳跃。有什么想法吗? 听起来你正在获取云台锁;仅当您在正确的坐标中表示旋转时,才能将旋转表示为矢量:en.wikipedia.org/wiki/Gimbal_lock Uhuu,你能澄清一下“围绕多个轴旋转”是什么意思吗?当您在四元数 a 和 b 之间执行 slerp 时,您围绕一个轴旋转;四元数 c 的轴,其中 c = b * a^-1【参考方案4】:

如果您决定使用四元数(它会非常好用),请在此处查看我对实施四元数资源的回答: Rotating in OpenGL relative to the viewport

您应该在那篇文章的链接中找到大量示例。

【讨论】:

以上是关于如何插值旋转?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 3D 中对 QML 旋转变换进行动画处理和属性插值

Flutter 动画插值

如何在转换后获得插值点

机器视觉学习笔记最近邻插值实现图片任意角度旋转(C++)

SLAM练习题(十三)—— 四元数插值

unity 有插值怎么解决摄像机的抖动