jaxtransform3d.rotations.compose_quaternions#
- jaxtransform3d.rotations.compose_quaternions(q1: Array | ndarray | bool_ | number | bool | int | float | complex, q2: Array | ndarray | bool_ | number | bool | int | float | complex) Array [source]#
Compose two quaternions.
We concatenate two quaternions by quaternion multiplication \(\boldsymbol{q}_1\boldsymbol{q}_2\).
We use Hamilton’s quaternion multiplication.
If the two quaternions are divided up into scalar part and vector part each, i.e., \(\boldsymbol{q} = (w, \boldsymbol{v}) \in \mathbb{H}, w \in \mathbb{R}, \boldsymbol{v} \in \mathbb{R}^3\), then the quaternion product is
\[\boldsymbol{q}_{12} = (w_1 w_2 - \boldsymbol{v}_1^T \cdot \boldsymbol{v}_2, w_1 \boldsymbol{v}_2 + w_2 \boldsymbol{v}_1 + \boldsymbol{v}_1 \times \boldsymbol{v}_2)\]with the dot product \(\cdot\) and the cross product \(\times\).
- Parameters:
- q1array-like, shape (…, 4)
First quaternion, scalar first.
- q2array-like, shape (…, 4)
Second quaternion, scalar first.
- Returns:
- q12array, shape (…, 4)
Quaternion that represents the concatenated rotation \(\boldsymbol{q}_1\boldsymbol{q}_2\) as defined above.
See also
compose_matrices
Compose two rotation matrices.
Examples
>>> import jax.numpy as jnp >>> from jaxtransform3d.rotations import compose_quaternions >>> compose_quaternions(jnp.array([1., 0., 0., 0.]), ... jnp.array([0., 1., 0., 0.])) Array([0., 1., 0., 0.], dtype=...) >>> compose_quaternions(jnp.array([0., 1., 0., 0.]), ... jnp.array([0., 0., 1., 0.])) Array([0., 0., 0., 1.], dtype=...) >>> compose_quaternions(jnp.array([0., 0., 1., 0.]), ... jnp.array([0., 0., 0., 1.])) Array([0., 1., 0., 0.], dtype=...) >>> compose_quaternions(jnp.array([0., 0., 0., 1.]), ... jnp.array([0., 0., 0., 1.])) Array([-1., 0., 0., 0.], dtype=...)