簡體   English   中英

確定任意 X 坐標處的 B 樣條曲線值

[英]Determining Value of B-Spline at an Arbitrary X Coordinate

我在數據點 xp 和 yp 的集合上創建了一個開放的、夾緊的、三次的、b 樣條曲線。

樣條由跨越 xp 域的向量 u 參數化。

我的目標是確定 xp 域中給定“x”坐標處的 b 樣條的“y”坐標。

正如生成參數曲線時的預期行為,當我在計算 tck 后將值“4”傳遞給 splev 時,返回對應於參數 4 的 x 和 y 坐標值。

我能夠使用牛頓法來確定給定“x”坐標處的參數 u 的值; 然而,這是間接的,需要比我的最終應用程序允許的更多的計算時間。

誰能建議一種更直接的方法來確定給定“x”的 b 樣條曲線上的“y”坐標?

import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate

xp = [0., 0.71428571, 1.42857143, 2.14285714, 2.85714286, 3.57142857, 4.28571429, 5.]
yp = [0., -0.86217009, -2.4457478, -2.19354839, -2.32844575, -0.48680352, -0.41055718, -3.]

length = len(xp)
t = np.linspace(0., xp[-1], length - 2, endpoint=True)
t = np.append([0, 0, 0], t)
t = np.append(t, [xp[-1], xp[-1], xp[-1]])

tck = [t, [xp, yp], 3]
u = np.linspace(0, 5., 1000, endpoint=True)
out = interpolate.splev(u, tck)

x_value_in_xp_domain = 4.
y_value_out = interpolate.splev(x_value_in_xp_domain, tck)

plt.plot(xp, yp, linestyle='--', marker='o', color='purple')
plt.plot(out[0], out[1], color = 'teal')
plt.plot(x_value_in_xp_domain, y_value_out[1], marker='o', color = 'orangered')
plt.plot(y_value_out[0], y_value_out[1], marker='o', color = 'black')
plt.axvline(x=x_value_in_xp_domain, color = 'orangered')
plt.show()

下圖顯示了由上述代碼生成的引導多邊形和 b 樣條曲線。 x=4 處的橙色點對應於我希望直接確定 b 樣條的 y 值的點。 黑點是將4的值作為參數傳遞時b樣條的值。

從上面的腳本中繪制

提供一些有用的參考:

使用 numpy/scipy 的快速 b 樣條算法

https://github.com/kawache/Python-B-spline-examples

https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/B-spline/bspline-curve.html

http://web.mit.edu/hyperbook/Patrikalakis-Maekawa-Cho/node17.html

PPoly類的roots方法可能是您的問題的解決方案。 這將比牛頓更快,如果有多個解決方案,它將為您提供所有解決方案。

sx = interpolate.BSpline(t, xp, 3)
sy = interpolate.BSpline(t, yp, 3)

x0 = 4
u0 = interpolate.PPoly.from_spline((sx.t, sx.c - x0, 3)).roots()
sy(u0)

plt.plot(xp, yp, linestyle='--', marker='o', color='purple')
plt.plot(out[0], out[1], color = 'teal')
plt.plot(sx(u0), sy(u0), 'o')
plt.show()

讓我建議更改框架。 如您所知,有兩種方法可以在平面中創建樣條曲線:作為function和作為參數曲線 您選擇了后者,但在問題中的任何地方我都看不到這樣做的任何令人信服的理由; 而采用前者會使您的問題的解決方案幾乎微不足道。

我們從一些輸入數據開始。

xdata  = [0.,  0.60626102,  1.36904762,  2.14285714,  2.85714286,  3.63095238,  4.39373898,  5.]
ydata  = [0., -0.82509685, -2.00782014, -2.25806452, -1.99902249, -0.77468231, -1.19975743, -3.]

請注意,與您在我的圈子中稱為控制點xpyp不同,我收集了一些我們將插值的點xdataydata 我通過在Greville 橫坐標上對您的 function 進行采樣來獲得與您的輸入類似的內容來做到這一點。 但是,確切的輸入類型取決於您的應用程序; 您在其中一條評論中提到了 function 近似值,所以我想這可能是一種方法。

現在,我們可以使用UnivariateSpline創建插值數據的樣條function

spline = interpolate.InterpolatedUnivariateSpline(xdata, ydata)

有一些選擇; 我建議查看插值教程及其中的參考資料。

這或多或少就是這樣。 您現在可以在很多點對 plot spline的值進行采樣:

xfunc  = np.linspace(0, 5., 1000, endpoint=True)
yfunc  = spline(xfunc)
plt.plot(xfunc, yfunc,  color = 'green')

然而,我們 go 之所以通過這一切是為了回答您的問題:如何找到給定x坐標對應的y坐標? 這很簡單:

x_value_in_xp_domain = 4.
y_value_out = spline(x_value_in_xp_domain)

這是一張顯示我的輸入數據(藍色;同樣,它們與您的輸入不相同)、插值樣條function (綠色)、 x_value_in_xp_domain (橙色曲線)和y_value_out (橙色點)的圖片。

樣條函數的繪圖。

最后,這是完整的源代碼。

import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate

xdata  = [0.,  0.60626102,  1.36904762,  2.14285714,  2.85714286,  3.63095238,  4.39373898,  5.]
ydata  = [0., -0.82509685, -2.00782014, -2.25806452, -1.99902249, -0.77468231, -1.19975743, -3.]

spline = interpolate.InterpolatedUnivariateSpline(xdata, ydata)
xfunc  = np.linspace(0, 5., 1000, endpoint=True)
yfunc  = spline(xfunc)

x_value_in_xp_domain = 4.
y_value_out = spline(x_value_in_xp_domain)

plt.plot(xfunc, yfunc,  color = 'green')
plt.plot(xdata, ydata, 'o', color = 'blue')
plt.plot(x_value_in_xp_domain, y_value_out, marker='o', color = 'orangered')
plt.axvline(x=x_value_in_xp_domain, color = 'orangered')
plt.show()

暫無
暫無

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

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