總結問題:你想通過多個點進行插值的平滑曲線。對於2D空間中的每個點,您都有座標以及一個角度,該角度定義了此時曲線的切線。
解決方案可能是使用Bézier curves的第三階。這樣的曲線將被定義爲4點;兩個端點,即圖中兩個連續點,以及兩個中間點,它們定義曲線的方向。 Bézier曲線通常用於圖形軟件,Matplotlib也可以在內部繪製路徑。
因此,我們可以定義具有它的兩個中間點沿着由角度到每個點的給定的正切Bezier曲線。 本身沒有任何暗示兩個中間點應該位於該切線上的位置,所以我們可以從兩個端點選擇一些任意距離。在下面的代碼中這就是所謂的r
。爲此參數r
選擇一個合適的值是獲得平滑曲線的關鍵。
import numpy as np
from scipy.special import binom
import matplotlib.pyplot as plt
bernstein = lambda n, k, t: binom(n,k)* t**k * (1.-t)**(n-k)
def bezier(points, num=200):
N = len(points)
t = np.linspace(0, 1, num=num)
curve = np.zeros((num, 2))
for i in range(N):
curve += np.outer(bernstein(N - 1, i, t), points[i])
return curve
class Segment():
def __init__(self, p1, p2, angle1, angle2, **kw):
self.p1 = p1; self.p2 = p2
self.angle1 = angle1; self.angle2 = angle2
self.numpoints = kw.get("numpoints", 100)
method = kw.get("method", "const")
if method=="const":
self.r = kw.get("r", 1.)
else:
r = kw.get("r", 0.3)
d = np.sqrt(np.sum((self.p2-self.p1)**2))
self.r = r*d
self.p = np.zeros((4,2))
self.p[0,:] = self.p1[:]
self.p[3,:] = self.p2[:]
self.calc_intermediate_points(self.r)
def calc_intermediate_points(self,r):
self.p[1,:] = self.p1 + np.array([self.r*np.cos(self.angle1),
self.r*np.sin(self.angle1)])
self.p[2,:] = self.p2 + np.array([self.r*np.cos(self.angle2+np.pi),
self.r*np.sin(self.angle2+np.pi)])
self.curve = bezier(self.p,self.numpoints)
def get_curve(points, **kw):
segments = []
for i in range(len(points)-1):
seg = Segment(points[i,:2], points[i+1,:2], points[i,2],points[i+1,2],**kw)
segments.append(seg)
curve = np.concatenate([s.curve for s in segments])
return segments, curve
def plot_point(ax, xy, angle, r=0.3):
ax.plot([xy[0]],[xy[1]], marker="o", ms=9, alpha=0.5, color="indigo")
p = xy + np.array([r*np.cos(angle),r*np.sin(angle)])
ax.plot([xy[0],p[0]], [xy[1],p[1]], color="limegreen")
if __name__ == "__main__":
# x y angle
points =np.array([[ 6.0, 0.5, 1.5],
[ 5.4, 1.2, 2.2],
[ 5.0, 1.7, 2.6],
[ 2.8, 2.4, 2.1],
[ 1.3, 3.2, 1.6],
[ 1.9, 3.9,-0.2],
[ 4.0, 3.0, 0.2],
[ 5.1, 3.7, 1.4]])
fig, ax = plt.subplots()
for point in points:
plot_point(ax, point[:2],point[2], r=0.1)
s1, c1 = get_curve(points, method="const", r=0.7)
ax.plot(c1[:,0], c1[:,1], color="crimson", zorder=0, label="const 0.7 units")
s2, c2 = get_curve(points, method="prop", r=0.3)
ax.plot(c2[:,0], c2[:,1], color="gold", zorder=0, label="prop 30% of distance")
plt.legend()
plt.show()
在上述兩種情況下的曲線圖進行比較。其中r
是恆定的0.7
個單位,其他r
是其中兩個點之間距離的相對30%。
您需要解釋*「將所有模式連接在一起」* **更詳細。否則,沒有人能夠理解你想要做什麼。此外,實現這一目標的問題究竟是什麼?你有什麼嘗試,在多遠沒有奏效。如果你沒有告訴你有什麼問題,這個問題可能太寬泛而無法回答。 – ImportanceOfBeingErnest
謝謝你的提示!我編輯它。我希望這將有助於理解我想要連接模式的方式。我的主要問題是沒有找到任何讓我做我想做的功能。我曾期待那些已經試圖做同樣事情的人可以給我一些關於如何實現這樣的任務的暗示。 –
我不認爲你會找到一個預定義的函數來做你想做的事情,因爲問題是二維的(你實際上有二維梯度,而不是一維導數),因此沒有獨特的解決方案來連接點。如果這是一個一維問題,像'scipy.interpolate.KroghInterpolator'可以幫助你。但是,在這種情況下,它會失敗。 – ImportanceOfBeingErnest