scipy.spatial.

geometric_slerp#

scipy.spatial.geometric_slerp(start, end, t, tol=1e-07)[source]#

几何球面线性插值。

插值在任意维空间的单位半径大圆弧上进行。

参数:
start(n_dimensions, ) array-like

1-D array-like 对象中的单个 n 维输入坐标。n 必须大于 1。

end(n_dimensions, ) array-like

1-D array-like 对象中的单个 n 维输入坐标。n 必须大于 1。

t浮点型或 (n_points,) 1D array-like

表示插值参数的浮点型或 1D array-like 双精度浮点数,取值为 0 到 1(包括边界值)的闭区间。一种常见的方法是使用 np.linspace(0, 1, n_pts) 为线性间隔点生成数组。允许升序、降序和随机顺序。

tol浮点型

用于确定起点和终点为对跖点的绝对公差。

返回:
result(t.size, D)

包含插值球形路径的双精度数组,包括在使用 0 和 1 t 时开始和结束。插值值应对应在 t 数组中提供的相同排序。如果 t 是浮点数,结果可能是 1 维的。

引发:
ValueError

如果 startend 是对跖点,不在单位 n 球面上,或存在多种退化条件。

另请参见

scipy.spatial.transform.Slerp

适用于四元数的 3-D Slerp

注释

此实现基于在 [1] 中提供的数学公式,并且该算法的首次已知展示(源于对 4-D 几何的研究)归功于 Glenn Davis,他在 Ken Shoemake [2] 撰写的原始四元数 Slerp 出版物的脚注中提到。

添加于 1.5.0 版中。

参考文献

[2]

Ken Shoemake (1985) Animating rotation with quaternion curves. ACM SIGGRAPH Computer Graphics, 19(3): 245-254.

示例

插值圆周上四线性间隔的值,跨度 90 度

>>> import numpy as np
>>> 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