CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-numpy-quaternion

Add a quaternion dtype to NumPy with comprehensive quaternion arithmetic and mathematical operations

Pending
Overview
Eval results
Files

rotation-conversions.mddocs/

Rotation Conversions

Convert between quaternions and various rotation representations including rotation matrices, axis-angle vectors, Euler angles, and spherical coordinates. These functions enable seamless integration with other rotation libraries and mathematical frameworks.

Capabilities

Rotation Matrix Conversions

Convert between quaternions and 3x3 rotation matrices.

def as_rotation_matrix(q):
    """
    Convert quaternions to 3x3 rotation matrices.
    
    Args:
        q (quaternion or quaternion array): Input quaternions (need not be normalized)
        
    Returns:
        ndarray: Rotation matrices with shape q.shape + (3, 3)
        
    Raises:
        ZeroDivisionError: If any input quaternion has zero norm
        
    Notes:
        For quaternion q and vector v, the rotated vector is:
        rotated_v = rotation_matrix @ v.vec
        where v.vec is the 3D vector part of quaternion v.
    """

def from_rotation_matrix(rot, nonorthogonal=True):
    """
    Convert 3x3 rotation matrices to unit quaternions.
    
    Args:
        rot (array_like): Rotation matrices with shape (..., 3, 3)
        nonorthogonal (bool): Use robust algorithm for non-orthogonal matrices (default: True)
        
    Returns:
        quaternion array: Unit quaternions with shape rot.shape[:-2]
        
    Raises:
        LinAlgError: If eigenvalue solutions do not converge (scipy algorithm)
        
    Notes:
        Uses Bar-Itzhack algorithm (scipy.linalg) when nonorthogonal=True for robustness.
        Falls back to Markley algorithm when scipy unavailable or nonorthogonal=False.
    """

Vector Rotation

Apply quaternion rotations to 3D vectors efficiently.

def rotate_vectors(R, v, axis=-1):
    """
    Rotate 3D vectors using quaternions.
    
    Args:
        R (quaternion array): Rotation quaternions
        v (array_like): 3D vectors to rotate
        axis (int): Axis of v containing vector components (must have length 3)
        
    Returns:
        ndarray: Rotated vectors with shape R.shape + v.shape
        
    Notes:
        More efficient than individual quaternion products when rotating
        multiple vectors with the same quaternion. Uses matrix multiplication
        internally for vectorized operations.
    """

Axis-Angle Representations

Convert between quaternions and axis-angle (rotation vector) representations.

def as_rotation_vector(q):
    """
    Convert quaternions to axis-angle representation.
    
    Args:
        q (quaternion or quaternion array): Input quaternions (need not be normalized)
        
    Returns:
        ndarray: Rotation vectors with shape q.shape + (3,)
        
    Notes:
        Each vector represents rotation axis with magnitude equal to rotation
        angle in radians. No error for zero-norm quaternions (produces NaN).
    """

def from_rotation_vector(rot):
    """
    Convert axis-angle vectors to unit quaternions.
    
    Args:
        rot (array_like): Rotation vectors with shape (..., 3)
        
    Returns:
        quaternion array: Unit quaternions with shape rot.shape[:-1]
        
    Notes:
        Vector magnitude is rotation angle in radians, direction is rotation axis.
        Uses quaternion exponential for conversion.
    """

Euler Angle Conversions

Convert between quaternions and Euler angles with caveats about Euler angle limitations.

def as_euler_angles(q):
    """
    Convert quaternions to Euler angles (ZYZ convention).
    
    Args:
        q (quaternion or quaternion array): Input quaternions (need not be normalized)
        
    Returns:
        ndarray: Euler angles (alpha, beta, gamma) with shape q.shape + (3,)
        
    Raises:
        AllHell: Metaphorically, if you use Euler angles when you shouldn't
        
    Notes:
        Uses ZYZ convention: R = exp(alpha*z/2) * exp(beta*y/2) * exp(gamma*z/2)
        Angles in radians. Euler angles have singularities and are generally
        discouraged. See package documentation warnings about Euler angles.
    """

def from_euler_angles(alpha_beta_gamma, beta=None, gamma=None):
    """
    Create quaternions from Euler angles (ZYZ convention).
    
    Args:
        alpha_beta_gamma (array_like): Euler angles array with last dim 3, or alpha values
        beta (array_like, optional): Beta angles if alpha_beta_gamma contains only alpha  
        gamma (array_like, optional): Gamma angles if alpha_beta_gamma contains only alpha
        
    Returns:
        quaternion array: Quaternions from Euler angle inputs
        
    Notes:
        Uses ZYZ convention with angles in radians. Inputs must broadcast together.
        Strongly consider using other rotation representations instead.
    """

Spherical Coordinate Conversions

Convert between quaternions and spherical coordinates (theta, phi).

def as_spherical_coords(q):
    """
    Convert quaternions to spherical coordinates.
    
    Args:
        q (quaternion or quaternion array): Input quaternions (must be nonzero)
        
    Returns:
        ndarray: Spherical coordinates (theta, phi) with shape q.shape + (2,)
        
    Notes:
        Returns point on sphere where quaternion rotates z-axis. Loses some
        information compared to full quaternion representation.
    """

def from_spherical_coords(theta_phi, phi=None):
    """
    Create quaternions from spherical coordinates.
    
    Args:
        theta_phi (array_like): Coordinate array with last dim 2, or theta values
        phi (array_like, optional): Phi coordinates if theta_phi contains only theta
        
    Returns:
        quaternion array: Quaternions rotating z-axis to specified coordinates
        
    Notes:
        Creates quaternion R = exp(phi*z/2) * exp(theta*y/2). Angles in radians.
        Rotates z-axis to given spherical coordinates and x,y to local tangent basis.
    """

Usage Examples

import quaternion
import numpy as np

# Create sample quaternions
q = quaternion.quaternion(1, 0, 0, 0)  # Identity
q_rot = quaternion.from_euler_angles(0, np.pi/4, 0)  # 45° rotation around y

# Convert to rotation matrix
R = quaternion.as_rotation_matrix(q_rot)
print(f"Rotation matrix shape: {R.shape}")  # (3, 3)

# Rotate vectors
vectors = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])  # Identity matrix columns
rotated = quaternion.rotate_vectors(q_rot, vectors.T, axis=0)
print(f"Rotated vectors shape: {rotated.shape}")

# Convert to axis-angle representation  
axis_angle = quaternion.as_rotation_vector(q_rot)
print(f"Axis-angle vector: {axis_angle}")

# Round-trip conversion
q_recovered = quaternion.from_rotation_vector(axis_angle)
print(f"Original close to recovered: {quaternion.allclose(q_rot, q_recovered)}")

# Convert to spherical coordinates
theta_phi = quaternion.as_spherical_coords(q_rot)
print(f"Spherical coords: theta={theta_phi[0]:.3f}, phi={theta_phi[1]:.3f}")

# Create from rotation matrix
R_input = np.array([[0, 1, 0], [-1, 0, 0], [0, 0, 1]])  # 90° rotation around z
q_from_matrix = quaternion.from_rotation_matrix(R_input)
print(f"Quaternion from matrix: {q_from_matrix}")

# Demonstrate quaternion-matrix equivalence
test_vector = np.array([1, 0, 0])
rotated_by_q = quaternion.as_vector_part(q_from_matrix * quaternion.from_vector_part(test_vector) * q_from_matrix.conjugate())
rotated_by_matrix = R_input @ test_vector
print(f"Quaternion rotation: {rotated_by_q}")
print(f"Matrix rotation: {rotated_by_matrix}")
print(f"Results match: {np.allclose(rotated_by_q, rotated_by_matrix)}")

Install with Tessl CLI

npx tessl i tessl/pypi-numpy-quaternion

docs

core-operations.md

index.md

rotation-conversions.md

time-series.md

tile.json