获取三维三次样条的轨迹 Scipy

Get Trajectory of Three Dimensional Cubic Spline Scipy

我正在尝试用三维三次样条近似给定路线(坐标)。示例数据:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
import numpy as np

%matplotlib inline

x = np.array([1, 2, 2.3, 3, 4, 5, 5.5, 8, 9, 9.5])
y = np.arange(0, 10)
z = np.sin(x) * np.cos(y^2) + x
fig = plt.figure(figsize=(10,6))
ax = axes3d.Axes3D(fig)
ax.stem(x, y, z)

我现在用 scipy 中的 RBF Interpolator 来近似数据点。这是正确的方法吗?

from scipy.interpolate import RBFInterpolator
coord_data = np.stack([x, y], -1)
spline = RBFInterpolator(coord_data, z, kernel = 'cubic')

我现在如何获得生成的样条曲线(它所遵循的点)?我如何访问它的衍生产品?

您正在尝试近似路线,即 3D 中的 曲线 ,而不是表面。您正在尝试的方法会产生一个表面,因此不适合您的情况。

3D 曲线的合适表示形式是元组 (x(u), y(u), z(u)) 的参数形式,其中 u 是某个参数,每个坐标都是 u 的函数。 曲线拟合问题简化为分别拟合(ui, xi)(ui, yi)(ui, zi)三个二维问题().

因此,为了执行曲线拟合,您需要为每个输入点提供参数化 ui。 样条拟合中的常见参数化是 chord-length parameterization。此参数化由有序点之间的距离的累积长度定义(u0=0, u1=|p1-p0|, u2 = u1+|p2-p1|...等)。

以下代码使用 chord-length 参数化实现数据的样条插值。

from scipy import interpolate

xyz = np.vstack([x, y, z]).T
u = np.cumsum(np.r_[[0], np.linalg.norm(np.diff(xyz, axis=0), axis=1)])
# u is the chord-legth parameterization for each xyz point

sx = interpolate.InterpolatedUnivariateSpline(u, x)  # x(u) spline
sy = interpolate.InterpolatedUnivariateSpline(u, y)  # y(u) spline
sz = interpolate.InterpolatedUnivariateSpline(u, z)  # z(u) spline

下面的代码对生成的样条曲线进行采样,并在您的数据(黑色多段线)上绘制结果(蓝色)。结果如下所示:

uu = np.linspace(u[0], u[-1], 100)
xx = sx(uu)
yy = sy(uu)
zz = sz(uu)
plt.plot(xx, yy, zz, "b")

您还可以使用您建议的 RBF 函数进行单变量插值。 以下代码是如何执行此操作的示例:

from scipy.interpolate import Rbf

rbfi_x = Rbf(u, x, function='cubic')
rbfi_y = Rbf(u, y, function='cubic')
rbfi_z = Rbf(u, z, function='cubic')

以与上面的样条样本类似的方式对结果函数进行采样,并将结果绘制在上图中,我们得到下图。可以看出,样条和 RBF 插值相似但不相同(例如在端点附近)。