scipy.spatial.transform.Rotation.from_davenport#

classmethod Rotation.from_davenport(cls, axes, order, angles, degrees=False)#

Initialize from Davenport angles.

Rotations in 3-D can be represented by a sequence of 3 rotations around a sequence of axes.

The three rotations can either be in a global frame of reference (extrinsic) or in a body centred frame of reference (intrinsic), which is attached to, and moves with, the object under rotation [1].

For both Euler angles and Davenport angles, consecutive axes must be are orthogonal (axis2 is orthogonal to both axis1 and axis3). For Euler angles, there is an additional relationship between axis1 or axis3, with two possibilities:

  • axis1 and axis3 are also orthogonal (asymmetric sequence)

  • axis1 == axis3 (symmetric sequence)

For Davenport angles, this last relationship is relaxed [2], and only the consecutive orthogonal axes requirement is maintained.

Parameters:
axesarray_like, shape (3,) or ([1 or 2 or 3], 3)

Axis of rotation, if one dimensional. If two dimensional, describes the sequence of axes for rotations, where each axes[i, :] is the ith axis. If more than one axis is given, then the second axis must be orthogonal to both the first and third axes.

orderstring

If it is equal to ‘e’ or ‘extrinsic’, the sequence will be extrinsic. If it is equal to ‘i’ or ‘intrinsic’, sequence will be treated as intrinsic.

anglesfloat or array_like, shape (N,) or (N, [1 or 2 or 3])

Euler angles specified in radians (degrees is False) or degrees (degrees is True). For a single axis, angles can be:

  • a single value

  • array_like with shape (N,), where each angle[i] corresponds to a single rotation

  • array_like with shape (N, 1), where each angle[i, 0] corresponds to a single rotation

For 2 and 3 axes, angles can be:

  • array_like with shape (W,) where W is the number of rows of axes, which corresponds to a single rotation with W axes

  • array_like with shape (N, W) where each angle[i] corresponds to a sequence of Davenport angles describing a single rotation

degreesbool, optional

If True, then the given angles are assumed to be in degrees. Default is False.

Returns:
rotationRotation instance

Object containing the rotation represented by the sequence of rotations around given axes with given angles.

References

[2]

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

Examples

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

Davenport angles are a generalization of Euler angles, when we use the canonical basis axes:

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

Initialize a single rotation with a given axis sequence:

>>> axes = [ez, ey, ex]
>>> r = R.from_davenport(axes, 'extrinsic', [90, 0, 0], degrees=True)
>>> r.as_quat().shape
(4,)

It is equivalent to Euler angles in this case:

>>> r.as_euler('zyx', degrees=True)
array([90.,  0., -0.])

Initialize multiple rotations in one object:

>>> r = R.from_davenport(axes, 'extrinsic', [[90, 45, 30], [35, 45, 90]], degrees=True)
>>> r.as_quat().shape
(2, 4)

Using only one or two axes is also possible:

>>> r = R.from_davenport([ez, ex], 'extrinsic', [[90, 45], [35, 45]], degrees=True)
>>> r.as_quat().shape
(2, 4)

Non-canonical axes are possible, and they do not need to be normalized, as long as consecutive axes are orthogonal:

>>> e1 = [2, 0, 0]
>>> e2 = [0, 1, 0]
>>> e3 = [1, 0, 1]
>>> axes = [e1, e2, e3]
>>> r = R.from_davenport(axes, 'extrinsic', [90, 45, 30], degrees=True)
>>> r.as_quat()
[ 0.701057,  0.430459, -0.092296,  0.560986]