Module

Linear.Quaternion

Package
purescript-linear
Repository
afcondon/purescript-linear

Quaternions for 3D rotations.

This module provides quaternions, which are the most efficient and numerically stable way to represent 3D rotations. Quaternions avoid gimbal lock and interpolate smoothly.

#Quaternion Source

data Quaternion a

A quaternion representing a rotation in 3D space.

A quaternion q = w + xi + yj + zk is stored as Quaternion w (V3 x y z). Unit quaternions (where |q| = 1) represent rotations.

identity = Quaternion 1.0 (V3 0.0 0.0 0.0)

Constructors

Instances

#axisAngle Source

axisAngle :: V3 Number -> Number -> Quaternion Number

Construct a rotation quaternion from an axis and angle.

The axis should be a unit vector. The angle is in radians.

-- 90 degree rotation around the Y axis
axisAngle (V3 0.0 1.0 0.0) (pi / 2.0)

#fromEuler Source

fromEuler :: Number -> Number -> Number -> Quaternion Number

Construct a rotation from Euler angles (in radians).

Order is ZYX (yaw, pitch, roll).

fromEuler 0.0 0.0 0.0 = identity

#rotate Source

rotate :: Quaternion Number -> V3 Number -> V3 Number

Rotate a 3D vector by a quaternion.

The quaternion should be a unit quaternion for proper rotation.

let q = axisAngle (V3 0.0 1.0 0.0) (pi / 2.0)  -- 90° around Y
rotate q (V3 1.0 0.0 0.0) ≈ V3 0.0 0.0 (-1.0)

#conjugate Source

conjugate :: forall a. Ring a => Quaternion a -> Quaternion a

The conjugate of a quaternion.

For unit quaternions, the conjugate equals the inverse and represents the opposite rotation.

conjugate (Quaternion w (V3 x y z)) = Quaternion w (V3 (-x) (-y) (-z))

#inverse Source

inverse :: Quaternion Number -> Quaternion Number

The multiplicative inverse of a quaternion.

For unit quaternions, this equals the conjugate.

qmul q (inverse q) ≈ identity

#slerp Source

slerp :: Number -> Quaternion Number -> Quaternion Number -> Quaternion Number

Spherical linear interpolation between two quaternions.

This produces smooth rotation interpolation along the shortest path.

slerp 0.0 q1 q2 = q1
slerp 1.0 q1 q2 = q2
slerp 0.5 q1 q2 -- halfway rotation

#getW Source

getW :: forall a. Quaternion a -> a

Get the scalar (w) component.

#getXYZ Source

getXYZ :: forall a. Quaternion a -> V3 a

Get the vector (xyz) components.

#getX Source

getX :: forall a. Quaternion a -> a

Get the x component.

#getY Source

getY :: forall a. Quaternion a -> a

Get the y component.

#getZ Source

getZ :: forall a. Quaternion a -> a

Get the z component.

#qmul Source

qmul :: forall a. Ring a => Quaternion a -> Quaternion a -> Quaternion a

Quaternion multiplication (Hamilton product).

This is NOT commutative: qmul q1 q2 /= qmul q2 q1 in general. Composing rotations: to apply rotation q1 then q2, use qmul q2 q1.

qmul identity q = q
qmul q identity = q