scipy 为什么三次样条曲线创建不符合逻辑的形状?

wfveoks0  于 2023-11-19  发布在  其他
关注(0)|答案(2)|浏览(124)

我试图使用SciPy的三次样条函数绘制一个类似拱形的三次样条曲线,但在某些时候,在两个控制点之间创建了一个非逻辑形状。黑色的线是函数正在评估的,绿色是我期望发生的(就像它在点4和8之间一样)
这就是我如何创建图像(您可以检查代码并运行它here

from scipy.interpolate import CubicSpline
import numpy as np
import matplotlib.pyplot as plt
x = [-0.0243890844, -0.0188174509, -0.00021640210000000056, 0.0202699043, 0.0239562802] # X values of the coordinates for points 2, 4, 8, 13 and 15
y = [-0.0117638968, 0.00469300617, 0.0177650191, 0.00215831073, -0.0154924048] # Y values of the coordinates for points 2, 4, 8, 13 and 15
cs = CubicSpline(x, y)
dsX = np.linspace(x[0], x[len(x)-1], num=1000)
plt.plot(dsX, cs(dsX), 'k')
plt.plot(x, y, 'mo')
plt.show()

字符串
x1c 0d1x的数据
你知道我该如何解决这个问题吗?或者是什么原因导致了这个问题?我是否缺少了任何类型的选项/配置参数?

pxy2qtax

pxy2qtax1#

结果是合乎逻辑的,也是预期的。你不应该使用scipy.interpolate.CubicSpline()来设计2D曲线。那个API是为插值函数而设计的。使用Splipy和Python等库。
在设计二维参数化曲线(xt),yt))时,指定曲线上的点而不指定 t 值,在 t 上找到两个独立的样条函数,xt)和 yt)。但是在插值函数 y = fx)时,指定函数上的点包括 x 值,而你只会发现 x 上的一个样条函数。后者并不能给予与原始插值点类似的曲线的所需光滑切线,因为前者具有旋转对称性,而后者没有。
请参阅B样条-计算机辅助设计和计算机图形学以及 The NURBS Book 的第3章,了解有关此主题的理论背景。
下面是使用Splipy库为插值点查找此类参数化曲线的示例。

import numpy as np
import matplotlib.pyplot as plt
import splipy.curve_factory

x = [-0.0243890844, -0.0188174509, -0.00021640210000000056, 0.0202699043, 0.0239562802]
y = [-0.0117638968, 0.00469300617, 0.0177650191, 0.00215831073, -0.0154924048]

interp_points = np.array([x, y]).T

curve = splipy.curve_factory.cubic_curve(interp_points)
t_values = np.linspace(curve.start(0), curve.end(0), 100)
points = curve.evaluate(t_values)

plt.plot(interp_points[:, 0], interp_points[:, 1], 'x')
plt.plot(points[:, 0], points[:, 1])
plt.xlabel('x')
plt.ylabel('y')
plt.show()

字符串
这将输出下图。x1c 0d1x

mutmk8jj

mutmk8jj2#

由于匹配二阶导数的约束,三次样条曲线很容易出现这样的过冲。因此,数据中的微小变化可能会导致曲线本身的巨大变化,包括你在这里看到的。
CubicSpline无法解决这个问题。您可以做的是明确您的要求并选择适当的插值。如果您可以放弃C2要求并且C1插值也可以,您可以使用pchip或Akima1D,如注解中所建议的。如果您想要平滑而不是插值,则可以使用make_smoothing_spline(如注解中所建议的)。

相关问题