Skip to main content
`Ctrl`+`K`
scipy.spatial.transform.Rotation.

# from_davenport

static Rotation.from_davenport(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 or more 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 (…, [1 or 2 or 3])

      Angles specified in radians (degrees is False) or degrees (degrees is True). Each angle i in the last dimension of angles turns around the corresponding axis axis[…, i, :]. The resulting rotation has the shape np.broadcast_shapes(np.atleast_2d(axes).shape[:-2], np.atleast_1d(angles).shape[:-1]) Dimensionless angles are thus only valid for a single axis.

    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.

  Notes

  Array API Standard Support

  `from_davenport` has experimental support for Python Array API Standard compatible backends in addition to NumPy. Please consider testing these features by setting an environment variable `SCIPY_ARRAY_API=1` and providing CuPy, PyTorch, JAX, or Dask arrays as array arguments. The following combinations of backend and device (or other capability) are supported.

  Library | CPU | GPU
  --- | --- | ---
  NumPy | ✅ | n/a
  CuPy | n/a | ✅
  PyTorch | ✅ | ✅
  JAX | ✅ | ✅
  Dask | ⛔ | n/a

  > See Support for the array API standard for more information.

  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]