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

# __mul__

RigidTransform.__mul__(other)

  Compose this transform with the other.

  If `p` and `q` are two transforms, then the composition of ‘`q` followed by `p`’ is equivalent to `p * q`. In terms of transformation matrices, the composition can be expressed as `p.as_matrix() @ q.as_matrix()`.

  In terms of translations and rotations, the composition when applied to a vector `v` is equivalent to `p.translation + p.rotation.apply(q.translation) + (p.rotation * q.rotation).apply(v)`.

  This function supports composition of multiple transforms at a time using broadcasting rules. The resulting shape for two `RigidTransform` instances `p` and `q` is np.broadcast_shapes(p.shape, q.shape).

  Parameters:
    other `RigidTransform` instance

      Transform(s) to be composed with this one. The shapes must be broadcastable.

  Returns:
    `RigidTransform` instance

      The composed transform.

  Notes

  Array API Standard Support

  `__mul__` 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.

  Examples

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

  Compose two transforms:

      >>> tf1 = Tf.from_translation([1, 0, 0])
      >>> tf2 = Tf.from_translation([0, 1, 0])
      >>> tf = tf1 * tf2
      >>> tf.translation
      array([1., 1., 0.])
      >>> tf.single
      True

  When applied to a vector, the composition of two transforms is applied in right-to-left order.

      >>> t1, r1 = [1, 2, 3], R.from_euler('z', 60, degrees=True)
      >>> t2, r2 = [0, 1, 0], R.from_euler('x', 30, degrees=True)
      >>> tf1 = Tf.from_components(t1, r1)
      >>> tf2 = Tf.from_components(t2, r2)
      >>> tf = tf1 * tf2
      >>> tf.apply([1, 0, 0])
      array([0.6339746, 3.3660254, 3.       ])
      >>> tf1.apply(tf2.apply([1, 0, 0]))
      array([0.6339746, 3.3660254, 3.       ])

  When at least one of the transforms is not single, the result is a stack of transforms.

      >>> tf1 = Tf.from_translation([1, 0, 0])
      >>> tf2 = Tf.from_translation([[0, 2, 0], [0, 0, 3]])
      >>> tf = tf1 * tf2
      >>> tf.translation
      array([[1., 2., 0.],
             [1., 0., 3.]])
      >>> tf.single
      False
      >>> len(tf)
      2

  Broadcasting rules apply when composing multiple transforms at a time.

      >>> tf1 = Tf.from_translation(np.ones((5, 1, 3)))  # Shape (5, 1, 3)
      >>> tf2 = Tf.from_translation(np.ones((1, 4, 3)))  # Shape (1, 4, 3)
      >>> tf = tf1 * tf2  # Shape (5, 4, 3)
      >>> tf.translation.shape
      (5, 4, 3)