我想知道如何解决 Scipy Interpolate 模块“LSQUnivariateSpline”遇到的问题,我试图通过一组 2D 点拟合 B 样条曲线。这里 LSQUnivariateSpline 方法工作得很好,代码返回一组 X/Y 点,我可以用它来创建 DXF 样条线。
在一些单元测试中,我发现了我的设计中的一个小缺陷。对于单元测试,我创建了一些简单的形状(以 X/Y 点为单位):椭圆形、起始形状、正方形等等......
对于正方形,起点和终点位于正方形的角上。如果我现在绘制 b 样条 2D 点,它表明起点和终点不相切。所有其他角都显示出一些最佳拟合以减轻锐角。
有谁知道如何确保在这种最佳相切拟合中也考虑起点/终点?
示例:
以下是创建 X/Y 点的方法。它需要一个 numpy-2D-array 作为输入。
def b_spline_interpolation(np_xy_points: np.array) -> np.array:
"""Creates a b-spline based on the scipy module 'interpolate' and it's method 'LSQ Univariate Spline'."""
# interpolate based on the 'LSQ Univariate Spline'
ui = np.cumsum(np.r_[[0], np.linalg.norm(np.diff(np_xy_points, axis=0), axis=1)])
knots = np.linspace(ui[0], ui[-1], 40)
try:
sx = interpolate.LSQUnivariateSpline(ui, np_xy_points[:, 0], knots[1:-1], k=3)
sy = interpolate.LSQUnivariateSpline(ui, np_xy_points[:, 1], knots[1:-1], k=3)
except ValueError as err:
log.error(f"Failed to create the LSQ Univariate Spline, error: {err}")
return np.array([])
# sampling the resulting spline
uu = np.linspace(ui[0], ui[-1], 150)
xx = sx(uu)
yy = sy(uu)
# create the numpy 2D array
np_xy_array = np.vstack((xx, yy)).T
return np_xy_array
最诚挚的问候, LVX
您的数据是否有噪音,您需要消除噪音吗?否则没有理由使用 LSQUnivariateSpline(此处 lsq = 最小二乘法)。 如果您确实想要插值,则该作业的工具是带有 bc_type="periodic" 的 CubicSpline,如评论中所建议的。或者,
splprep
对于参数曲线可能更方便;确保添加 s=0
来强制插值。
总而言之,如果数据有尖角并且您想将它们保留在曲线中,则您不需要或不需要三次样条;它们是两次连续可导的,因此不可避免地会圆角(并且经常在尖锐特征周围产生波动)。为什么不直接拟合四条直线呢?