-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement 4x4
Matrix
as Outermorphism
wip
- impl for `Scalar`, `Vector`, `Bivector`
- Loading branch information
Showing
3 changed files
with
129 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
use super::impl_outermorphism; | ||
use crate::*; | ||
|
||
/// A matrix whose column vectors have basis [e0, e1, e2, e3] | ||
/// | ||
/// Note: This is different to matrices from other libraries, which often have | ||
/// a basis ordered more like [e1, e2, e3, e0] (homogeneous coordinates) | ||
#[rustfmt::skip] | ||
#[derive(Debug, Copy, Clone)] | ||
pub struct Matrix { | ||
pub m00: f32, pub m01: f32, pub m02: f32, pub m03: f32, | ||
pub m10: f32, pub m11: f32, pub m12: f32, pub m13: f32, | ||
pub m20: f32, pub m21: f32, pub m22: f32, pub m23: f32, | ||
pub m30: f32, pub m31: f32, pub m32: f32, pub m33: f32, | ||
} | ||
|
||
impl_outermorphism! { matrix_morph_scalar: Matrix, Scalar => Scalar } | ||
impl_outermorphism! { matrix_morph_vector: Matrix, Vector => Vector } | ||
impl_outermorphism! { matrix_morph_bivector: Matrix, Bivector => Bivector } | ||
|
||
fn matrix_morph_scalar(_: Matrix, s: Scalar) -> Scalar { | ||
s | ||
} | ||
|
||
#[rustfmt::skip] | ||
fn matrix_morph_vector(m: Matrix, v: Vector) -> Vector { | ||
let Matrix { | ||
m00, m01, m02, m03, | ||
m10, m11, m12, m13, | ||
m20, m21, m22, m23, | ||
m30, m31, m32, m33, | ||
} = m; | ||
let Vector { e0: v0, e1: v1, e2: v2, e3: v3 } = v; | ||
|
||
let e0 = m00*v0 + m01*v1 + m02*v2 + m03*v3; | ||
let e1 = m10*v0 + m11*v1 + m12*v2 + m13*v3; | ||
let e2 = m20*v0 + m21*v1 + m22*v2 + m23*v3; | ||
let e3 = m30*v0 + m31*v1 + m32*v2 + m33*v3; | ||
|
||
Vector { e0, e1, e2, e3 } | ||
} | ||
|
||
#[rustfmt::skip] | ||
fn matrix_morph_bivector(m: Matrix, b: Bivector) -> Bivector { | ||
let Matrix { | ||
m00, m01, m02, m03, | ||
m10, m11, m12, m13, | ||
m20, m21, m22, m23, | ||
m30, m31, m32, m33, | ||
} = m; | ||
let Bivector { | ||
e23: b23, e31: b31, e12: b12, | ||
e01: b01, e02: b02, e03: b03, | ||
} = b; | ||
|
||
let w1 = m11*b01 + m12*b02 + m13*b03; | ||
let x1 = -m10*b01 + m12*b12 - m13*b31; | ||
let y1 = -m10*b02 - m11*b12 + m13*b23; | ||
let z1 = -m10*b03 + m11*b31 - m12*b23; | ||
|
||
let w2 = m21*b01 + m22*b02 + m23*b03; | ||
let x2 = -m20*b01 + m22*b12 - m23*b31; | ||
let y2 = -m20*b02 - m21*b12 + m23*b23; | ||
let z2 = -m20*b03 + m21*b31 - m22*b23; | ||
|
||
let w3 = m31*b01 + m32*b02 + m33*b03; | ||
let x3 = -m30*b01 + m32*b12 - m33*b31; | ||
let y3 = -m30*b02 - m31*b12 + m33*b23; | ||
let z3 = -m30*b03 + m31*b31 - m32*b23; | ||
|
||
let e23 = m20*w3 + m21*x3 + m22*y3 + m23*z3; | ||
let e31 = m30*w1 + m31*x1 + m32*y1 + m33*z1; | ||
let e12 = m10*w2 + m11*x2 + m12*y2 + m13*z2; | ||
let e01 = m00*w1 + m01*x1 + m02*y1 + m03*z1; | ||
let e02 = m00*w2 + m01*x2 + m02*y2 + m03*z2; | ||
let e03 = m00*w3 + m01*x3 + m02*y3 + m03*z3; | ||
|
||
Bivector { e23, e31, e12, e01, e02, e03 } | ||
} | ||
|
||
#[rustfmt::skip] | ||
#[cfg(any(test, doctest))] | ||
mod tests { | ||
use super::*; | ||
use crate::test_values::*; | ||
|
||
#[test] | ||
fn matrix_morph_vector() { | ||
let result = MATRIX_A.morph(VECTOR_A); | ||
let expected = Vector { e0: 1622., e1: 4174., e2: 6726., e3: 9278. }; | ||
assert_eq!(dbg!(result), dbg!(expected)); | ||
} | ||
|
||
#[test] | ||
fn matrix_morph_bivector() { | ||
let a = Meet::meet(MATRIX_A.morph(VECTOR_A), MATRIX_A.morph(VECTOR_B)); | ||
let b = MATRIX_A.morph(Meet::meet(VECTOR_A, VECTOR_B)); | ||
|
||
assert_eq!(dbg!(a), dbg!(b)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
mod matrix; | ||
pub use matrix::Matrix; | ||
|
||
/// A linear mapping extended to multivectors | ||
pub trait Outermorphism<Arg> { | ||
fn morph(self, arg: Arg) -> Arg; | ||
} | ||
|
||
macro_rules! impl_outermorphism { | ||
($morph_fn:ident: $morph:ty, $arg:ty => $ret:ty) => { | ||
impl crate::Outermorphism<$arg> for $morph { | ||
#[inline] | ||
fn morph(self, arg: $arg) -> $ret { | ||
$morph_fn(self, arg) | ||
} | ||
} | ||
}; | ||
} | ||
pub(crate) use impl_outermorphism; |