Rotation2d
Represents a 2D rotation using the unit complex number representation.
A rotation in 2D can be represented as a unit complex number \(z = \cos\theta + i\sin\theta\), where \(\theta\) is the angle of rotation. This representation is stored as the pair (real, imag) = \((\cos\theta, \sin\theta)\).
Why Unit Complex Numbers?
This representation has several advantages:
Efficient composition: Multiplying two rotations \(z_1 \cdot z_2\) composes them
No gimbal lock: Unlike Euler angles, no singularities
Numerically stable: No wrap-around issues at \(2\pi\)
Direct vector transformation: Rotating a vector is a simple complex multiplication
Mathematical Operations
Composition (multiplication): \((\cos\theta_1, \sin\theta_1) \cdot (\cos\theta_2, \sin\theta_2) = (\cos(\theta_1+\theta_2), \sin(\theta_1+\theta_2))\)
Inverse (conjugate): \((\cos\theta, \sin\theta)^{-1} = (\cos\theta, -\sin\theta)\)
Vector rotation: To rotate a vector \((x, y)\) by angle \(\theta\): \((x', y') = (\cos\theta \cdot x - \sin\theta \cdot y, \sin\theta \cdot x + \cos\theta \cdot y)\)
Example Usage
// Create a 90-degree rotation
val rot90 = Rotation2d.exp(Math.PI / 2)
// Create from an Angle
val rot = Rotation2d.fromAngle(45.0.degrees)
// Compose rotations
val composed = rot90 * rot90 // 180-degree rotation
// Rotate a vector
val v = Vector2d(1.0.inches, 0.0.inches)
val rotated = rot90 * v // Results in approximately (0, 1)
// Get angle back
val angle = rot90.log() // π/2 radiansProperties
Functions
Computes the inverse (opposite) rotation.
Linear interpolation (lerp) toward another rotation using spherical linear interpolation (SLERP).
Computes the relative angle from another rotation to this rotation.
Adds an angle (in radians) to this rotation.
Rotates a pose velocity by this rotation.
Composes two rotations.
Rotates a vector by this rotation.
Converts this rotation to a unit vector.