Skip to main content
`Ctrl`+`K`

# 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:
    axes array_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.

    order string

      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.

    angles float 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

    degrees bool, optional

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

  Returns:
    rotation `Rotation` instance

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

  References

  [1]

  https://en.wikipedia.org/wiki/Euler_angles#Definition_by_intrinsic_rotations

  [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]