[英]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樣條的值。
提供一些有用的參考:
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.]
請注意,與您在我的圈子中稱為控制點的xp
和yp
不同,我收集了一些我們將插值的點xdata
和ydata
。 我通過在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.