Skip to main content

Quaternion

Struct Quaternion 

Source
pub struct Quaternion<T> {
    pub w: T,
    pub x: T,
    pub y: T,
    pub z: T,
}
Expand description

Unit quaternion for 3D rotations.

Scalar-first Hamilton convention: q = w + xi + yj + zk stored as [w, x, y, z]. Hamilton product satisfies ij = k.

§Rotation convention

q * v computes the rotated vector q v q⁻¹. When used for attitude representation, q is the source-to-body (e.g. inertial-to-body) quaternion: v_body = q * v_inertial.

Composition follows right-to-left order: q_total = q2 * q1 applies q1 first, then q2.

§Example

use numeris::{Quaternion, Vector3};

// Create a 90° rotation about the Z axis
let q = Quaternion::from_axis_angle(
    Vector3::from_array([0.0, 0.0, 1.0]),
    std::f64::consts::FRAC_PI_2,
);

// Rotate the X unit vector → should become Y
let v = Vector3::from_array([1.0, 0.0, 0.0]);
let rotated = q * v;
assert!((rotated[0]).abs() < 1e-12);
assert!((rotated[1] - 1.0).abs() < 1e-12);

Fields§

§w: T§x: T§y: T§z: T

Implementations§

Source§

impl<T: FloatScalar> Quaternion<T>

Source

pub fn new(w: T, x: T, y: T, z: T) -> Self

Create a quaternion from components.

Source

pub fn identity() -> Self

Identity quaternion (no rotation).

Source

pub fn rotx(angle: T) -> Self

Rotation about the X axis by angle radians.

Source

pub fn roty(angle: T) -> Self

Rotation about the Y axis by angle radians.

Source

pub fn rotz(angle: T) -> Self

Rotation about the Z axis by angle radians.

Source

pub fn from_axis_angle(axis: Vector3<T>, angle: T) -> Self

Create from an axis (must be unit length) and angle in radians.

use numeris::{Quaternion, Vector3};
let q = Quaternion::from_axis_angle(
    Vector3::from_array([0.0_f64, 1.0, 0.0]),
    1.0,
);
assert!((q.norm() - 1.0).abs() < 1e-12);
Source

pub fn from_rotation_matrix(m: &Matrix<T, 3, 3>) -> Self

Create from a 3×3 rotation matrix using Shepperd’s method.

Numerically stable for all rotation angles.

Source

pub fn from_euler(roll: T, pitch: T, yaw: T) -> Self

Create from Euler angles (ZYX intrinsic convention).

Arguments: roll (X), pitch (Y), yaw (Z), all in radians.

Source§

impl<T: FloatScalar> Quaternion<T>

Source

pub fn conjugate(&self) -> Self

Conjugate: (w, -x, -y, -z).

Source

pub fn norm_squared(&self) -> T

Squared norm: w² + x² + y² + z².

Source

pub fn norm(&self) -> T

Norm (magnitude).

Source

pub fn normalize(&self) -> Self

Normalize to unit quaternion.

Source

pub fn inverse(&self) -> Self

Inverse: conjugate / norm².

For unit quaternions this equals the conjugate.

Source

pub fn dot(&self, rhs: &Self) -> T

Dot product of two quaternions.

Source§

impl<T: FloatScalar> Quaternion<T>

Source

pub fn to_rotation_matrix(&self) -> Matrix<T, 3, 3>

Convert to a 3×3 rotation matrix.

use numeris::{Quaternion, Matrix, Vector3};
let q = Quaternion::from_axis_angle(
    Vector3::from_array([0.0_f64, 1.0, 0.0]),
    0.8,
);
let m = q.to_rotation_matrix();
// Rotation via quaternion and matrix should match
let v = Vector3::from_array([1.0, 0.0, 0.0]);
let r_q = q * v;
let r_m = m.vecmul(&v);
assert!((r_q[0] - r_m[0]).abs() < 1e-12);
Source

pub fn to_axis_angle(&self) -> (Vector3<T>, T)

Convert to axis-angle representation.

Returns (axis, angle) where axis is a unit vector and angle is in radians. For identity rotation, returns ([1,0,0], 0).

Source

pub fn to_euler(&self) -> (T, T, T)

Convert to Euler angles (ZYX intrinsic convention).

Returns (roll, pitch, yaw) in radians.

Source§

impl<T: FloatScalar> Quaternion<T>

Source

pub fn slerp(&self, other: &Self, t: T) -> Self

Spherical linear interpolation between self and other.

t = 0 returns self, t = 1 returns other. Automatically takes the short path on the 4-sphere.

use numeris::{Quaternion, Vector3};
use std::f64::consts::FRAC_PI_2;

let a = Quaternion::<f64>::identity();
let b = Quaternion::from_axis_angle(
    Vector3::from_array([0.0, 0.0, 1.0]),
    FRAC_PI_2,
);
let mid = a.slerp(&b, 0.5);
assert!((mid.norm() - 1.0).abs() < 1e-12);
Source§

impl<T: FloatScalar> Quaternion<T>

Source

pub fn from_angular_velocity(omega: &Vector3<T>, dt: T) -> Self

Create a rotation quaternion from angular velocity and time step.

Computes the exact finite rotation δq = exp(½ ω dt) using the axis-angle formula: angle = |ω| · dt, axis = ω / |ω|.

The returned quaternion represents the rotation that the body undergoes over dt at constant angular velocity omega. To apply it to an existing attitude quaternion, right-multiply: q_new = q ⊗ δq (see propagate).

Source

pub fn derivative(&self, omega: &Vector3<T>) -> Self

Quaternion time derivative for body-frame angular velocity.

Returns q̇ = ½ q ⊗ ω̃ where ω̃ = (0, ωx, ωy, ωz) is the angular velocity as a pure quaternion.

§Convention
  • self is the source-to-body quaternion (e.g. inertial-to-body). It transforms vectors from the source frame into the body frame: v_body = q * v_source.
  • omega is the angular velocity of the body relative to the source frame, expressed in the body frame — this is what a body-mounted gyroscope measures.
  • The right-multiply (q ⊗ ω̃) follows from body-frame rates. If you have rates in the source (inertial) frame instead, use q̇ = ½ ω̃_source ⊗ q (left-multiply).
§Usage

Feed this into an ODE integrator (e.g. RK4, RKTS54). The result is a general quaternion (not unit), so normalize periodically to prevent drift. For constant-rate propagation, use propagate instead.

§Example
use numeris::{Quaternion, Vector3};

// Constant rotation about Z at 1 rad/s
let q = Quaternion::<f64>::identity();
let omega = Vector3::from_array([0.0, 0.0, 1.0]);
let q_dot = q.derivative(&omega);
// q̇ = ½ (1,0,0,0) ⊗ (0,0,0,1) = (0, 0, 0, 0.5)
assert!((q_dot.w).abs() < 1e-12);
assert!((q_dot.z - 0.5).abs() < 1e-12);
Source

pub fn propagate(&self, omega: &Vector3<T>, dt: T) -> Self

Propagate quaternion by body-frame angular velocity over a time step using the exponential map (exact for constant rate).

Computes q_new = q ⊗ δq where δq = exp(½ ω dt) is the exact finite rotation. This is geometrically exact for constant angular velocity over dt and preserves unit norm (up to floating-point rounding). Equivalent to from_angular_velocity composed with the current quaternion.

§Convention

Same as derivative:

  • self is the source-to-body quaternion (e.g. inertial-to-body).
  • omega is the angular velocity of the body relative to the source frame, expressed in the body frame.
  • The delta rotation is right-multiplied (q ⊗ δq) because the rates are in the body frame.
§When to use

Use this for constant-rate steps or as a first-order integrator. For time-varying rates (e.g. from Euler’s equations with applied torques), use derivative with a higher-order ODE integrator instead.

§Example
use numeris::{Quaternion, Vector3};

// Rotate 90° about Z at 1 rad/s
let q = Quaternion::<f64>::identity();
let omega = Vector3::from_array([0.0, 0.0, 1.0]);
let q_new = q.propagate(&omega, std::f64::consts::FRAC_PI_2);

// Should match a 90° rotation about Z
let v = Vector3::from_array([1.0, 0.0, 0.0]);
let rotated = q_new * v;
assert!((rotated[0]).abs() < 1e-12);
assert!((rotated[1] - 1.0).abs() < 1e-12);

Trait Implementations§

Source§

impl<T: Clone> Clone for Quaternion<T>

Source§

fn clone(&self) -> Quaternion<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug> Debug for Quaternion<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Display> Display for Quaternion<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: FloatScalar> Mul<&Matrix<T, 1, 3>> for &Quaternion<T>

Source§

type Output = Matrix<T, 1, 3>

The resulting type after applying the * operator.
Source§

fn mul(self, v: &Vector3<T>) -> Vector3<T>

Performs the * operation. Read more
Source§

impl<T: FloatScalar> Mul<&Matrix<T, 1, 3>> for Quaternion<T>

Source§

type Output = Matrix<T, 1, 3>

The resulting type after applying the * operator.
Source§

fn mul(self, v: &Vector3<T>) -> Vector3<T>

Performs the * operation. Read more
Source§

impl<T: FloatScalar> Mul<&Quaternion<T>> for &Quaternion<T>

Source§

type Output = Quaternion<T>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &Quaternion<T>) -> Quaternion<T>

Performs the * operation. Read more
Source§

impl<T: FloatScalar> Mul<&Quaternion<T>> for Quaternion<T>

Source§

type Output = Quaternion<T>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &Quaternion<T>) -> Quaternion<T>

Performs the * operation. Read more
Source§

impl<T: FloatScalar> Mul<Matrix<T, 1, 3>> for &Quaternion<T>

Source§

type Output = Matrix<T, 1, 3>

The resulting type after applying the * operator.
Source§

fn mul(self, v: Vector3<T>) -> Vector3<T>

Performs the * operation. Read more
Source§

impl<T: FloatScalar> Mul<Matrix<T, 1, 3>> for Quaternion<T>

Source§

type Output = Matrix<T, 1, 3>

The resulting type after applying the * operator.
Source§

fn mul(self, v: Vector3<T>) -> Vector3<T>

Performs the * operation. Read more
Source§

impl<T: FloatScalar> Mul<Quaternion<T>> for &Quaternion<T>

Source§

type Output = Quaternion<T>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Quaternion<T>) -> Quaternion<T>

Performs the * operation. Read more
Source§

impl<T: FloatScalar> Mul for Quaternion<T>

Source§

type Output = Quaternion<T>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Self) -> Self

Performs the * operation. Read more
Source§

impl<T: FloatScalar> Neg for &Quaternion<T>

Source§

type Output = Quaternion<T>

The resulting type after applying the - operator.
Source§

fn neg(self) -> Quaternion<T>

Performs the unary - operation. Read more
Source§

impl<T: FloatScalar> Neg for Quaternion<T>

Source§

type Output = Quaternion<T>

The resulting type after applying the - operator.
Source§

fn neg(self) -> Self

Performs the unary - operation. Read more
Source§

impl<T: PartialEq> PartialEq for Quaternion<T>

Source§

fn eq(&self, other: &Quaternion<T>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T: Copy> Copy for Quaternion<T>

Source§

impl<T> StructuralPartialEq for Quaternion<T>

Auto Trait Implementations§

§

impl<T> Freeze for Quaternion<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for Quaternion<T>
where T: RefUnwindSafe,

§

impl<T> Send for Quaternion<T>
where T: Send,

§

impl<T> Sync for Quaternion<T>
where T: Sync,

§

impl<T> Unpin for Quaternion<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for Quaternion<T>
where T: UnsafeUnpin,

§

impl<T> UnwindSafe for Quaternion<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.