Skip to content

Commit

Permalink
implement 4x4 Matrix as Outermorphism wip
Browse files Browse the repository at this point in the history
- impl for `Scalar`, `Vector`, `Bivector`
  • Loading branch information
ickk committed May 4, 2024
1 parent a6ae309 commit 03b3cae
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 0 deletions.
9 changes: 9 additions & 0 deletions ega/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ use ::libm::Libm;

mod operators;
mod optional_features;
mod outermorphisms;
mod values;

pub use operators::*;
pub use outermorphisms::*;
pub use values::*;

#[rustfmt::skip]
Expand Down Expand Up @@ -83,4 +85,11 @@ mod test_values {
pub const PSEUDOSCALAR_A: Pseudoscalar = Pseudoscalar { e0123: 397. };
pub const PSEUDOSCALAR_B: Pseudoscalar = Pseudoscalar { e0123: 401. };
pub const PSEUDOSCALAR_C: Pseudoscalar = Pseudoscalar { e0123: -409. };

pub const MATRIX_A: Matrix = Matrix {
m00: 1.0, m01: 2.0, m02: 3.0, m03: 4.0,
m10: 5.0, m11: 6.0, m12: 7.0, m13: 8.0,
m20: 9.0, m21: 10.0, m22: 11.0, m23: 12.0,
m30: 13.0, m31: 14.0, m32: 15.0, m33: 16.0,
};
}
101 changes: 101 additions & 0 deletions ega/src/outermorphisms/matrix.rs
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));
}
}
19 changes: 19 additions & 0 deletions ega/src/outermorphisms/mod.rs
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;

0 comments on commit 03b3cae

Please sign in to comment.