scipy.spatial.

geometric_slerp#

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

幾何球面線性內插。

內插發生在任意維度空間中單位半徑大圓弧上。

參數:
start(n_dimensions, ) 類陣列

單一 n 維輸入座標,以 1 維類陣列物件表示。n 必須大於 1。

end(n_dimensions, ) 類陣列

單一 n 維輸入座標,以 1 維類陣列物件表示。n 必須大於 1。

tfloat 或 (n_points,) 1D 類陣列

浮點數或雙精度浮點數的 1 維類陣列,表示內插參數,值必須在 0 到 1 的包含區間內。常見的方法是使用 np.linspace(0, 1, n_pts) 產生線性間隔點的陣列。允許升序、降序和亂序。

tolfloat

用於判斷起始和結束座標是否為對跖點的絕對容差。

返回:
result(t.size, D)

包含內插球面路徑的雙精度浮點數陣列,當使用 0 和 1 作為 t 時,包含起始和結束點。內插值應對應於 t 陣列中提供的相同排序順序。如果 t 是浮點數,則結果可能是一維的。

引發:
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