scipy.spatial.geometric_slerp

scipy.spatial.geometric_slerp(start, end, t, tol=1e-07)[源代码]

几何球面线性插值。

插补是在任意维空间中沿单位半径大圆弧进行的。

参数
start(n_维数,)类似数组

一维阵列状对象中的单个n维输入坐标。 n 必须大于1。

end(n_维数,)类似数组

一维阵列状对象中的单个n维输入坐标。 n 必须大于1。

t: float or (n_points,) 1D array-like

表示插值参数的浮点或一维双精度数组,需要介于0和1之间的包含区间内的值。通常的方法是使用以下命令生成数组 np.linspace(0, 1, n_pts) 用于线性间隔点。允许升序、降序和加扰顺序。

TOL:浮点

用于确定起点坐标和终点坐标是否为对极的绝对公差。

退货
result(t.size,D)

包含内插球面路径并在使用0和1t时包括开始和结束的双精度数组。内插值应对应于t数组中提供的相同排序顺序。如果满足以下条件,则结果可以是一维 t 是一个浮点。

加薪
ValueError

如果 startend 是对极,而不是在单位n球面上,或用于各种简并条件。

参见

scipy.spatial.transform.Slerp

使用四元数的3-D Slerp

注意事项

该实现基于中提供的数学公式 [1], 在Ken Shoemake的原始四元数Slerp出版物的脚注中,这种算法的第一个已知演示(源自对4-D几何的研究)归功于Glenn Davis [2].

1.5.0 新版功能.

参考文献

1

https://en.wikipedia.org/wiki/Slerp#Geometric_Slerp

2

Ken Shoemake(1985)使用四元数曲线设置旋转动画。计算机图形学,19(3):245-254。

示例

在跨度为90度的圆的圆周上插入四个线性间隔值:

>>> from scipy.spatial import geometric_slerp
>>> import matplotlib.pyplot as plt
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> start = np.array([1, 0])
>>> end = np.array([0, 1])
>>> t_vals = np.linspace(0, 1, 4)
>>> result = geometric_slerp(start,
...                          end,
...                          t_vals)

插值结果应为单位圆上可识别的30度间隔:

>>> ax.scatter(result[...,0], result[...,1], c='k')
>>> circle = plt.Circle((0, 0), 1, color='grey')
>>> ax.add_artist(circle)
>>> ax.set_aspect('equal')
>>> plt.show()
../../_images/scipy-spatial-geometric_slerp-1_00_00.png

尝试在圆上的对极之间进行插值是不明确的,因为在球面上有两条可能的路径,而在球面上测地曲面上有无限条可能的路径。尽管如此,仍会返回其中一条不明确的路径以及一条警告:

>>> opposite_pole = np.array([-1, 0])
>>> with np.testing.suppress_warnings() as sup:
...     sup.filter(UserWarning)
...     geometric_slerp(start,
...                     opposite_pole,
...                     t_vals)
array([[ 1.00000000e+00,  0.00000000e+00],
       [ 5.00000000e-01,  8.66025404e-01],
       [-5.00000000e-01,  8.66025404e-01],
       [-1.00000000e+00,  1.22464680e-16]])

将原始示例扩展到球体并在3D中绘制插值点:

>>> from mpl_toolkits.mplot3d import proj3d
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111, projection='3d')

打印单位球体以供参考(可选):

>>> u = np.linspace(0, 2 * np.pi, 100)
>>> v = np.linspace(0, np.pi, 100)
>>> x = np.outer(np.cos(u), np.sin(v))
>>> y = np.outer(np.sin(u), np.sin(v))
>>> z = np.outer(np.ones(np.size(u)), np.cos(v))
>>> ax.plot_surface(x, y, z, color='y', alpha=0.1)

在较大数量的点上插值可能会在球体曲面上提供平滑曲线的外观,这对于球体曲面上的离散积分计算也很有用:

>>> start = np.array([1, 0, 0])
>>> end = np.array([0, 0, 1])
>>> t_vals = np.linspace(0, 1, 200)
>>> result = geometric_slerp(start,
...                          end,
...                          t_vals)
>>> ax.plot(result[...,0],
...         result[...,1],
...         result[...,2],
...         c='k')
>>> plt.show()
../../_images/scipy-spatial-geometric_slerp-1_01_00.png