scipy.spatial.transform.Rotation.

as_davenport#

Rotation.as_davenport(self, axes, order, degrees=False)#

表示成 Davenport 角。

任何方位皆可表示為 3 個基本旋轉的組合。

對於尤拉角和 Davenport 角,連續軸必須是正交的(axis2axis1axis3 皆正交)。對於尤拉角,axis1axis3 之間存在額外的關係,有兩種可能性:

  • axis1axis3 也正交(非對稱序列)

  • axis1 == axis3(對稱序列)

對於 Davenport 角,最後這個關係被放寬 [1],並且僅保留連續正交軸的要求。

使用了稍微修改自 [2] 的演算法,以計算繞給定軸序列旋轉的 Davenport 角。

Davenport 角與尤拉角一樣,都存在萬向鎖的問題 [3],其中表示法失去一個自由度,並且無法唯一確定第一個和第三個角。在這種情況下,會發出警告,並且第三個角設定為零。但請注意,返回的角度仍然表示正確的旋轉。

參數:
axesarray_like,形狀 (3,) 或 ([1 或 2 或 3], 3)

旋轉軸,若為一維。若為二維,則描述旋轉軸的序列,其中每個 axes[i, :] 是第 i 個軸。若給定多個軸,則第二個軸必須與第一個和第三個軸都正交。

order字串

如果屬於集合 {‘e’, ‘extrinsic’},則序列將為外在的。如果屬於集合 {‘i’, ‘intrinsic’},則序列將被視為內在的。

degrees布林值,選用

如果此旗標為 True,則傳回的角度以度為單位,否則以弧度為單位。預設值為 False。

返回:
anglesndarray,形狀 (3,) 或 (N, 3)

形狀取決於用於初始化物件的輸入形狀。傳回的角度在以下範圍內

  • 第一個角屬於 [-180, 180] 度(包含兩端)

  • 第三個角屬於 [-180, 180] 度(包含兩端)

  • 第二個角屬於大小為 180 度的集合,由以下給出:[-abs(lambda), 180 - abs(lambda)],其中 lambda 是第一個和第三個軸之間的角度。

參考文獻

[1]

Shuster, Malcolm & Markley, Landis. (2003). Generalization of the Euler Angles. Journal of the Astronautical Sciences. 51. 123-132. 10.1007/BF03546304.

[2]

Bernardes E, Viollet S (2022) Quaternion to Euler angles conversion: A direct, general and computationally efficient method. PLoS ONE 17(11): e0276302. 10.1371/journal.pone.0276302

範例

>>> from scipy.spatial.transform import Rotation as R
>>> import numpy as np

當我們使用標準基底軸時,Davenport 角是尤拉角的推廣

>>> ex = [1, 0, 0]
>>> ey = [0, 1, 0]
>>> ez = [0, 0, 1]

表示單次旋轉

>>> r = R.from_rotvec([0, 0, np.pi/2])
>>> r.as_davenport([ez, ex, ey], 'extrinsic', degrees=True)
array([90.,  0.,  0.])
>>> r.as_euler('zxy', degrees=True)
array([90.,  0.,  0.])
>>> r.as_davenport([ez, ex, ey], 'extrinsic', degrees=True).shape
(3,)

表示單次旋轉的堆疊

>>> r = R.from_rotvec([[0, 0, np.pi/2]])
>>> r.as_davenport([ez, ex, ey], 'extrinsic', degrees=True)
array([[90.,  0.,  0.]])
>>> r.as_davenport([ez, ex, ey], 'extrinsic', degrees=True).shape
(1, 3)

在單個物件中表示多次旋轉

>>> r = R.from_rotvec([
... [0, 0, 90],
... [45, 0, 0]], degrees=True)
>>> r.as_davenport([ez, ex, ey], 'extrinsic', degrees=True)
array([[90.,  0.,  0.],
       [ 0., 45.,  0.]])
>>> r.as_davenport([ez, ex, ey], 'extrinsic', degrees=True).shape
(2, 3)