numpy-quaternion
numpy-quaternion extends NumPy by adding a quaternion dtype, enabling efficient array operations and mathematical functions for handling quaternions. This library is crucial for applications involving 3D rotations, such as animation, robotics, and aerospace. It is actively maintained with frequent releases, with the current version being 2024.0.13.
Warnings
- gotcha The library strongly discourages the use of Euler angles for rotations due to issues like gimbal lock and reduced accuracy. Quaternions are presented as a superior alternative.
- gotcha When performing `numpy.copy()` on an array of `quaternion` dtype, the resulting array might lose its quaternionic nature and become a plain array of floats, leading to incorrect behavior in subsequent quaternion operations.
- gotcha While `R * v * R.conjugate()` is a mathematically valid way to rotate a pure-vector quaternion `v` by a rotation quaternion `R`, using the `rotate_vectors` function (if available for your specific use case or a utility function in the broader `quaternion` ecosystem) can often be more efficient and numerically accurate.
- breaking Compatibility with NumPy 2.x (released late 2025) may require updates. NumPy 2.0 introduced significant breaking changes to its ABI, Python, and C APIs, which can affect libraries that deeply integrate with NumPy dtypes like `numpy-quaternion`.
Install
-
pip install numpy-quaternion -
conda install -c conda-forge quaternion
Imports
- quaternion
import quaternion import numpy as np
Quickstart
import numpy as np
import quaternion
# Create a quaternion
q_rot = np.quaternion(0.92388, 0, 0.38268, 0) # Example: 45-degree rotation around Y-axis
# Represent a 3D point as a pure-imaginary quaternion
point = np.quaternion(0, 1, 0, 0) # Represents point (1, 0, 0)
# Rotate the point using quaternion multiplication
rotated_point = q_rot * point * q_rot.conjugate()
print(f"Original point: ({point.x}, {point.y}, {point.z})")
print(f"Rotation quaternion: {q_rot}")
print(f"Rotated point: ({rotated_point.x:.3f}, {rotated_point.y:.3f}, {rotated_point.z:.3f})")