构造曲线桥接图的算法给定具有位置和速度的点,其中时间轴是恒定的

时间:2014-01-05 07:11:36

标签: c# algorithm interpolation

我正在记录物体随时间的位置和速度。我需要形成一个图形,其中X轴是连续的(时间),Y轴是对象的三个维度之一(X,Y或Z)。我将为3个轴中的每一个构建一个图形。录制一个点时,我有它的时间和位置/速度。这不是最合适的线;它需要经过每个点,并且尽可能准确地预测物体在采样之间的位置。我试图以非线性方式在记录点之间进行插值。

我不确定这种数据类型存储曲线的样子。后来我需要反转这个图表,以便我可以播放录音。我知道图是方程,我确实需要一个函数,我可以输入一个值(时间)并返回一个结果(位置)。

重申我的两部分问题:

  1. 此图表应存储为什么数据类型?
  2. 我可以使用什么算法提供时间,位置和速度?
  3. 我正在使用C#。

1 个答案:

答案 0 :(得分:3)

由于您在每个时间点都知道对象的位置和速度,因此自然选择使用cubic spline插值。

具体来说,让对象在 t 0 时的位置和速度向量为 x 0 并且 v 0 ,并让时间 t 1 的对应位置和速度> t 0 x 1 v 1 。然后有一个独特的三次多项式:

p t )= at 3 + bt 2 + ct + d

带衍生物:

2 + 2 + c

这样 p t 0 )= x 0 ,< em> p '( t 0 )= v 0 p t 1 )= x 1 p '( t 1 )= v 1 。 我们可以使用这个多项式来随时插入对象的位置和速度 t 0 t t 1 选择 x t )= p t )和< em> v ( t )= p '( t )。


可以求解 p的系数 a b c d 直接来自上述边界条件,但实际上,最简单的方法是通过 t shifting( t - t t em> 0 )/( t 1 - t 0 ),这样 t 0 映射到0而 t 1 映射到1.(请注意,这也需要我们重新缩放速度 v 0 * = v 0 /( t 1 - t 0 )和 v 1 * = v < sub> 1 /( t 1 - t 0 )。)这给了我们四个等式:

p (0)= d = x 0 p '(0)= c = v 0 *, p (1)= a + b + c + d = X <子> 1 p '(1)= 3 a + 2 b + c = v <子> 1 *

前两个方程式直接给出系数 c d ,因此我们只需求解 a b < / em>的。一点点线性代数给出了解决方案:

a = v 0 * + v 1 * + 2( x 0 - x 1 ), b = -2 v 0 * - v 1 * - 3(< em> x 0 - x 1 ), c = v 0 *, d = x 0

然后我们可以将这些值重新插入上面 p 的定义中并在 t 评估它<=( t - t 0 )/( t 1 - t 0 )在 t 时获取对象的插值位置。为了获得速度,我们可以将相同的值插入 p ',在 t *进行评估,并将结果乘以( t 1 - t 0 )将其重新缩放回适当的时间。

由于这是Stack Overflow,所以这里有一些简单的Python代码:

def interpolate (t, t0, x0, v0, t1, x1, v1):
    # scale time so that t0 -> 0 and t1 -> 1
    timescale = t1 - t0
    t = (t - t0) / timescale
    v0 /= timescale
    v1 /= timescale

    # calculate the coefficients of the polynomial
    a = v0 + v1 + 2*(x0 - x1)
    b = -2*v0 - v1 - 3*(x0 - x1)
    c = v0
    d = x0

    # calculate position and velocity at time t
    x = ((a*t + b)*t + c)*t + d
    v = ((3*a*t + 2*b)*t + c) * timescale
    return (x, v)

(将其转换为C#应该很简单,因为基本算法在两种语言中都是一样的。)

请注意,您可以通过将位置和速度(以及多项式系数)视为矢量,一次性在所有三个维度中进行插值,或者您可以一次只在一个维度上进行插值;插值位置和速度线性地取决于原点,因此结果两种方式相同(并且不依赖于您选择坐标轴的方式)。