簡體   English   中英

如何在兩個時間步之間插入二維點?

[英]How to interpolate 2-D points between two timesteps?

我有 2 個二維坐標。 假設(x_1, y_1)是時間t = 1的點, (x_2, y_2)是時間t = 10的點。 我想在110時間步長之間進行線性插值,即2,3,...9

我如何在 python 中做到這一點?

您可以使用這兩個點計算直線的方程,然后使用該方程生成盡可能多的點。 但與時間的關系取決於你想要的運動類型(easeOut、easeIn、linear)

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

這是等式。 您可以使用您的實際值並獲得 X 和 Y 的方程。然后計算 Y 值到給定的 X 值。

這應該有效。 你可以給seek在0和1之間和值來獲得中間坐標

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

您想要做的稱為線性插值,可以使用lerp()函數完成:

from __future__ import division  # For Python 2

def lerp(t, times, points):
    dx = points[1][0] - points[0][0]
    dy = points[1][1] - points[0][1]
    dt = (t-times[0]) / (times[1]-times[0])
    return dt*dx + points[0][0], dt*dy + points[0][1]

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 -> ( 0.556,  2.222)
 3 -> ( 0.111,  2.444)
 4 -> (-0.333,  2.667)
 5 -> (-0.778,  2.889)
 6 -> (-1.222,  3.111)
 7 -> (-1.667,  3.333)
 8 -> (-2.111,  3.556)
 9 -> (-2.556,  3.778)
10 -> (-3.000,  4.000)

通過將lerp()轉換為生成器函數,可以實現一種更有效的方法,每次迭代的計算量明顯減少。 由於連續相加的累積誤差,這種方法的准確度稍低。

from __future__ import division  # For Python 2

def lerp(times, points, steps):
    divisor = steps-1
    dt =     (times[1] - times[0]) / divisor
    dx = (points[1][0] - points[0][0]) / divisor
    dy = (points[1][1] - points[0][1]) / divisor
    t, x, y = (times[0],) + points[0]
    for _ in range(steps):
        yield t, x, y
        t += dt
        x += dx
        y += dy

x_1, y_1 = 1, 2
x_2, y_2 = -3, 4
times = [1, 10]
points = [(x_1, y_1), (x_2, y_2)]
steps= times[1] - times[0] + 1
for t, x, y in lerp(times, points, steps):
    print('{:6.2f} -> ({:6.3f}, {:6.3f})'.format(t, x, y))

面向對象方法

如果您要經常調用它,那么優化它可能是值得的,這樣它就不需要在每次調用時都相同的調用之間重新計算這么多值。 一種方法是使用__call__()方法使其成為一個class 這樣,所有的初步計算都可以在第一次構造時完成,然后只要稍后使用不同的時間參數調用對象時就可以重用。 如果需要,它還可以讓每個人同時擁有和使用多個Lerp對象或它們的容器。

像這樣的類有時被稱為“函子”,因為它們是函數和對象的組合(盡管普通函數在 Python 中已經是對象,但它們並不那么靈活和易於定制)。

這就是我的意思:

from __future__ import division  # For Python 2

class Lerp(object):
    def __init__(self, times, points):
        self.t0 = times[0]
        self.p0 = points[0]
        self.dt = times[1] - times[0]
        self.dx = points[1][0] - points[0][0]
        self.dy = points[1][1] - points[0][1]

    def __call__(self, t):
        dt = (t-self.t0) / self.dt
        return dt*self.dx + self.p0[0], dt*self.dy + self.p0[1]

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)))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM