我有2个二维坐标。比如说,(x_1, y_1)
是t = 1
的时间点,(x_2, y_2)
是t = 10
的时间点。我想在1
到10
时间步之间进行线性插值,即2,3,...9
。
我如何在python中执行此操作?
答案 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)))