#[repr(transparent)]pub struct Matrix<Repr, Map>(pub Repr, _);Expand description
A generic matrix type.
Tuple Fields§
§0: ReprImplementations§
Source§impl<Repr, Map> Matrix<Repr, Map>
impl<Repr, Map> Matrix<Repr, Map>
Sourcepub fn to<M>(&self) -> Matrix<Repr, M>where
Repr: Clone,
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?
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>
impl<Sc, const N: usize, const M: usize, Map> Matrix<[[Sc; N]; M], Map>
Source§impl<Sc: Copy, const N: usize, const DIM: usize, S, D> Matrix<[[Sc; N]; N], RealToReal<DIM, S, D>>
impl<Sc: Copy, const N: usize, const DIM: usize, S, D> Matrix<[[Sc; N]; N], RealToReal<DIM, S, D>>
Source§impl<const N: usize, Map> Matrix<[[f32; N]; N], Map>
impl<const N: usize, Map> Matrix<[[f32; N]; N], Map>
Sourcepub const fn identity() -> Self
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], ()>
impl Matrix<[[f32; 4]; 4], ()>
Sourcepub const fn from_linear<S, D>(
i: Vec3<D>,
j: Vec3<D>,
k: Vec3<D>,
) -> Mat4x4<RealToReal<3, S, D>>
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.
Sourcepub const fn from_affine<S, D>(
i: Vec3<D>,
j: Vec3<D>,
k: Vec3<D>,
o: Point3<D>,
) -> Mat4x4<RealToReal<3, S, D>>
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>
impl<Sc, const N: usize, Map> Matrix<[[Sc; N]; N], Map>
Sourcepub fn compose<Inner: LinearMap>(
&self,
other: &Matrix<[[Sc; N]; N], Inner>,
) -> Matrix<[[Sc; N]; N], <Map as Compose<Inner>>::Result>where
Map: Compose<Inner>,
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 𝘃.
Sourcepub fn then<Outer: Compose<Map>>(
&self,
other: &Matrix<[[Sc; N]; N], Outer>,
) -> Matrix<[[Sc; N]; N], <Outer as Compose<Map>>::Result>
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?
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>>
impl<Src, Dest> Matrix<[[f32; 2]; 2], RealToReal<2, Src, Dest>>
Sourcepub const fn determinant(&self) -> f32
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);Sourcepub const fn checked_inverse(&self) -> Option<Mat2x2<RealToReal<2, Dest, Src>>>
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);Sourcepub const fn inverse(&self) -> Mat2x2<RealToReal<2, Dest, Src>>
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>>
impl<Src, Dest> Matrix<[[f32; 3]; 3], RealToReal<2, Src, Dest>>
Sourcepub const fn determinant(&self) -> f32
pub const fn determinant(&self) -> f32
Returns the determinant of self.
Sourcepub const fn cofactor(&self, row: usize, col: usize) -> f32
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:
- Remove the given row and column from
selfto get a 2x2 submatrix; - Compute its determinant;
- If exactly one of
rowandcolis 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);Sourcepub fn checked_inverse(&self) -> Option<Mat3x3<RealToReal<2, Dest, Src>>>
pub fn checked_inverse(&self) -> Option<Mat3x3<RealToReal<2, Dest, Src>>>
Returns the inverse of self, or None if self is singular.
pub fn inverse(&self) -> Mat3x3<RealToReal<2, Dest, Src>>
Source§impl<Src, Dst> Matrix<[[f32; 4]; 4], RealToReal<3, Src, Dst>>
impl<Src, Dst> Matrix<[[f32; 4]; 4], RealToReal<3, Src, Dst>>
Sourcepub fn determinant(&self) -> f32
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 ⎜Sourcepub fn inverse(&self) -> Mat4x4<RealToReal<3, Dst, Src>>
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>,
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
fn approx_eq_eps(&self, other: &Self, rel_eps: &E) -> bool
self and other are approximately equal,
using the relative epsilon rel_eps.Source§fn relative_epsilon() -> E
fn relative_epsilon() -> E
E.