pyquaternion Documentation

repository·master·Indexed 18 days ago

https://github.com/kieranwynn/pyquaternion

A Python library for quaternion representation, manipulation, 3D animation, and geometry. It provides tools for creating quaternions from axes, angles, scalars, or rotation matrices, as well as methods for rotating 3D vectors, chaining rotations, and performing spherical linear interpolation (slerp). The library includes support for Riemannian manifold operations (Exp and Log maps), distance calculations, and quaternion integration and derivatives. Designed for Python 2.7+ and 3.0+, it requires Numpy for array and matrix representation.

Tokens
7K
Snippets
32
Records
32
Agent score
13%

What's inside pyquaternion

  1. Basic usage of Quaternion for rotation and interpolation

    master

    To use pyquaternion, import the Quaternion class. You can create quaternions to represent rotations, rotate vectors using the .rotate() method, and chain rotations together using the * operator (note: quaternions are multiplied in reverse order of rotation).

    pyquaternion assumes a right-handed coordinate system compatible with East-North-Up and North-East-Down conventions.

    For smooth transitions between orientations, use Quaternion.intermediates() to generate an iterator of intermediate quaternions for interpolation.

    from pyquaternion import Quaternion
    import numpy
    
    # Create a rotation of pi radians about the X axis
    my_quaternion = Quaternion(axis=[1, 0, 0], angle=3.14159265)
    
    # Rotate a vector
    v = numpy.array([0., 0., 1.])
    v_prime = my_quaternion.rotate(v)
    
    # Chain rotations (q2 * q1 applies q1 then q2)
    q1 = Quaternion(axis=[1, 0, 0], angle=3.14159265)
    q2 = Quaternion(axis=[0, 1, 0], angle=3.14159265 / 2)
    q3 = q2 * q1
    
    # Interpolation
    q0 = Quaternion(axis=[1, 1, 1], angle=0.0)
    q1 = Quaternion(axis=[1, 1, 1], angle=2 * 3.14159265 / 3)
    for q in Quaternion.intermediates(q0, q1, 8, include_endpoints=True):
        print(q.rotate(v))
  2. Access rotation axis and angle

    master

    Extract the axis and magnitude of a quaternion rotation:

    Rotation Axis

    • axis: Returns a Numpy unit 3-vector describing the axis of rotation. For a null rotation, this returns [0, 0, 0].
    • get_axis(undefined=[0,0,0]): Allows specifying a custom vector to return if the rotation is a null rotation.

    Rotation Angle

    • angle: Returns the magnitude of rotation in radians (range $-\pi$ to $\pi$).
    • radians: Explicitly returns the angle in radians.
    • degrees: Returns the angle in degrees.

    Note: For unit quaternions, these methods implicitly normalize the object. Discontinuities may occur at 180-degree rotations due to the dual representation of quaternions.

    u = my_quaternion.axis # Unit vector about which rotation occurs
    u = my_quaternion.get_axis(undefined=[1, 0, 0]) # Custom axis for null rotation
    
    theta = my_quaternion.angle # Magnitude in radians
    theta = my_quaternion.radians # Explicit radians
    theta = my_quaternion.degrees # In degrees
  3. Integrate a quaternion over a timestep

    master

    Use the integrate(rate, timestep) method to advance a time-varying quaternion to its value at a timestep in the future. This method modifies the existing Quaternion object in place.

    Parameters:

    • rate: A numpy 3-array (or array-like) describing rotation rates about the global x, y, and z axes.
    • timestep: The interval over which to integrate (e.g., from $T=0$ to $T=timestep$).

    Notes:

    • The method implicitly normalizes the object to a unit quaternion before integration.
    • The solution is a second-order approximation assuming rate is constant over the interval.

    Errors:

    • TypeError: If rate contents cannot be converted to real numbers.
    • ValueError: If rate does not contain exactly 3 elements.
    >>> import numpy as np
    >>> from pyquaternion import Quaternion
    >>> pi = np.pi
    >>> q = Quaternion() # null rotation
    >>> q.integrate([2*pi, 0, 0], 0.25) # Rotate about x at 1 rotation per second
    >>> q == Quaternion(axis=[1, 0, 0], angle=(pi/2))
    True
  4. Rotate a vector using a Quaternion

    master

    To apply a rotation to a 3D vector, use the .rotate() method on a Quaternion instance. The method accepts a list or array representing the vector.

    import pyquaternion
    
    my_quaternion = pyquaternion.Quaternion(axis=[0, 1, 0], degrees=90)
    my_vector = [0, 0, 4]
    
    my_rotated_vector = my_quaternion.rotate(my_vector)
    print(my_rotated_vector) # Output: [4.0, 0.0, 0.0]
  5. Calculate the norm and check if a Quaternion is a unit quaternion

    master

    The norm (or magnitude) is the L2 norm of the quaternion 4-vector. For a unit quaternion (versor), this should be 1.0.

    Use is_unit(tolerance=1e-14) to check if the quaternion is a unit quaternion within a specified absolute tolerance.

    my_quaternion = Quaternion.random()
    
    # Get the L2 norm
    n = my_quaternion.norm
    m = my_quaternion.magnitude
    
    # Check if it is a unit quaternion
    check = my_quaternion.is_unit(tolerance=1e-14)
  6. Format and represent Quaternions as strings

    master

    Pyquaternion provides several ways to convert a Quaternion to a string:

    • str(q) / print(q): Returns an informal, nicely printable string (e.g., '-0.810 +0.022i -0.563j -0.166k').
    • repr(q): Returns the 'official' string representation, which is a valid Python expression used to recreate the object.
    • format(q, format_spec): Allows custom formatting using the Python format specification mini-language (similar to float formatting).
    # Informal string
    print(f"{my_quaternion}")
    
    # Official representation
    print(repr(my_quaternion))
    
    # Custom formatting
    print("{:+.6}.format(my_quaternion)")
  7. Initialize a Quaternion using default, copy, or random methods

    master

    Default

    Quaternion() creates a unit quaternion 1 + 0i + 0j + 0k (a null rotation).

    Copy

    Quaternion(other) clones an existing Quaternion instance. Raises TypeError if other is not a Quaternion.

    Random

    Quaternion.random() is a class method that returns a quaternion representing a rotation chosen from a uniform distribution across the rotation space.

    # Default
    q1 = Quaternion()
    
    # Copy
    q2 = Quaternion(q1)
    
    # Random
    q3 = Quaternion.random()
  8. Create a Quaternion

    master

    Use pyquaternion.Quaternion to represent rotations. You can define a rotation using an axis and either an angle in degrees or radians.

    Common parameters:

    • axis: The axis of rotation (e.g., [0, 1, 0]).
    • degrees: The rotation angle in degrees (if used, angle should not be provided).
    • angle: The rotation angle in radians.
    import pyquaternion
    
    # Create a rotation of 90 degrees about the positive y axis
    my_quaternion = pyquaternion.Quaternion(axis=[0, 1, 0], degrees=90)
    
    # Create a null rotation (no rotation)
    null_quaternion = pyquaternion.Quaternion(axis=[0, 1, 0], angle=0)
  9. Convert quaternion to rotation or transformation matrices

    master

    Convert a unit quaternion into its matrix equivalents:

    • rotation_matrix: Returns a 3x3 orthogonal rotation matrix as a 3x3 Numpy array.
    • transformation_matrix: Returns a 4x4 homogeneous transformation matrix as a 4x4 Numpy array.

    Note: Both methods implicitly normalize the quaternion to unit length. Be aware that different quaternion values (e.g., $q$ and $-q$) can represent the same rotation, which may cause discontinuities in conversion sequences.

    R = my_quaternion.rotation_matrix 1 # 3x3 rotation matrix
    T = my_quaternion.transformation_matrix # 4x4 transformation matrix
  10. Evaluate the truthiness of a Quaternion

    master

    A Quaternion object evaluates to False in a logical context only if it is the zero quaternion (Quaternion(0.0, 0.0, 0.0, 0.0)). Otherwise, it evaluates to True.

    Warning: This does not evaluate whether the quaternion represents a null rotation. A unit quaternion representing no rotation (e.g., Quaternion(1.0, 0.0, 0.0, 0.0)) will evaluate to True.

    # Zero quaternion is False
    print(bool(Quaternion(0, 0, 0, 0))) # False
    
    # Identity rotation (null rotation) is True
    print(bool(Quaternion(1, 0, 0, 0))) # True