获取三维三次样条的轨迹 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 插值相似但不相同(例如在端点附近)。
我正在尝试用三维三次样条近似给定路线(坐标)。示例数据:
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 插值相似但不相同(例如在端点附近)。