如何在Python中构建过全部输入点的3D光滑样条?求替代库
3D插值样条:光滑且过所有输入点的实现方案
一、用你当前的Scipy库直接解决问题
你当前代码里,splprep的参数s=0.5是最小二乘平滑因子,数值越大拟合越宽松,自然不会经过所有点。把s设为0就能强制样条通过所有输入点,同时保持样条的光滑性:
修改后的代码:
import numpy as np from scipy.interpolate import splprep, splev import matplotlib.pyplot as plt numpoints = 15 x = np.linspace(0, 10, numpoints) y = np.cos(x) z = x # s=0 强制通过所有输入点,k=3指定三次样条保证二阶连续光滑 tck, u = splprep([x, y, z], s=0, k=3) # 生成更多采样点,让绘制的曲线更流畅 u_new = np.linspace(u.min(), u.max(), 1000) new_points = splev(u_new, tck) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.plot(x, y, z, 'r.', label='输入点') ax.plot(new_points[0], new_points[1], new_points[2], 'b-', label='光滑样条') ax.legend() plt.show()
二、其他可选函数库
如果你确实需要更换库,以下两个方案可满足需求:
1. pySpline(专业样条库)
pySpline专门用于生成各类样条曲线,支持3D参数样条,能强制通过所有输入点且保持光滑:
安装命令:
pip install pyspline
示例代码:
import numpy as np import matplotlib.pyplot as plt from pyspline import Curve numpoints = 15 x = np.linspace(0, 10, numpoints) y = np.cos(x) z = x # 将点组合成Nx3的数组 points = np.column_stack((x, y, z)) # 创建三次样条曲线,强制通过所有点 curve = Curve(x=np.arange(numpoints), y=points, k=3) # 生成样条上的采样点 u_new = np.linspace(0, numpoints-1, 1000) new_points = curve(u_new) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.plot(x, y, z, 'r.', label='输入点') ax.plot(new_points[:,0], new_points[:,1], new_points[:,2], 'b-', label='光滑样条') ax.legend() plt.show()
2. OpenCV(多维度插值适配)
OpenCV的插值函数可分别对x、y、z三个维度进行一维样条插值,同样能实现过所有点的光滑曲线:
安装命令:
pip install opencv-python
示例代码:
import numpy as np import cv2 import matplotlib.pyplot as plt numpoints = 15 x = np.linspace(0, 10, numpoints) y = np.cos(x) z = x # 定义参数化变量u u = np.arange(numpoints) u_new = np.linspace(0, numpoints-1, 1000) # 对每个维度进行三次样条插值 x_new = cv2.spline(u, x, u_new, k=3) y_new = cv2.spline(u, y, u_new, k=3) z_new = cv2.spline(u, z, u_new, k=3) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.plot(x, y, z, 'r.', label='输入点') ax.plot(x_new, y_new, z_new, 'b-', label='光滑样条') ax.legend() plt.show()
内容的提问来源于stack exchange,提问作者Tim Bentley
相关产品推荐
相关产品推荐

