Linear
- Package
- purescript-linear
- Repository
- afcondon/purescript-linear
Linear algebra for graphics programming.
This module re-exports the core functionality from the linear package. It provides fixed-size vectors (V2, V3, V4), quaternions for 3D rotations, and matrix operations commonly used in graphics and game development.
Quick Start
import Linear
-- 2D vector operations
v1 = V2 3.0 4.0
v2 = V2 1.0 0.0
sum = v1 ^+^ v2 -- V2 4.0 4.0
length = norm v1 -- 5.0
unit = signorm v1 -- V2 0.6 0.8
-- 3D cross product
x = V3 1.0 0.0 0.0
y = V3 0.0 1.0 0.0
z = cross x y -- V3 0.0 0.0 1.0
-- Quaternion rotation
q = axisAngle (V3 0.0 1.0 0.0) (pi / 2.0) -- 90° around Y
rotated = rotate q (V3 1.0 0.0 0.0) -- ≈ V3 0.0 0.0 (-1.0)
Re-exports from Linear.Affine
#Point Source
newtype Point :: forall k. (k -> Type) -> k -> Typenewtype Point f a
A point in an affine space.
The Point newtype distinguishes points from vectors at the type level.
This prevents nonsensical operations like adding two points together.
origin = P (V2 0.0 0.0)
position = P (V2 3.0 4.0)
Constructors
P (f a)
Instances
Newtype (Point f a) _(Eq (f a)) => Eq (Point f a)(Ord (f a)) => Ord (Point f a)(Show (f a)) => Show (Point f a)(Functor f) => Functor (Point f)(Apply f) => Apply (Point f)(Applicative f) => Applicative (Point f)(Foldable f) => Foldable (Point f)(Traversable f) => Traversable (Point f)(Additive f, Epsilon (f a)) => Epsilon (Point f a)(Additive f) => Affine (Point f) f
#Affine Source
class Affine :: (Type -> Type) -> (Type -> Type) -> Constraintclass (Additive d) <= Affine p d | p -> d where
An affine space is a set of points with associated difference vectors.
Laws:
p .+^ (q .-. p) = q(p .+^ u) .+^ v = p .+^ (u ^+^ v)p .-. p = zero
Members
diff :: forall a. Ring a => p a -> p a -> d aThe vector from the first point to the second.
moveBy :: forall a. Semiring a => p a -> d a -> p aAdd a vector to a point.
moveByNeg :: forall a. Ring a => p a -> d a -> p aSubtract a vector from a point.
Instances
#origin Source
origin :: forall f a. Applicative f => Semiring a => Point f aThe origin point (all coordinates zero).
origin :: Point V3 Number
origin = P (V3 0.0 0.0 0.0)
Re-exports from Linear.Epsilon
#Epsilon Source
class Epsilon a whereA typeclass for types that support approximate zero testing.
The nearZero function provides a "fairly subjective test to see
if a quantity is near zero" (as Ed Kmett puts it).
Members
Instances
Re-exports from Linear.Matrix
#transpose44 Source
transpose44 :: forall a. M44 a -> M44 aTranspose a 4x4 matrix.
#transpose33 Source
transpose33 :: forall a. M33 a -> M33 aTranspose a 3x3 matrix.
#transpose22 Source
transpose22 :: forall a. M22 a -> M22 aTranspose a 2x2 matrix.
#mkTransformation Source
mkTransformation :: Quaternion Number -> V3 Number -> M44 NumberBuild a 4x4 transformation matrix from a quaternion rotation and translation.
The resulting matrix applies rotation first, then translation.
mkTransformation identity (V3 1.0 2.0 3.0) -- pure translation
mkTransformation rotation (V3 0.0 0.0 0.0) -- pure rotation
#identity44 Source
identity44 :: forall a. Semiring a => M44 a4x4 identity matrix.
#identity33 Source
identity33 :: forall a. Semiring a => M33 a3x3 identity matrix.
#identity22 Source
identity22 :: forall a. Semiring a => M22 a2x2 identity matrix.
#fromQuaternion Source
fromQuaternion :: Quaternion Number -> M33 NumberConvert a unit quaternion to a 3x3 rotation matrix.
fromQuaternion (Quaternion 1.0 (V3 0.0 0.0 0.0)) = identity33
#diagonal33 Source
diagonal33 :: forall a. M33 a -> V3 aExtract the diagonal of a 3x3 matrix.
Re-exports from Linear.Metric
#Metric Source
class Metric :: (Type -> Type) -> Constraintclass (Additive f) <= Metric f where
A metric space with an inner product.
Laws:
dot v v >= 0(positive semi-definite)dot v v = 0impliesv = zerodot u v = dot v u(symmetry)dot (a *^ u) v = a * dot u v(linearity)
Members
dot :: forall a. Semiring a => f a -> f a -> aThe inner (dot) product of two vectors.
dot (V2 1.0 2.0) (V2 3.0 4.0) = 11.0 -- 1*3 + 2*4quadrance :: forall a. Semiring a => f a -> aThe squared norm of a vector (quadrance from rational trigonometry).
This is more efficient than
normwhen you only need to compare magnitudes.quadrance (V2 3.0 4.0) = 25.0 -- 3² + 4²qd :: forall a. Ring a => f a -> f a -> aThe squared distance between two vectors.
qd (V2 0.0 0.0) (V2 3.0 4.0) = 25.0distance :: f Number -> f Number -> NumberThe Euclidean distance between two vectors.
distance (V2 0.0 0.0) (V2 3.0 4.0) = 5.0norm :: f Number -> NumberThe Euclidean norm (magnitude) of a vector.
norm (V2 3.0 4.0) = 5.0signorm :: f Number -> f NumberConvert a non-zero vector to a unit vector (signorm = "sign of norm").
Returns the zero vector when given the zero vector.
signorm (V2 3.0 4.0) = V2 0.6 0.8 signorm (V2 0.0 0.0) = V2 0.0 0.0
Re-exports from Linear.Quaternion
#Quaternion Source
data Quaternion aA 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
Quaternion a (V3 a)
Instances
(Eq a) => Eq (Quaternion a)(Show a) => Show (Quaternion a)Functor QuaternionApply QuaternionApplicative QuaternionFoldable QuaternionTraversable QuaternionAdditive QuaternionMetric Quaternion(Semiring a) => Semigroup (Quaternion a)(Semiring a) => Monoid (Quaternion a)(Epsilon a) => Epsilon (Quaternion a)
#slerp Source
slerp :: Number -> Quaternion Number -> Quaternion Number -> Quaternion NumberSpherical 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
#qmul Source
qmul :: forall a. Ring a => Quaternion a -> Quaternion a -> Quaternion aQuaternion 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
#inverse Source
inverse :: Quaternion Number -> Quaternion NumberThe multiplicative inverse of a quaternion.
For unit quaternions, this equals the conjugate.
qmul q (inverse q) ≈ identity
#conjugate Source
conjugate :: forall a. Ring a => Quaternion a -> Quaternion aThe 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))
Re-exports from Linear.V2
#V2 Source
#crossZ Source
crossZ :: forall a. Ring a => V2 a -> V2 a -> aThe z-component of the cross product of two 2D vectors.
This is useful for determining the orientation of two vectors:
- Positive: v2 is counter-clockwise from v1
- Negative: v2 is clockwise from v1
- Zero: vectors are parallel
crossZ (V2 1.0 0.0) (V2 0.0 1.0) = 1.0 -- counter-clockwise
crossZ (V2 0.0 1.0) (V2 1.0 0.0) = -1.0 -- clockwise
Re-exports from Linear.V3
#V3 Source
Re-exports from Linear.V4
#V4 Source
#normalizePoint Source
normalizePoint :: V4 Number -> V3 NumberConvert homogeneous coordinates back to 3D by dividing by w.
normalizePoint (V4 2.0 4.0 6.0 2.0) = V3 1.0 2.0 3.0
Re-exports from Linear.Vector
#Additive Source
class Additive :: (Type -> Type) -> Constraintclass (Functor f) <= Additive f where
A vector space with addition and scalar multiplication.
Laws:
add zero v = v(left identity)add v zero = v(right identity)add (add u v) w = add u (add v w)(associativity)add u v = add v u(commutativity)sub v v = zero
Members
zero :: forall a. Semiring a => f aThe zero vector
add :: forall a. Semiring a => f a -> f a -> f aVector addition
sub :: forall a. Ring a => f a -> f a -> f aVector subtraction
lerp :: forall a. Ring a => a -> f a -> f a -> f aLinear interpolation:
lerp t a b = a + t * (b - a)lerp 0.0 a b = alerp 1.0 a b = b
liftU2 :: forall a. (a -> a -> a) -> f a -> f a -> f aApply a function to non-zero values (union semantics)
liftI2 :: forall a b c. (a -> b -> c) -> f a -> f b -> f cApply a function component-wise (intersection semantics)
Points form an affine space over their underlying vectors.