繁体   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