[英]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.