如何在两个时间步之间插入二维点?

时间:2017-10-13 15:08:27

标签: python python-2.7 python-3.x interpolation

我有2个二维坐标。比如说,(x_1, y_1)t = 1的时间点,(x_2, y_2)t = 10的时间点。我想在110时间步之间进行线性插值,即2,3,...9

我如何在python中执行此操作?

2 个答案:

答案 0 :(得分:0)

您可以使用这两个点计算线的方程,然后使用公式生成多个点。但是与时间的关系取决于你想要的运动类型(easeOut,easeIn,linear)

(Y - y2)/(X - x2) = (y2 - y1)(x2 - x1)

这是等式。您可以使用实数值并得到X和Y的等式。然后将Y值计算为给定的X值。

这应该有效。您可以为seek提供介于0和0之间的值。 1得到中间坐标

def interpolate(x1, y1, x2, y2, seek):
    X = x1 + x2*seek
    Y = y2 + (y2 - y1)(X - x2)/(x2 - x1)
    return (X,Y)

答案 1 :(得分:0)

您需要做的是linear interpolation,所以您需要的是lerp()功能:

from __future__ import division  # For Python 2
from operator import itemgetter

def lerp(t, times, points):
    getx, gety = itemgetter(0), itemgetter(1)
    tmin, tmax = min(times), max(times)
    dt = (t-tmin) / (tmax-tmin)

    xmin = min(getx(point) for point in points)
    xmax = max(getx(point) for point in points)
    ymin = min(gety(point) for point in points)
    ymax = max(gety(point) for point in points)

    return dt*(xmax-xmin) + xmin, dt*(ymax-ymin) + ymin

x_1, y_1 = 1, 2
x_2, y_2 = 3, 4
times = [1, 10]
points = [(x_1, y_1), (x_2, y_2)]

for v in range(1, 11):
    print('{:2d} -> ({:6.3f}, {:6.3f})'.format(v, *lerp(v, times, points)))

输出:

 1 -> ( 1.000,  2.000)
 2 -> ( 1.222,  2.222)
 3 -> ( 1.444,  2.444)
 4 -> ( 1.667,  2.667)
 5 -> ( 1.889,  2.889)
 6 -> ( 2.111,  3.111)
 7 -> ( 2.333,  3.333)
 8 -> ( 2.556,  3.556)
 9 -> ( 2.778,  3.778)
10 -> ( 3.000,  4.000)

面向对象的方法

如果您经常打电话给它,那么优化它可能是值得的,所以它不需要在每次调用之间重新计算这么多的值调用。一种方法是使用class方法将其设为 __call__() 。这样,所有初步计算都可以在它首次构建时完成,然后只要稍后用不同的时间参数调用对象就重新使用。如果需要的话,它还可以使每个对象同时拥有和使用多个Lerp个对象或它们的容器。

像这样的类有时被称为"functors",因为它们是函数和对象的组合(尽管普通函数已经是Python中的对象,它们不够灵活且易于定制)。 / p>

这就是我的意思:

from __future__ import division  # For Python 2
from operator import itemgetter

class Lerp(object):
    def __init__(self, times, points):
        getx, gety = itemgetter(0), itemgetter(1)

        self.tmin, self.tmax = min(times), max(times)
        self.time_delta = self.tmax-self.tmin

        self.xmin = min(getx(point) for point in points)
        self.xmax = max(getx(point) for point in points)
        self.x_delta = self.xmax-self.xmin

        self.ymin = min(gety(point) for point in points)
        self.ymax = max(gety(point) for point in points)
        self.y_delta = self.ymax-self.ymin

    def __call__(self, t):
        dt = (t-self.tmin) / self.time_delta
        return (dt*self.x_delta + self.xmin, dt*self.y_delta + self.ymin)


x_1, y_1 = 1, 2
x_2, y_2 = 3, 4
times = [1, 10]
points = [(x_1, y_1), (x_2, y_2)]
lerp = Lerp(times, points)

for v in range(1, 11):
    print('{:2d} -> ({:6.3f}, {:6.3f})'.format(v, *lerp(v)))