viva_math/quaternion

Unit quaternions for 3-D rotation.

A quaternion w + xi + yj + zk extends complex numbers to four dimensions. Unit quaternions provide a numerically stable, gimbal-lock-free representation of 3-D rotation that interpolates smoothly via SLERP.

Conventions

When to use

Types

pub type Quaternion {
  Quaternion(w: Float, x: Float, y: Float, z: Float)
}

Constructors

  • Quaternion(w: Float, x: Float, y: Float, z: Float)

Values

pub fn conjugate(q: Quaternion) -> Quaternion

Quaternion conjugate (w, -x, -y, -z). For unit quaternions this is the inverse.

pub fn dot(a: Quaternion, b: Quaternion) -> Float

Quaternion-quaternion dot product (treating each as a 4-vector).

pub fn from_axis_angle(
  axis: vector.Vec3,
  theta: Float,
) -> Quaternion

Build a unit quaternion from an axis-angle representation.

axis need not be normalised — this function normalises it. theta is the rotation angle in radians.

pub fn identity() -> Quaternion

The identity quaternion (no rotation).

pub fn inverse(q: Quaternion) -> Quaternion

Inverse conj(q) / |q|². For unit quaternions equals the conjugate.

pub fn is_close(a: Quaternion, b: Quaternion, tol: Float) -> Bool

Approximate equality up to a tolerance.

pub fn magnitude(q: Quaternion) -> Float

Magnitude / Euclidean norm of a quaternion.

pub fn magnitude_squared(q: Quaternion) -> Float

Squared magnitude (cheaper than magnitude when only comparison is needed).

pub fn mul(a: Quaternion, b: Quaternion) -> Quaternion

Hamilton product a · b. Non-commutative.

pub fn nlerp(
  a: Quaternion,
  b: Quaternion,
  t: Float,
) -> Quaternion

Linear interpolation (LERP) between two quaternions, then normalise.

Cheaper than SLERP but yields non-uniform angular speed. Acceptable for small angular distances (< ~30°). For large or critical interpolations use slerp.

pub fn normalize(q: Quaternion) -> Quaternion

Normalise to unit length. Returns identity if the input is zero.

pub fn raw(w: Float, x: Float, y: Float, z: Float) -> Quaternion

Build a quaternion from raw components without normalisation.

pub fn rotate(q: Quaternion, v: vector.Vec3) -> vector.Vec3

Rotate a 3-D vector v by unit quaternion q.

Computes q · v · q⁻¹ using the optimised Rodrigues-style formula that skips two of the quaternion products.

pub fn slerp(
  a: Quaternion,
  b: Quaternion,
  t: Float,
) -> Quaternion

Spherical linear interpolation (SLERP) — constant angular velocity.

Falls back to nlerp when the angle between the quaternions is very small (sin(θ) < 1e-6), where SLERP becomes numerically unstable.

pub fn to_axis_angle(q: Quaternion) -> #(vector.Vec3, Float)

Quaternion → axis-angle. Returns (axis, angle) with axis unit-length. When the rotation is identity returns (z-axis, 0) by convention.

Search Document