CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyglm

OpenGL Mathematics (GLM) library for Python providing comprehensive vector and matrix manipulation capabilities for graphics programming.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

quaternions.mddocs/

Quaternion Operations

Efficient 3D rotation representation using quaternions. Quaternions provide smooth interpolation, avoid gimbal lock, and offer compact storage for rotations in 3D graphics and physics applications.

Capabilities

Quaternion Types

PyGLM provides quaternion types in different precisions for various performance and accuracy requirements.

class quat:
    """
    Single-precision quaternion for 3D rotations.
    Components: w (scalar), x, y, z (vector)
    """
    w: float  # Scalar component
    x: float  # X vector component  
    y: float  # Y vector component
    z: float  # Z vector component
    
    def __init__(self): ...  # Identity quaternion (0, 0, 0, 1)
    def __init__(self, w: float, x: float, y: float, z: float): ...  # From components
    def __init__(self, v: vec3): ...  # From Euler angles
    def __init__(self, m: mat3): ...  # From rotation matrix
    def __init__(self, m: mat4): ...  # From transformation matrix

class dquat:
    """
    Double-precision quaternion for high-accuracy rotations.
    Components: w (scalar), x, y, z (vector)
    """
    w: float  # Scalar component (double precision)
    x: float  # X vector component (double precision)
    y: float  # Y vector component (double precision)  
    z: float  # Z vector component (double precision)
    
    def __init__(self): ...  # Identity quaternion
    def __init__(self, w: float, x: float, y: float, z: float): ...
    def __init__(self, v: vec3): ...  # From Euler angles
    def __init__(self, m: mat3): ...  # From rotation matrix
    def __init__(self, m: mat4): ...  # From transformation matrix

Quaternion Construction

Functions for creating quaternions from various rotation representations.

def angleAxis(angle, axis):
    """
    Create a quaternion from an angle and rotation axis.

    Args:
        angle: Rotation angle in radians
        axis: Rotation axis vector (vec3, should be normalized)

    Returns:
        Quaternion representing the rotation

    Example:
        q = glm.angleAxis(glm.radians(45), glm.vec3(0, 1, 0))  # 45° around Y-axis
    """

def quatLookAt(direction, up):
    """
    Create a quaternion that rotates to look in a specific direction.

    Args:
        direction: Direction to look toward (vec3, will be normalized)
        up: Up vector (vec3, will be normalized)

    Returns:
        Quaternion representing the look-at rotation
    """

def euler(angles):
    """
    Create a quaternion from Euler angles.

    Args:
        angles: Euler angles in radians (vec3: pitch, yaw, roll)

    Returns:
        Quaternion representing the combined rotation

    Example:
        q = glm.euler(glm.vec3(glm.radians(15), glm.radians(30), glm.radians(45)))
    """

Quaternion Operations

Core quaternion mathematics including arithmetic, normalization, and conjugation.

def normalize(q):
    """
    Normalize a quaternion to unit length.

    Args:
        q: Quaternion to normalize

    Returns:
        Normalized quaternion (unit quaternion)

    Note:
        Unit quaternions represent pure rotations
    """

def conjugate(q):
    """
    Calculate the conjugate of a quaternion.

    Args:
        q: Input quaternion

    Returns:
        Conjugate quaternion (negated vector part)

    Note:
        For unit quaternions, conjugate equals inverse
    """

def inverse(q):
    """
    Calculate the inverse of a quaternion.

    Args:
        q: Input quaternion

    Returns:
        Inverse quaternion
    """

def length(q):
    """
    Calculate the length (magnitude) of a quaternion.

    Args:
        q: Input quaternion

    Returns:
        Scalar length of the quaternion
    """

def dot(q1, q2):
    """
    Calculate the dot product of two quaternions.

    Args:
        q1: First quaternion
        q2: Second quaternion

    Returns:
        Scalar dot product
    """

Quaternion Interpolation

Smooth interpolation functions for animation and smooth transitions between rotations.

def slerp(x, y, a):
    """
    Spherical linear interpolation between two quaternions.

    Args:
        x: Start quaternion
        y: End quaternion  
        a: Interpolation factor (0.0 = x, 1.0 = y)

    Returns:
        Interpolated quaternion with constant angular velocity

    Note:
        SLERP provides the shortest rotation path between quaternions
    """

def lerp(x, y, a):
    """
    Linear interpolation between two quaternions.

    Args:
        x: Start quaternion
        y: End quaternion
        a: Interpolation factor (0.0 = x, 1.0 = y)

    Returns:
        Linearly interpolated quaternion (requires normalization)

    Note:
        Faster than SLERP but doesn't maintain constant angular velocity
    """

def mix(x, y, a):
    """
    Alias for lerp - linear interpolation between quaternions.

    Args:
        x: Start quaternion
        y: End quaternion
        a: Interpolation factor

    Returns:
        Linearly interpolated quaternion
    """

Matrix Conversion

Functions for converting between quaternions and rotation matrices.

def mat3_cast(q):
    """
    Convert a quaternion to a 3×3 rotation matrix.

    Args:
        q: Quaternion to convert

    Returns:
        3×3 rotation matrix equivalent to the quaternion

    Example:
        rotation_matrix = glm.mat3_cast(quaternion)
    """

def mat4_cast(q):
    """
    Convert a quaternion to a 4×4 transformation matrix.

    Args:
        q: Quaternion to convert

    Returns:
        4×4 transformation matrix with rotation and identity translation

    Example:
        transform_matrix = glm.mat4_cast(quaternion)
    """

def quat_cast(m):
    """
    Convert a rotation matrix to a quaternion.

    Args:
        m: 3×3 or 4×4 rotation matrix

    Returns:
        Quaternion equivalent to the matrix rotation

    Example:
        quaternion = glm.quat_cast(rotation_matrix)
    """

Euler Angle Conversion

Functions for converting between quaternions and Euler angle representations.

def eulerAngles(q):
    """
    Extract Euler angles from a quaternion.

    Args:
        q: Input quaternion

    Returns:
        vec3 containing Euler angles in radians (pitch, yaw, roll)

    Example:
        angles = glm.eulerAngles(quaternion)
        pitch = angles.x
        yaw = angles.y  
        roll = angles.z
    """

def pitch(q):
    """
    Extract the pitch angle from a quaternion.

    Args:
        q: Input quaternion

    Returns:
        Pitch angle in radians (rotation around X-axis)
    """

def yaw(q):
    """
    Extract the yaw angle from a quaternion.

    Args:
        q: Input quaternion

    Returns:
        Yaw angle in radians (rotation around Y-axis)
    """

def roll(q):
    """
    Extract the roll angle from a quaternion.

    Args:
        q: Input quaternion

    Returns:
        Roll angle in radians (rotation around Z-axis)
    """

def angle(q):
    """
    Extract the rotation angle from a quaternion.

    Args:
        q: Input quaternion

    Returns:
        Rotation angle in radians
    """

def axis(q):
    """
    Extract the rotation axis from a quaternion.

    Args:
        q: Input quaternion

    Returns:
        vec3 representing the normalized rotation axis
    """

Quaternion Arithmetic

All quaternion types support standard arithmetic operations through operator overloading:

  • Addition: q1 + q2 - Component-wise addition
  • Subtraction: q1 - q2 - Component-wise subtraction
  • Multiplication: q1 * q2 - Quaternion multiplication (composition of rotations)
  • Scalar Multiplication: q * scalar - Scale quaternion components
  • Negation: -q - Component-wise negation
  • Equality: q1 == q2, q1 != q2 - Component-wise equality

Usage Examples

from pyglm import glm
import math

# === Basic Quaternion Creation ===

# Identity quaternion (no rotation)
identity_quat = glm.quat()

# From explicit components (w, x, y, z)
explicit_quat = glm.quat(0.707, 0.0, 0.707, 0.0)  # 90° around Y-axis

# From angle and axis
angle = glm.radians(45)
axis = glm.vec3(0, 1, 0)  # Y-axis
angle_axis_quat = glm.angleAxis(angle, axis)

# From Euler angles (pitch, yaw, roll)
euler_angles = glm.vec3(glm.radians(15), glm.radians(30), glm.radians(45))
euler_quat = glm.euler(euler_angles)

# === Quaternion Operations ===

# Normalize quaternion (essential for rotations)
normalized_quat = glm.normalize(angle_axis_quat)

# Quaternion multiplication (combines rotations)
q1 = glm.angleAxis(glm.radians(30), glm.vec3(1, 0, 0))  # 30° around X
q2 = glm.angleAxis(glm.radians(45), glm.vec3(0, 1, 0))  # 45° around Y
combined_rotation = q2 * q1  # Apply q1 first, then q2

# Conjugate (inverse for unit quaternions)
inverse_rotation = glm.conjugate(normalized_quat)

# === Quaternion Interpolation for Animation ===

# SLERP for smooth rotation animation
start_quat = glm.angleAxis(glm.radians(0), glm.vec3(0, 1, 0))
end_quat = glm.angleAxis(glm.radians(90), glm.vec3(0, 1, 0))

# Animate from 0° to 90° over time
animation_time = 0.5  # 50% through animation
interpolated_quat = glm.slerp(start_quat, end_quat, animation_time)

# === Matrix Conversion ===

# Convert quaternion to rotation matrix
rotation_quat = glm.angleAxis(glm.radians(45), glm.vec3(0, 0, 1))
rotation_matrix_3x3 = glm.mat3_cast(rotation_quat)
rotation_matrix_4x4 = glm.mat4_cast(rotation_quat)

# Convert matrix back to quaternion
recovered_quat = glm.quat_cast(rotation_matrix_3x3)

# === Euler Angle Extraction ===

# Get Euler angles from quaternion
quaternion = glm.angleAxis(glm.radians(45), glm.vec3(1, 1, 0))
euler_angles = glm.eulerAngles(quaternion)

pitch_degrees = glm.degrees(euler_angles.x)
yaw_degrees = glm.degrees(euler_angles.y)  
roll_degrees = glm.degrees(euler_angles.z)

# Extract individual components
pitch_rad = glm.pitch(quaternion)
yaw_rad = glm.yaw(quaternion)
roll_rad = glm.roll(quaternion)

# Extract angle and axis
rotation_angle = glm.angle(quaternion)
rotation_axis = glm.axis(quaternion)

# === Practical 3D Graphics Example ===

# Create a first-person camera rotation system
class FirstPersonCamera:
    def __init__(self):
        self.orientation = glm.quat()  # Identity quaternion
        self.sensitivity = 0.002  # Mouse sensitivity
    
    def rotate(self, mouse_delta_x, mouse_delta_y):
        # Yaw rotation (around world Y-axis)
        yaw_rotation = glm.angleAxis(-mouse_delta_x * self.sensitivity, glm.vec3(0, 1, 0))
        
        # Pitch rotation (around local X-axis)
        pitch_rotation = glm.angleAxis(-mouse_delta_y * self.sensitivity, glm.vec3(1, 0, 0))
        
        # Apply rotations: pitch first (local), then yaw (world)
        self.orientation = yaw_rotation * self.orientation * pitch_rotation
        self.orientation = glm.normalize(self.orientation)
    
    def get_view_matrix(self, position):
        # Convert quaternion to rotation matrix
        rotation_matrix = glm.mat4_cast(glm.conjugate(self.orientation))
        
        # Apply translation
        view_matrix = glm.translate(rotation_matrix, -position)
        return view_matrix

# Usage
camera = FirstPersonCamera()
camera.rotate(0.1, 0.05)  # Simulate mouse movement
view_matrix = camera.get_view_matrix(glm.vec3(0, 2, 5))

# === Character Animation Example ===

# Smooth rotation between two orientations
old_facing = glm.angleAxis(glm.radians(0), glm.vec3(0, 1, 0))    # North
new_facing = glm.angleAxis(glm.radians(90), glm.vec3(0, 1, 0))   # East

# Smoothly rotate character over 2 seconds
animation_duration = 2.0
current_time = 0.75  # 0.75 seconds into animation
t = current_time / animation_duration

current_facing = glm.slerp(old_facing, new_facing, t)
character_transform = glm.mat4_cast(current_facing)

# === Look-At Quaternion ===

target_position = glm.vec3(10, 0, 0)
current_position = glm.vec3(0, 0, 0)
up_vector = glm.vec3(0, 1, 0)

look_direction = glm.normalize(target_position - current_position)
look_at_quat = glm.quatLookAt(look_direction, up_vector)
look_at_matrix = glm.mat4_cast(look_at_quat)

Quaternion Best Practices

  1. Always normalize quaternions used for rotations to ensure they remain unit quaternions
  2. Use SLERP for smooth animation between rotations to maintain constant angular velocity
  3. Prefer quaternion multiplication over Euler angle arithmetic to avoid gimbal lock
  4. Store orientations as quaternions and convert to matrices only when needed for rendering
  5. Use conjugate instead of inverse for unit quaternions (more efficient)
  6. Be consistent with rotation order when converting between Euler angles and quaternions

Install with Tessl CLI

npx tessl i tessl/pypi-pyglm

docs

extensions.md

index.md

math-functions.md

matrices.md

quaternions.md

random-noise.md

transformations.md

utilities.md

vectors.md

tile.json