Skip to content

Rotations

rotations

Rotation representation conversions for skeleton-based motion data.

All functions are batch-vectorized using NumPy and operate on arrays where the leading dimensions are batch dimensions.

Supported representations: - Euler angles: (, 3) in degrees or radians - Rotation matrices: (, 3, 3) - 6D rotation (Zhou et al., CVPR 2019): (, 6) — continuous representation - Quaternions: (, 4) in (w, x, y, z) scalar-first convention - Axis-angle: (*, 3) — rotation axis scaled by rotation angle in radians

Convention note: Euler angles in BVH files use intrinsic rotations with pre-multiplication: R = R_first @ R_second @ R_third where the order comes from the joint's rot_channels (e.g., ['Z','Y','X']). Angles are in degrees in BVH files, but most functions here work in radians unless stated otherwise.

euler_to_rotmat(angles: npt.ArrayLike, order: Union[str, Sequence[str]], degrees: bool = False) -> npt.NDArray[np.float64]

Convert Euler angles to rotation matrices (batch).

Parameters:

Name Type Description Default
angles array_like, shape (*, 3) or (*, J, 3)

Euler angles. Each row is (angle1, angle2, angle3) following the axis order given by order. When order is a per-joint sequence of length J, the second-to-last axis is the joint axis.

required
order str or sequence of strings
  • 'ZYX' or ['Z', 'Y', 'X'] — single global order applied to every entry. R = R1 @ R2 @ R3 (intrinsic, pre-multiplied).
  • ['ZYX', 'ZYX', 'ZXY', ...] — per-joint orders, one entry per joint along axis -2 of angles. Input shape must satisfy angles.shape[-2] == len(order). Joints sharing an order are grouped so the rotation math vectorizes inside each group.
required
degrees bool

If True, Euler angles are in degrees. Default False (radians).

False

Returns:

Name Type Description
R ndarray, shape (*, 3, 3) or (*, J, 3, 3)

Rotation matrices, one per input entry.

rotmat_to_euler(R: npt.ArrayLike, order: Union[str, Sequence[str]], degrees: bool = False) -> npt.NDArray[np.float64]

Convert rotation matrices to Euler angles (batch).

Uses the convention of intrinsic rotations with pre-multiplication. Handles gimbal lock by setting the third angle to 0.

Parameters:

Name Type Description Default
R array_like, shape (*, 3, 3) or (*, J, 3, 3)

Rotation matrices. When order is a per-joint sequence of length J, the third-to-last axis is the joint axis.

required
order str or sequence of strings
  • 'ZYX' or ['Z', 'Y', 'X'] — single global order.
  • ['ZYX', 'ZYX', ...] — per-joint orders, one entry per joint along axis -3 of R. Must satisfy R.shape[-3] == len(order).
required
degrees bool

If True, Euler angles are in degrees. Default False (radians).

False

Returns:

Name Type Description
angles ndarray, shape (*, 3) or (*, J, 3)

Euler angles in the specified order.

rotmat_to_rot6d(R: npt.ArrayLike) -> npt.NDArray[np.float64]

Convert rotation matrices to 6D representation.

The 6D representation consists of the first two columns of the rotation matrix, concatenated into a 6-vector.

Parameters:

Name Type Description Default
R array_like, shape (*, 3, 3)

Rotation matrices.

required

Returns:

Name Type Description
rot6d ndarray, shape (*, 6)

6D rotation vectors [col0 | col1].

rot6d_to_rotmat(rot6d: npt.ArrayLike) -> npt.NDArray[np.float64]

Convert 6D rotation representation to rotation matrices using Gram-Schmidt orthogonalization (Zhou et al., CVPR 2019).

Parameters:

Name Type Description Default
rot6d array_like, shape (*, 6)

6D rotation vectors [a1 | a2] where a1 and a2 are 3-vectors.

required

Returns:

Name Type Description
R ndarray, shape (*, 3, 3)

Rotation matrices (proper rotations, det = +1).

euler_to_rot6d(angles: npt.ArrayLike, order: Union[str, Sequence[str]], degrees: bool = False) -> npt.NDArray[np.float64]

Convert Euler angles to 6D rotation representation.

Parameters:

Name Type Description Default
angles array_like, shape (*, 3)

Euler angles.

required
order str or list

Rotation axis order, e.g. 'ZYX'.

required
degrees bool

If True, Euler angles are in degrees. Default False (radians).

False

Returns:

Name Type Description
rot6d ndarray, shape (*, 6)

rot6d_to_euler(rot6d: npt.ArrayLike, order: Union[str, Sequence[str]], degrees: bool = False) -> npt.NDArray[np.float64]

Convert 6D rotation representation to Euler angles.

Parameters:

Name Type Description Default
rot6d array_like, shape (*, 6)

6D rotation vectors.

required
order str or list

Rotation axis order, e.g. 'ZYX'.

required
degrees bool

If True, Euler angles are in degrees. Default False (radians).

False

Returns:

Name Type Description
angles ndarray, shape (*, 3)

rotmat_to_quat(R: npt.ArrayLike) -> npt.NDArray[np.float64]

Convert rotation matrices to quaternions (batch).

Uses the Shepperd method for numerical stability.

Parameters:

Name Type Description Default
R array_like, shape (*, 3, 3)

Rotation matrices.

required

Returns:

Name Type Description
q ndarray, shape (*, 4)

Unit quaternions in (w, x, y, z) scalar-first convention.

quat_to_rotmat(q: npt.ArrayLike) -> npt.NDArray[np.float64]

Convert quaternions to rotation matrices (batch).

Parameters:

Name Type Description Default
q array_like, shape (*, 4)

Quaternions in (w, x, y, z) scalar-first convention. Need not be unit quaternions (will be normalized).

required

Returns:

Name Type Description
R ndarray, shape (*, 3, 3)

Rotation matrices.

euler_to_quat(angles: npt.ArrayLike, order: Union[str, Sequence[str]], degrees: bool = False) -> npt.NDArray[np.float64]

Convert Euler angles to quaternions.

Parameters:

Name Type Description Default
angles array_like, shape (*, 3)

Euler angles.

required
order str or list, e.g. 'ZYX'

Rotation axis order.

required
degrees bool

If True, Euler angles are in degrees. Default False (radians).

False

Returns:

Name Type Description
q ndarray, shape (*, 4)

Quaternions (w, x, y, z).

quat_to_euler(q: npt.ArrayLike, order: Union[str, Sequence[str]], degrees: bool = False) -> npt.NDArray[np.float64]

Convert quaternions to Euler angles.

Parameters:

Name Type Description Default
q array_like, shape (*, 4)

Quaternions (w, x, y, z).

required
order str or list, e.g. 'ZYX'

Rotation axis order.

required
degrees bool

If True, Euler angles are in degrees. Default False (radians).

False

Returns:

Name Type Description
angles ndarray, shape (*, 3)

Euler angles.

rotmat_to_axisangle(R: npt.ArrayLike) -> npt.NDArray[np.float64]

Convert rotation matrices to axis-angle representation (batch).

The axis-angle vector is the unit rotation axis scaled by the rotation angle (in radians). For the identity rotation the zero vector is returned.

Uses the logarithmic map: angle = arccos((trace(R)-1)/2), axis from the skew-symmetric part of R. The 180° case is handled via the eigenvector of R corresponding to eigenvalue 1.

Parameters:

Name Type Description Default
R array_like, shape (*, 3, 3)

Rotation matrices.

required

Returns:

Name Type Description
aa ndarray, shape (*, 3)

Axis-angle vectors (axis × angle_radians).

axisangle_to_rotmat(aa: npt.ArrayLike) -> npt.NDArray[np.float64]

Convert axis-angle vectors to rotation matrices using Rodrigues' formula (batch).

Parameters:

Name Type Description Default
aa array_like, shape (*, 3)

Axis-angle vectors (axis × angle_radians). Zero vector maps to identity.

required

Returns:

Name Type Description
R ndarray, shape (*, 3, 3)

Rotation matrices.

euler_to_axisangle(angles: npt.ArrayLike, order: Union[str, Sequence[str]], degrees: bool = False) -> npt.NDArray[np.float64]

Convert Euler angles to axis-angle vectors.

Parameters:

Name Type Description Default
angles array_like, shape (*, 3)

Euler angles.

required
order str or list, e.g. 'ZYX'

Rotation axis order.

required
degrees bool

If True, Euler angles are in degrees. Default False (radians).

False

Returns:

Name Type Description
aa ndarray, shape (*, 3)

Axis-angle vectors (axis × angle_radians).

axisangle_to_euler(aa: npt.ArrayLike, order: Union[str, Sequence[str]], degrees: bool = False) -> npt.NDArray[np.float64]

Convert axis-angle vectors to Euler angles.

Parameters:

Name Type Description Default
aa array_like, shape (*, 3)

Axis-angle vectors (axis × angle_radians).

required
order str or list, e.g. 'ZYX'

Rotation axis order.

required
degrees bool

If True, Euler angles are in degrees. Default False (radians).

False

Returns:

Name Type Description
angles ndarray, shape (*, 3)

Euler angles.

quat_slerp(q1: npt.ArrayLike, q2: npt.ArrayLike, t: float | npt.ArrayLike) -> npt.NDArray[np.float64]

Spherical linear interpolation between quaternions.

Parameters:

Name Type Description Default
q1 array_like, shape (*, 4)

Start quaternions (w, x, y, z).

required
q2 array_like, shape (*, 4)

End quaternions (w, x, y, z).

required
t float or array_like

Interpolation parameter(s) in [0, 1].

required

Returns:

Name Type Description
q ndarray, shape (*, 4)

Interpolated unit quaternions.

convert(data: npt.ArrayLike, from_repr: str, to_repr: str, *, order: Union[str, Sequence[str], None] = None, degrees: bool = False) -> npt.NDArray[np.float64]

Convert rotation data between representations via a string alias.

Pivots through rotation matrices internally, so every pair of representations is reachable. When from_repr or to_repr is "euler", the order argument is required (and accepts the same single-string / per-joint-sequence forms as :func:euler_to_rotmat).

Parameters:

Name Type Description Default
data array_like

Input data. Shape depends on from_repr — see :data:REPRESENTATION_CHANNELS for the channel count.

required
from_repr str

One of "euler", "rotmat", "6d", "quaternion", "axisangle".

required
to_repr str

One of "euler", "rotmat", "6d", "quaternion", "axisangle".

required
order str or sequence of strings

Euler rotation order(s). Required when from_repr == "euler" or to_repr == "euler"; ignored otherwise.

None
degrees bool

Interpret/emit Euler angles in degrees (default False). Ignored when neither side is Euler.

False

Returns:

Type Description
ndarray

Converted data. Shape depends on to_repr.