Matrix

Struct Matrix 

Source
#[repr(transparent)]
pub struct Matrix<Repr, Map>(pub Repr, _);
Expand description

A generic matrix type.

Tuple Fields§

§0: Repr

Implementations§

Source§

impl<Repr, Map> Matrix<Repr, Map>

Source

pub const fn new(els: Repr) -> Self

Returns a matrix with the given elements.

Source

pub fn to<M>(&self) -> Matrix<Repr, M>
where Repr: Clone,

Returns a matrix equal to self but with mapping M.

This method can be used to coerce a matrix to a different mapping in case it is needed to make types match.

Examples found in repository?
examples/hello_tri.rs (line 31)
4fn main() {
5    let verts = [
6        vertex(pt3(-1.0, 1.0, 0.0), rgb(1.0, 0.0, 0.0)),
7        vertex(pt3(1.0, 1.0, 0.0), rgb(0.0, 0.8, 0.0)),
8        vertex(pt3(0.0, -1.0, 0.0), rgb(0.4, 0.4, 1.0)),
9    ];
10
11    #[cfg(feature = "fp")]
12    let shader = shader::new(
13        |v: Vertex3<Color3f>, mvp: &Mat4x4<ModelToProj>| {
14            // Transform vertex position from model to projection space
15            // Interpolate vertex colors in linear color space
16            vertex(mvp.apply(&v.pos), v.attrib.to_linear())
17        },
18        |frag: Frag<Color3f<_>>| frag.var.to_srgb().to_color4(),
19    );
20    #[cfg(not(feature = "fp"))]
21    let shader = shader::new(
22        |v: Vertex3<Color3f>, mvp: &Mat4x4<ModelToProj>| {
23            // Transform vertex position from model to projection space
24            // Interpolate vertex colors in normal sRGB color space
25            vertex(mvp.apply(&v.pos), v.attrib)
26        },
27        |frag: Frag<Color3f<_>>| frag.var.to_color4(),
28    );
29
30    let dims @ (w, h) = (640, 480);
31    let modelview = translate3(0.0, 0.0, 2.0).to();
32    let project = perspective(1.0, w as f32 / h as f32, 0.1..1000.0);
33    let viewport = viewport(pt2(0, h)..pt2(w, 0));
34
35    let mut framebuf = Buf2::<Color4>::new(dims);
36
37    render(
38        [tri(0, 1, 2)],
39        verts,
40        &shader,
41        &modelview.then(&project),
42        viewport,
43        &mut framebuf,
44        &Context::default(),
45    );
46
47    let center_pixel = framebuf[[w / 2, h / 2]];
48
49    if cfg!(feature = "fp") {
50        assert_eq!(center_pixel, rgba(150, 128, 186, 255));
51    } else {
52        assert_eq!(center_pixel, rgba(114, 102, 127, 255));
53    }
54    #[cfg(feature = "std")]
55    {
56        pnm::save_ppm("triangle.ppm", framebuf).unwrap();
57    }
58}
Source§

impl<Sc, const N: usize, const M: usize, Map> Matrix<[[Sc; N]; M], Map>
where Sc: Copy, Map: LinearMap,

Source

pub fn row_vec(&self, i: usize) -> Vector<[Sc; N], Map::Source>

Returns the row vector of self with index i.

The returned vector is in space Map::Source.

§Panics

If i >= M.

Source

pub fn col_vec(&self, i: usize) -> Vector<[Sc; M], Map::Dest>

Returns the column vector of self with index i.

The returned vector is in space Map::Dest.

§Panics

If i >= N.

Source§

impl<Sc: Copy, const N: usize, const DIM: usize, S, D> Matrix<[[Sc; N]; N], RealToReal<DIM, S, D>>

Source

pub fn transpose(self) -> Matrix<[[Sc; N]; N], RealToReal<DIM, D, S>>

Returns self with its rows and columns swapped.

Source§

impl<const N: usize, Map> Matrix<[[f32; N]; N], Map>

Source

pub const fn identity() -> Self

Returns the N×N identity matrix.

An identity matrix is a square matrix with ones on the main diagonal and zeroes everywhere else:

        ⎛ 1  0  ⋯  0 ⎞
 I  =   ⎜ 0  1       ⎟
        ⎜ ⋮     ⋱  0 ⎟
        ⎝ 0     0  1 ⎠

It is the neutral element of matrix multiplication: A · I = I · A = A, as well as matrix-vector multiplication: I·v = v.

Source§

impl Matrix<[[f32; 4]; 4], ()>

Source

pub const fn from_linear<S, D>( i: Vec3<D>, j: Vec3<D>, k: Vec3<D>, ) -> Mat4x4<RealToReal<3, S, D>>

Constructs a matrix from a linear basis.

The basis does not have to be orthonormal.

Source

pub const fn from_affine<S, D>( i: Vec3<D>, j: Vec3<D>, k: Vec3<D>, o: Point3<D>, ) -> Mat4x4<RealToReal<3, S, D>>

Constructs a matrix from an affine basis, or frame.

The basis does not have to be orthonormal.

Source§

impl<Sc, const N: usize, Map> Matrix<[[Sc; N]; N], Map>
where Sc: Linear<Scalar = Sc> + Copy, Map: LinearMap,

Source

pub fn compose<Inner: LinearMap>( &self, other: &Matrix<[[Sc; N]; N], Inner>, ) -> Matrix<[[Sc; N]; N], <Map as Compose<Inner>>::Result>
where Map: Compose<Inner>,

Returns the composite transform of self and other.

Computes the matrix product of self and other such that applying the resulting transformation is equivalent to first applying other and then self. More succinctly,

(𝗠 ∘ 𝗡) 𝘃 = 𝗠(𝗡 𝘃)

for some matrices 𝗠 and 𝗡 and a vector 𝘃.

Source

pub fn then<Outer: Compose<Map>>( &self, other: &Matrix<[[Sc; N]; N], Outer>, ) -> Matrix<[[Sc; N]; N], <Outer as Compose<Map>>::Result>

Returns the composite transform of other and self.

Computes the matrix product of self and other such that applying the resulting matrix is equivalent to first applying self and then other. The call self.then(other) is thus equivalent to other.compose(self).

Examples found in repository?
examples/hello_tri.rs (line 41)
4fn main() {
5    let verts = [
6        vertex(pt3(-1.0, 1.0, 0.0), rgb(1.0, 0.0, 0.0)),
7        vertex(pt3(1.0, 1.0, 0.0), rgb(0.0, 0.8, 0.0)),
8        vertex(pt3(0.0, -1.0, 0.0), rgb(0.4, 0.4, 1.0)),
9    ];
10
11    #[cfg(feature = "fp")]
12    let shader = shader::new(
13        |v: Vertex3<Color3f>, mvp: &Mat4x4<ModelToProj>| {
14            // Transform vertex position from model to projection space
15            // Interpolate vertex colors in linear color space
16            vertex(mvp.apply(&v.pos), v.attrib.to_linear())
17        },
18        |frag: Frag<Color3f<_>>| frag.var.to_srgb().to_color4(),
19    );
20    #[cfg(not(feature = "fp"))]
21    let shader = shader::new(
22        |v: Vertex3<Color3f>, mvp: &Mat4x4<ModelToProj>| {
23            // Transform vertex position from model to projection space
24            // Interpolate vertex colors in normal sRGB color space
25            vertex(mvp.apply(&v.pos), v.attrib)
26        },
27        |frag: Frag<Color3f<_>>| frag.var.to_color4(),
28    );
29
30    let dims @ (w, h) = (640, 480);
31    let modelview = translate3(0.0, 0.0, 2.0).to();
32    let project = perspective(1.0, w as f32 / h as f32, 0.1..1000.0);
33    let viewport = viewport(pt2(0, h)..pt2(w, 0));
34
35    let mut framebuf = Buf2::<Color4>::new(dims);
36
37    render(
38        [tri(0, 1, 2)],
39        verts,
40        &shader,
41        &modelview.then(&project),
42        viewport,
43        &mut framebuf,
44        &Context::default(),
45    );
46
47    let center_pixel = framebuf[[w / 2, h / 2]];
48
49    if cfg!(feature = "fp") {
50        assert_eq!(center_pixel, rgba(150, 128, 186, 255));
51    } else {
52        assert_eq!(center_pixel, rgba(114, 102, 127, 255));
53    }
54    #[cfg(feature = "std")]
55    {
56        pnm::save_ppm("triangle.ppm", framebuf).unwrap();
57    }
58}
Source§

impl<Src, Dest> Matrix<[[f32; 2]; 2], RealToReal<2, Src, Dest>>

Source

pub const fn determinant(&self) -> f32

Returns the determinant of self.

§Examples
use retrofire_core::math::{Mat2x2, mat::RealToReal};

let double: Mat2x2<RealToReal<2>> = [[2.0, 0.0], [0.0, 2.0]].into();
assert_eq!(double.determinant(), 4.0);

let singular: Mat2x2<RealToReal<2>> = [[1.0, 0.0], [2.0, 0.0]].into();
assert_eq!(singular.determinant(), 0.0);
Source

pub const fn checked_inverse(&self) -> Option<Mat2x2<RealToReal<2, Dest, Src>>>

Returns the inverse of self, or None if self is not invertible.

A matrix is invertible if and only if its determinant is nonzero. A non-invertible matrix is also called singular.

§Examples
use retrofire_core::math::{Mat2x2, mat::RealToReal};

let rotate_90: Mat2x2<RealToReal<2>> = [[0.0, -1.0], [1.0, 0.0]].into();
let rotate_neg_90 = rotate_90.checked_inverse();

assert_eq!(rotate_neg_90, Some([[0.0, 1.0], [-1.0, 0.0]].into()));

let singular: Mat2x2<RealToReal<2>> = [[1.0, 0.0], [2.0, 0.0]].into();
assert_eq!(singular.checked_inverse(), None);
Source

pub const fn inverse(&self) -> Mat2x2<RealToReal<2, Dest, Src>>

Returns the inverse of self, if it exists.

A matrix is invertible if and only if its determinant is nonzero. A non-invertible matrix is also called singular.

§Panics

If self has no inverse.

§Examples
use retrofire_core::math::{Mat2x2, mat::RealToReal, vec2};

let rotate_90: Mat2x2<RealToReal<2>> = [[0.0, -1.0], [1.0, 0.0]].into();
let rotate_neg_90 = rotate_90.inverse();

assert_eq!(rotate_neg_90.0, [[0.0, 1.0], [-1.0, 0.0]]);
assert_eq!(rotate_90.then(&rotate_neg_90), Mat2x2::identity())

// This matrix has no inverse
let singular: Mat2x2<RealToReal<2>> = [[1.0, 0.0], [2.0, 0.0]].into();

// This will panic
let _ = singular.inverse();
Source§

impl<Src, Dest> Matrix<[[f32; 3]; 3], RealToReal<2, Src, Dest>>

Source

pub const fn determinant(&self) -> f32

Returns the determinant of self.

Source

pub const fn cofactor(&self, row: usize, col: usize) -> f32

Returns the cofactor of the element at the given row and column.

Cofactors are used to compute the inverse of a matrix. A cofactor is calculated as follows:

  1. Remove the given row and column from self to get a 2x2 submatrix;
  2. Compute its determinant;
  3. If exactly one of row and col is even, multiply by -1.
§Examples
use retrofire_core::{mat, math::Mat3x3, math::mat::RealToReal};

let mat: Mat3x3<RealToReal<2>> = mat![
    1.0, 2.0, 3.0;
    4.0, 5.0, 6.0;
    7.0, 8.0, 9.0
];
// Remove row 0 and col 1, giving [[4.0, 6.0], [7.0, 9.0]].
// The determinant of this submatrix is 4.0 * 7.0 - 6.0 * 9.0.
// Multiply by -1 because row is even and col is odd.
assert_eq!(mat.cofactor(0, 1), 6.0 * 7.0 - 4.0 * 9.0);
Source

pub fn checked_inverse(&self) -> Option<Mat3x3<RealToReal<2, Dest, Src>>>

Returns the inverse of self, or None if self is singular.

Source

pub fn inverse(&self) -> Mat3x3<RealToReal<2, Dest, Src>>

Source§

impl<Src, Dst> Matrix<[[f32; 4]; 4], RealToReal<3, Src, Dst>>

Source

pub fn determinant(&self) -> f32

Returns the determinant of self.

Given a matrix M,

        ⎛ a  b  c  d ⎞
 M  =   ⎜ e  f  g  h ⎟
        ⎜ i  j  k  l ⎟
        ⎝ m  n  o  p ⎠

its determinant can be computed by recursively computing the determinants of sub-matrices on rows 1..4 and multiplying them by the elements on row 0:

             ⎜ f g h ⎜       ⎜ e g h ⎜
det(M) = a · ⎜ j k l ⎜ - b · ⎜ i k l ⎜  + - ···
             ⎜ n o p ⎜       ⎜ m o p ⎜
Source

pub fn inverse(&self) -> Mat4x4<RealToReal<3, Dst, Src>>

Returns the inverse matrix of self.

The inverse 𝝡-1 of matrix 𝝡 is a matrix that, when composed with 𝝡, results in the identity matrix:

𝝡 ∘ 𝝡-1 = 𝝡-1 ∘ 𝝡 = 𝐈

In other words, it applies the transform of 𝝡 in reverse. Given vectors 𝘃 and 𝘂,

𝝡𝘃 = 𝘂 ⇔ 𝝡-1 𝘂 = 𝘃.

Only matrices with a nonzero determinant have a defined inverse. A matrix without an inverse is said to be singular.

Note: This method uses naive Gauss–Jordan elimination and may suffer from imprecision or numerical instability in certain cases.

§Panics

If debug assertions are enabled, panics if self is singular or near-singular. If not enabled, the return value is unspecified and may contain non-finite values (infinities and NaNs).

Trait Implementations§

Source§

impl<Repr, E, M> ApproxEq<Matrix<Repr, M>, E> for Matrix<Repr, M>
where Repr: ApproxEq<Repr, E>,

Source§

fn approx_eq_eps(&self, other: &Self, rel_eps: &E) -> bool

Returns whether self and other are approximately equal, using the relative epsilon rel_eps.
Source§

fn relative_epsilon() -> E

Returns the default relative epsilon of type E.
Source§

fn approx_eq(&self, other: &Other) -> bool

Returns whether self and other are approximately equal. Uses the epsilon returned by Self::relative_epsilon.
Source§

impl<R: Clone, M> Clone for Matrix<R, M>

Source§

fn clone(&self) -> Self

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<S: Debug, Map: Debug + Default, const N: usize, const M: usize> Debug for Matrix<[[S; N]; M], Map>

Source§

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

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

impl<const N: usize, Map> Default for Matrix<[[f32; N]; N], Map>

Source§

fn default() -> Self

Returns the N×N identity matrix.

Source§

impl<Repr, M> From<Repr> for Matrix<Repr, M>

Source§

fn from(repr: Repr) -> Self

Converts to this type from the input type.
Source§

impl<Repr: PartialEq, Map: PartialEq> PartialEq for Matrix<Repr, Map>

Source§

fn eq(&self, other: &Matrix<Repr, Map>) -> 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<Repr: Copy, Map: Copy> Copy for Matrix<Repr, Map>

Source§

impl<Repr: Eq, Map: Eq> Eq for Matrix<Repr, Map>

Source§

impl<Repr, Map> StructuralPartialEq for Matrix<Repr, Map>

Auto Trait Implementations§

§

impl<Repr, Map> Freeze for Matrix<Repr, Map>
where Repr: Freeze,

§

impl<Repr, Map> RefUnwindSafe for Matrix<Repr, Map>
where Repr: RefUnwindSafe, Map: RefUnwindSafe,

§

impl<Repr, Map> Send for Matrix<Repr, Map>
where Repr: Send, Map: Send,

§

impl<Repr, Map> Sync for Matrix<Repr, Map>
where Repr: Sync, Map: Sync,

§

impl<Repr, Map> Unpin for Matrix<Repr, Map>
where Repr: Unpin, Map: Unpin,

§

impl<Repr, Map> UnwindSafe for Matrix<Repr, Map>
where Repr: UnwindSafe, Map: 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<!> for T

Source§

fn from(t: !) -> T

Converts to this type from the input type.
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, 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.