al_jabr/
lib.rs

1// Copyright 2019 The Al_Jabr Developers. For a full listing of authors,
2// refer to the Cargo.toml file at the top-level directory of this distribution.
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9//
10//! A generic linear algebra library for computer graphics.
11//!
12//! `al_jabr` is roughly compatible with [cgmath](https://github.com/rustgd/cgmath)
13//! and is intended to provide a small set of lightweight linear algebra
14//! operations typically useful in interactive computer graphics.
15//!
16//! `al_jabr` is n-dimensional, meaning that its data structures support an
17//! arbitrary number of elements. If you wish to create a five-dimensional rigid
18//! body simulation, `al_jabr` can help you.
19//!
20//! ## Getting started
21//!
22//! All of `al_jabr`'s types are exported in the root of the crate, so importing
23//! them all is as easy as adding the following to the top of your source file:
24//!
25//! ```
26//! use al_jabr::*;
27//! ```
28//!
29//! After that, you can begin using `al_jabr`.
30//!
31//! ### Vectors
32//!
33//! Small (N = 1, 2, 3, 4) vectors as well as an N-dimensional [ColumnVector] are
34//! provided. Unless you have a need for larger vectors, it is recommended to use
35//! [Vector1], [Vector2], [Vector3] or [Vector4].
36//!
37//! [Add], [Sub], and [Neg] will be properly implemented for any `Vector` and
38//! `ColumnVector<Scalar, N>` for any respective implementation of such operations
39//! for `Scalar`. Operations are only implemented for vectors of equal sizes.
40//!
41//! ```
42//! # use al_jabr::*;
43//! let a = Vector4::new(0.0f32, 1.0, 2.0, 3.0);
44//! let b = Vector4::new(1.0f32, 1.0, 1.0, 1.0);
45//! assert_eq!(
46//!     a + b,
47//!     Vector4::new(1.0, 2.0, 3.0, 4.0),
48//! );
49//!
50//! let d = column_vector![ 0.0f32, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, ];
51//! let e = column_vector![ 1.0f32, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, ] * 0.5;
52//! assert_eq!(
53//!     d + e,
54//!     column_vector![ 0.5f32, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5 ]
55//! );
56//! ```
57//!
58//! If the scalar type implements [Mul] as well, then the Vector will be an
59//! [InnerSpace] and have the [dot](InnerSpace::dot) product defined for it,
60//! as well as the ability to find the squared distance between two vectors
61//! (implements [MetricSpace]) and the squared magnitude of a vector. If the
62//! scalar type is a real number then the  distance between two vectors and
63//! the magnitude of a vector can be found in addition:
64//!
65//! ```rust
66//! # use al_jabr::*;
67//! let a = Vector2::new(1i32, 1);
68//! let b = Vector2::new(5i32, 5);
69//! assert_eq!(a.distance2(b), 32);       // distance method not implemented.
70//! assert_eq!((b - a).magnitude2(), 32); // magnitude method not implemented.
71//!
72//! let a = Vector2::new(1.0f32, 1.0);
73//! let b = Vector2::new(5.0f32, 5.0);
74//! const close: f32 = 5.65685424949;
75//! assert_eq!(a.distance(b), close);       // distance is implemented.
76//! assert_eq!((b - a).magnitude(), close); // magnitude is implemented.
77//!
78//! // Vector normalization is also supported for floating point scalars.
79//! assert_eq!(
80//!     Vector3::new(0.0f32, 20.0, 0.0)
81//!         .normalize(),
82//!     Vector3::new(0.0f32, 1.0, 0.0)
83//! );
84//! ```
85//!
86//! #### Swizzling
87//!
88//! ColumnVectors of any size and Vectors of size 2, 3 and 4 support
89//! [swizzling](https://en.wikipedia.org/wiki/Swizzling_(computer_graphics)).
90//! The methods are hidden as to not pollute the docs, but are still available:
91//!
92//! ```rust
93//! # use al_jabr::*;
94//! assert_eq!(Vector3::new(1i32, 2, 3).xy(), Vector2::new(1i32, 2));
95//! ```
96//!
97//! ### Points
98//!
99//! Small (N = 1, 2, 3, 4) points in space are provided.
100//!
101//! Points are far less flexible and useful than vectors and are used
102//! to express the purpose or meaning of a variable through its type.
103//!
104//! Points can be moved through space by adding or subtracting Vectors from
105//! them.
106//!
107//! The only mathematical operator supported between two points is
108//! subtraction, which results in the vector between the two points.
109//!
110//! Points can be freely converted to and from vectors via `from_vec`
111//! and `to_vec`.
112//!
113//! ```rust
114//! # use al_jabr::*;
115//! let a = Point3::new(5, 4, 3);
116//! let b = Point3::new(1, 1, 1);
117//! assert_eq!(a - b, Vector3::new(4, 3, 2));
118//! ```
119//!
120//! ### Matrices
121//!
122//! [Matrices](Matrix) can be created from an array of arrays of any size
123//! and scalar type. Matrices are column-major and constructing a matrix from a
124//! raw array reflects that. The [matrix!] macro can be used to construct a
125//! matrix in row-major order:
126//!
127//! ```
128//! # use al_jabr::*;
129//! // Construct in column-major order:
130//! let a = Matrix::<i32, 3, 3>::from([
131//!     [  0,  6,  2 ],
132//!     [ -3,  1,  3 ],
133//!     [  5, -4, -2 ],
134//! ]);
135//!
136//! // Construct in row-major order:
137//! let b: Matrix::<i32, 3, 3> = matrix![
138//!     [ 0, -3, 5 ],
139//!     [ 6, 1, -4 ],
140//!     [ 2, 3, -2 ]
141//! ];
142//!
143//! assert_eq!(a, b);
144//! ```
145//!
146//! All operations performed on matrices produce fixed-size outputs. For
147//! example, taking the [transpose](Matrix::transpose) of a non-square matrix
148//! will produce a matrix with the width and height swapped:
149//!
150//! ```
151//! # use al_jabr::*;
152//! assert_eq!(
153//!     Matrix::<i32, 1, 2>::from([ [ 1 ], [ 2 ] ])
154//!         .transpose(),
155//!     Matrix::<i32, 2, 1>::from([ [ 1, 2 ] ])
156//! );
157//! ```
158//!
159//! As with Vectors, if the underlying scalar type supports the appropriate
160//! operations, a matrix will implement element-wise [Add] and [Sub] for
161//! matrices of equal size:
162//!
163//! ```
164//! # use al_jabr::*;
165//! let a = matrix!([1_u32]);
166//! let b = matrix!([2_u32]);
167//! let c = matrix!([3_u32]);
168//! assert_eq!(a + b, c);
169//! ```
170//!
171//! And this is true for any type that implements [Add], so therefore the
172//! following is possible as well:
173//!
174//! ```
175//! # use al_jabr::*;
176//! let a = matrix!([matrix!([1_u32])]);
177//! let b = matrix!([matrix!([2_u32])]);
178//! let c = matrix!([matrix!([3_u32])]);
179//! assert_eq!(a + b, c);
180//! ```
181//!
182//! For a given type `T`, if `T: Clone` and `Vector<T, _>` is an [InnerSpace],
183//! then multiplication is defined for `Matrix<T, N, M> * Matrix<T, M, P>`. The
184//! result is a `Matrix<T, N, P>`:
185//!
186//! ```rust
187//! # use al_jabr::*;
188//! let a: Matrix::<i32, 3, 3> = matrix![
189//!     [ 0, -3, 5 ],
190//!     [ 6, 1, -4 ],
191//!     [ 2, 3, -2 ],
192//! ];
193//! let b: Matrix::<i32, 3, 3> = matrix![
194//!     [ -1, 0, -3 ],
195//!     [  4, 5,  1 ],
196//!     [  2, 6, -2 ],
197//! ];
198//! let c: Matrix::<i32, 3, 3> = matrix![
199//!     [  -2,  15, -13 ],
200//!     [ -10, -19,  -9 ],
201//!     [   6,   3,   1 ],
202//! ];
203//! assert_eq!(
204//!     a * b,
205//!     c
206//! );
207//! ```
208//!
209//! Some matrices have special functions defined for them. Check out [Matrix3]
210//! and [Matrix4] for more information.
211
212use core::{
213    cmp::PartialOrd,
214    fmt,
215    hash::{Hash, Hasher},
216    iter::{FromIterator, Product},
217    marker::PhantomData,
218    mem::{self, transmute_copy, MaybeUninit},
219    ops::{
220        Add, AddAssign, Deref, DerefMut, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub,
221        SubAssign,
222    },
223};
224
225#[cfg(feature = "rand")]
226use rand::{
227    distributions::{Distribution, Standard},
228    Rng,
229};
230
231#[cfg(feature = "serde")]
232use serde::{
233    de::{Error, SeqAccess, Visitor},
234    ser::SerializeTuple,
235    Deserialize, Deserializer, Serialize, Serializer,
236};
237
238mod array;
239mod column_vector;
240mod matrix;
241mod point;
242mod rotation;
243pub mod row_view;
244mod vector;
245
246pub use array::*;
247pub use column_vector::*;
248pub use matrix::*;
249pub use point::*;
250pub use rotation::*;
251use row_view::*;
252pub use vector::*;
253
254/// Defines the additive identity for `Self`.
255pub trait Zero {
256    /// Returns the additive identity of `Self`.
257    fn zero() -> Self;
258
259    /// Returns true if the value is the additive identity.
260    fn is_zero(&self) -> bool;
261}
262
263macro_rules! impl_zero {
264    // Default $zero to '0' if not provided.
265    (
266        $type:ty
267    ) => {
268        impl_zero! { $type, 0 }
269    };
270    // Main impl.
271    (
272        $type:ty,
273        $zero:expr
274    ) => {
275        impl Zero for $type {
276            fn zero() -> Self {
277                $zero
278            }
279
280            fn is_zero(&self) -> bool {
281                *self == $zero
282            }
283        }
284    };
285}
286
287impl_zero! { bool, false }
288impl_zero! { f32, 0.0 }
289impl_zero! { f64, 0.0 }
290impl_zero! { i8 }
291impl_zero! { i16 }
292impl_zero! { i32 }
293impl_zero! { i64 }
294impl_zero! { i128 }
295impl_zero! { isize }
296impl_zero! { u8 }
297impl_zero! { u16 }
298impl_zero! { u32 }
299impl_zero! { u64 }
300impl_zero! { u128 }
301impl_zero! { usize }
302
303/// Defines the multiplicative identity element for `Self`.
304///
305/// For Matrices, `one` is an alias for the unit matrix.
306pub trait One {
307    /// Returns the multiplicative identity for `Self`.
308    fn one() -> Self;
309
310    /// Returns true if the value is the multiplicative identity.
311    fn is_one(&self) -> bool;
312}
313
314macro_rules! impl_one {
315    // Default $one to '1' if not provided.
316    (
317        $type:ty
318    ) => {
319        impl_one! { $type, 1 }
320    };
321    // Main impl.
322    (
323        $type:ty,
324        $one:expr
325    ) => {
326        impl One for $type {
327            fn one() -> Self {
328                $one
329            }
330
331            fn is_one(&self) -> bool {
332                *self == $one
333            }
334        }
335    };
336}
337
338impl_one! { bool, true }
339impl_one! { f32, 1.0 }
340impl_one! { f64, 1.0 }
341impl_one! { i8 }
342impl_one! { i16 }
343impl_one! { i32 }
344impl_one! { i64 }
345impl_one! { i128 }
346impl_one! { isize }
347impl_one! { u8 }
348impl_one! { u16 }
349impl_one! { u32 }
350impl_one! { u64 }
351impl_one! { u128 }
352impl_one! { usize }
353
354/// Values that are [real numbers](https://en.wikipedia.org/wiki/Real_number#Axiomatic_approach).
355pub trait Real
356where
357    Self: Sized,
358    Self: Add<Output = Self>,
359    Self: Sub<Output = Self>,
360    Self: Mul<Output = Self>,
361    Self: Div<Output = Self>,
362    Self: Neg<Output = Self>,
363    Self: PartialOrd + PartialEq,
364{
365    fn sqrt(self) -> Self;
366
367    /// Returns twice the value.
368    fn mul2(self) -> Self;
369
370    /// Returns half of the value.
371    fn div2(self) -> Self;
372
373    fn abs(self) -> Self;
374
375    /// Returns the sine of the angle.
376    fn sin(self) -> Self;
377
378    /// Returns the cosine of the angle.
379    fn cos(self) -> Self;
380
381    /// Returns the tangent of the angle.
382    fn tan(self) -> Self;
383
384    /// Returns the arcsine of the angle.
385    fn asin(self) -> Self;
386
387    /// Returns the arccos of the angle.
388    fn acos(self) -> Self;
389
390    /// Returns the four quadrant arctangent of `self` and `x` in radians.
391    fn atan2(self, x: Self) -> Self;
392
393    /// Returns the sine and the cosine of the angle.
394    fn sin_cos(self) -> (Self, Self);
395
396    /// Returns the sign of the number.
397    fn signum(self) -> Self;
398}
399
400impl Real for f32 {
401    fn sqrt(self) -> Self {
402        self.sqrt()
403    }
404
405    fn mul2(self) -> Self {
406        2.0 * self
407    }
408
409    fn div2(self) -> Self {
410        self / 2.0
411    }
412
413    fn abs(self) -> Self {
414        self.abs()
415    }
416
417    fn sin(self) -> Self {
418        self.sin()
419    }
420
421    fn cos(self) -> Self {
422        self.cos()
423    }
424
425    fn asin(self) -> Self {
426        self.asin()
427    }
428
429    fn acos(self) -> Self {
430        self.acos()
431    }
432
433    fn tan(self) -> Self {
434        self.tan()
435    }
436
437    fn atan2(self, x: Self) -> Self {
438        self.atan2(x)
439    }
440
441    fn sin_cos(self) -> (Self, Self) {
442        (self.sin(), self.cos())
443    }
444
445    fn signum(self) -> Self {
446        self.signum()
447    }
448}
449
450impl Real for f64 {
451    fn sqrt(self) -> Self {
452        self.sqrt()
453    }
454
455    fn mul2(self) -> Self {
456        2.0 * self
457    }
458
459    fn div2(self) -> Self {
460        self / 2.0
461    }
462
463    fn abs(self) -> Self {
464        self.abs()
465    }
466
467    fn sin(self) -> Self {
468        self.sin()
469    }
470
471    fn cos(self) -> Self {
472        self.cos()
473    }
474
475    fn asin(self) -> Self {
476        self.asin()
477    }
478
479    fn acos(self) -> Self {
480        self.acos()
481    }
482
483    fn tan(self) -> Self {
484        self.tan()
485    }
486
487    fn atan2(self, x: Self) -> Self {
488        self.atan2(x)
489    }
490
491    fn sin_cos(self) -> (Self, Self) {
492        (self.sin(), self.cos())
493    }
494
495    fn signum(self) -> Self {
496        self.signum()
497    }
498}
499
500/// Vectors that can be added together and multiplied by scalars form a
501/// `VectorSpace`.
502///
503/// If a type implements [Add] and [Sub] and its scalar implements [Mul] and
504/// [Div], then that vector is part of a `VectorSpace`.
505pub trait VectorSpace
506where
507    Self: Sized + Clone + Zero,
508    Self: Add<Self, Output = Self>,
509    Self: Sub<Self, Output = Self>,
510    Self: Mul<<Self as VectorSpace>::Scalar, Output = Self>,
511    Self: Div<<Self as VectorSpace>::Scalar, Output = Self>,
512{
513    // I only need Div, but I felt like I had to add them all...
514    type Scalar: Add<Self::Scalar, Output = Self::Scalar>
515        + Sub<Self::Scalar, Output = Self::Scalar>
516        + Mul<Self::Scalar, Output = Self::Scalar>
517        + Div<Self::Scalar, Output = Self::Scalar>;
518
519    /// Linear interpolate between the two vectors with a weight of `t`.
520    fn lerp(self, other: Self, t: Self::Scalar) -> Self {
521        self.clone() + ((other - self) * t)
522    }
523}
524
525/// A type with a distance function between two values.
526pub trait MetricSpace: Sized {
527    type Metric;
528
529    /// Returns the distance squared between the two values.
530    fn distance2(self, other: Self) -> Self::Metric;
531}
532
533/// A [MetricSpace] where the metric is a real number.
534pub trait RealMetricSpace: MetricSpace
535where
536    Self::Metric: Real,
537{
538    /// Returns the distance between the two values.
539    fn distance(self, other: Self) -> Self::Metric {
540        self.distance2(other).sqrt()
541    }
542}
543
544impl<T> RealMetricSpace for T
545where
546    T: MetricSpace,
547    <T as MetricSpace>::Metric: Real,
548{
549}
550
551/// Vector spaces that have an inner (also known as "dot") product.
552pub trait InnerSpace: VectorSpace
553where
554    Self: Clone,
555    Self: MetricSpace<Metric = <Self as VectorSpace>::Scalar>,
556{
557    /// Return the inner (also known as "dot") product.
558    fn dot(self, other: Self) -> Self::Scalar;
559
560    /// Returns the squared length of the value.
561    fn magnitude2(self) -> Self::Scalar {
562        self.clone().dot(self)
563    }
564
565    /// Returns the [reflection](https://en.wikipedia.org/wiki/Reflection_(mathematics))
566    /// of the current vector with respect to the given surface normal. The
567    /// surface normal must be of length 1 for the return value to be
568    /// correct. The current vector is interpreted as pointing toward the
569    /// surface, and does not need to be normalized.
570    fn reflect(self, surface_normal: Unit<Self>) -> Self {
571        let surface_normal = surface_normal.into_inner();
572        let a = surface_normal.clone() * self.clone().dot(surface_normal);
573        self - (a.clone() + a)
574    }
575}
576
577/// Defines an [InnerSpace] where the Scalar is a real number. Automatically
578/// implemented.
579pub trait RealInnerSpace: InnerSpace
580where
581    Self: Clone,
582    Self: MetricSpace<Metric = <Self as VectorSpace>::Scalar>,
583    <Self as VectorSpace>::Scalar: Real,
584{
585    /// Returns the length of the vector.
586    fn magnitude(self) -> Self::Scalar {
587        self.clone().dot(self).sqrt()
588    }
589
590    /// Returns a vector with the same direction and a magnitude of `1`.
591    fn normalize(self) -> Self
592    where
593        Self::Scalar: One,
594    {
595        self.normalize_to(<Self::Scalar as One>::one())
596    }
597
598    /// Returns a vector with the same direction and a given magnitude.
599    fn normalize_to(self, magnitude: Self::Scalar) -> Self {
600        self.clone() * (magnitude / self.magnitude())
601    }
602
603    /// Returns the
604    /// [vector projection](https://en.wikipedia.org/wiki/Vector_projection)
605    /// of the current inner space projected onto the supplied argument.
606    fn project_on(self, other: Self) -> Self {
607        other.clone() * (self.dot(other.clone()) / other.magnitude2())
608    }
609}
610
611impl<T> RealInnerSpace for T
612where
613    T: InnerSpace,
614    <T as VectorSpace>::Scalar: Real,
615{
616}
617
618/// An object with a magnitude of one
619#[derive(Copy, Clone, Debug, PartialEq, Eq)]
620#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
621#[repr(transparent)]
622pub struct Unit<T>(T);
623
624impl<T> Unit<T> {
625    pub fn into_inner(self) -> T {
626        self.0
627    }
628}
629
630impl<T> Deref for Unit<T> {
631    type Target = T;
632
633    fn deref(&self) -> &Self::Target {
634        &self.0
635    }
636}
637
638impl<T> DerefMut for Unit<T> {
639    fn deref_mut(&mut self) -> &mut Self::Target {
640        &mut self.0
641    }
642}
643
644impl<T> Unit<T>
645where
646    T: RealInnerSpace + VectorSpace,
647    T::Scalar: Real + One,
648{
649    /// Construct a new unit object, normalizing the input in the process
650    pub fn new_normalize(obj: T) -> Self {
651        Unit(obj.normalize())
652    }
653}
654
655impl<T> Unit<T> {
656    /// Construct a new unit object without normalizing
657    ///
658    /// # Safety
659    ///
660    /// This method assumes that the object being passed to it is normalized,
661    /// i.e. has a magnitude of one. If it does not, other methods can break
662    /// in strange ways.
663    pub unsafe fn new_unchecked(obj: T) -> Self {
664        Unit(obj)
665    }
666}
667
668impl<T> Unit<T>
669where
670    T: RealInnerSpace + VectorSpace + Neg<Output = T>,
671    T::Scalar: Real + Zero + One + Clone,
672{
673    /// Perform a normalized linear interpolation between self and rhs
674    pub fn nlerp(self, mut rhs: Self, amount: T::Scalar) -> Self {
675        if self.0.clone().dot(rhs.0.clone()) < T::Scalar::zero() {
676            rhs.0 = -rhs.0;
677        }
678        Self::new_normalize(self.0 * (T::Scalar::one() - amount.clone()) + rhs.0 * amount)
679    }
680
681    /// Perform a spherical linear interpolation between self and rhs
682    pub fn slerp(self, mut rhs: Self, amount: T::Scalar) -> Self {
683        let mut dot = self.0.clone().dot(rhs.0.clone());
684
685        if dot.clone() < T::Scalar::zero() {
686            rhs.0 = -rhs.0;
687            dot = -dot;
688        }
689
690        if dot.clone() >= T::Scalar::one() {
691            return self;
692        }
693
694        let theta = dot.acos();
695        let scale_lhs = (theta.clone() * (T::Scalar::one() - amount.clone())).sin();
696        let scale_rhs = (theta * amount).sin();
697
698        Self::new_normalize(self.0 * scale_lhs + rhs.0 * scale_rhs)
699    }
700}
701
702/// Convert a object to a unit object
703pub trait IntoUnit: Sized {
704    fn into_unit(self) -> Unit<Self>;
705}
706
707impl<T> IntoUnit for T
708where
709    T: RealInnerSpace + VectorSpace,
710    T::Scalar: Real + One,
711{
712    fn into_unit(self) -> Unit<Self> {
713        Unit::new_normalize(self)
714    }
715}