Skip to content

Commit

Permalink
impl Outermorphism for UniformScale
Browse files Browse the repository at this point in the history
  • Loading branch information
ickk committed May 5, 2024
1 parent 637903a commit 5a6fc90
Show file tree
Hide file tree
Showing 2 changed files with 213 additions and 0 deletions.
3 changes: 3 additions & 0 deletions ega/src/outermorphisms/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
mod matrix_4x4;
mod uniform_scale;

pub use matrix_4x4::Matrix4x4;
pub use uniform_scale::UniformScale;

/// A linear mapping extended to multivectors
pub trait Outermorphism<Arg> {
Expand Down
210 changes: 210 additions & 0 deletions ega/src/outermorphisms/uniform_scale.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
use crate::*;

#[derive(Debug, Copy, Clone)]
pub struct UniformScale {
pub scale: f32,
}

impl UniformScale {
#[inline]
pub fn new(scale: f32) -> Self {
UniformScale { scale }
}
}

macro_rules! impl_outermorphism {
($morph_fn:ident: $morph:ty, $arg:ty => $ret:ty) => {
impl Outermorphism<$arg> for $morph {
fn morph(self, arg: $arg) -> $ret {
$morph_fn(self, arg)
}
}
};
}

impl_outermorphism! { return_empty: UniformScale, Empty => Empty }
impl_outermorphism! { uniform_scale_morph_scalar: UniformScale, Scalar => Scalar }
impl_outermorphism! { uniform_scale_morph_vector: UniformScale, Vector => Vector }
impl_outermorphism! { uniform_scale_morph_bivector: UniformScale, Bivector => Bivector }
impl_outermorphism! { uniform_scale_morph_trivector: UniformScale, Trivector => Trivector }
impl_outermorphism! { uniform_scale_morph_pseudo_scalar: UniformScale, Pseudoscalar => Pseudoscalar }
impl_outermorphism! { uniform_scale_morph_multivector: UniformScale, Multivector => Multivector }

#[inline]
fn uniform_scale_morph_scalar(_: UniformScale, s: Scalar) -> Scalar {
s
}

#[rustfmt::skip]
#[inline]
fn uniform_scale_morph_vector(
UniformScale { scale }: UniformScale,
Vector { mut e0, mut e1, mut e2, mut e3 }: Vector
) -> Vector {

e0 *= scale;
e1 *= scale;
e2 *= scale;
e3 *= scale;

Vector { e0, e1, e2, e3 }
}

#[rustfmt::skip]
#[inline]
fn uniform_scale_morph_bivector(
UniformScale { scale }: UniformScale,
Bivector {
mut e23, mut e31, mut e12,
mut e01, mut e02, mut e03,
}: Bivector
) -> Bivector {

let scale2 = scale*scale;

e23 *= scale2;
e03 *= scale2;
e31 *= scale2;
e01 *= scale2;
e12 *= scale2;
e02 *= scale2;

Bivector { e23, e31, e12, e01, e02, e03 }
}

#[rustfmt::skip]
#[inline]
fn uniform_scale_morph_trivector(
UniformScale { scale }: UniformScale,
Trivector { mut e123, mut e032, mut e013, mut e021 }: Trivector
) -> Trivector {

let scale3 = scale.powi(3);

e123 *= scale3;
e032 *= scale3;
e013 *= scale3;
e021 *= scale3;

Trivector {
e123, e032, e013, e021
}
}

#[rustfmt::skip]
#[inline]
fn uniform_scale_morph_pseudo_scalar(
UniformScale { scale }: UniformScale,
Pseudoscalar {
mut e0123
}: Pseudoscalar,
) -> Pseudoscalar {

e0123 *= scale.powi(4);

Pseudoscalar { e0123 }
}

#[rustfmt::skip]
#[inline]
fn uniform_scale_morph_multivector(
UniformScale { scale }: UniformScale,
Multivector {
mut e0, mut e1, mut e2, mut e3,
s, mut e23, mut e31, mut e12,
mut e01, mut e02, mut e03, mut e0123,
mut e123, mut e032, mut e013, mut e021,
}: Multivector,
) -> Multivector {

let scale2 = scale*scale;
let scale3 = scale*scale2;
let scale4 = scale2*scale2;

e0 *= scale;
e1 *= scale;
e2 *= scale;
e3 *= scale;
e23 *= scale2;
e03 *= scale2;
e31 *= scale2;
e01 *= scale2;
e12 *= scale2;
e02 *= scale2;
e123 *= scale3;
e032 *= scale3;
e013 *= scale3;
e021 *= scale3;
e0123 *= scale4;

Multivector {
e0, e1, e2, e3,
s, e23, e31, e12,
e01, e02, e03, e0123,
e123, e032, e013, e021,
}
}

#[cfg(any(test, doctest))]
mod tests {
use super::*;
use crate::test_values::*;
use ::approx::assert_ulps_eq;

#[test]
fn morph_scalar() {
let scale = UniformScale::new(3.0);

let result = scale.morph(SCALAR_A);
let expected = SCALAR_A;
assert_eq!(dbg!(result), dbg!(expected));
}

#[test]
#[rustfmt::skip]
fn morph_vector() {
let scale = UniformScale::new(3.0);

let result = scale.morph(VECTOR_A);
let expected = Vector {
e0: 453., e1: 471., e2: 489., e3: 501.,
};
assert_ulps_eq!(dbg!(result), dbg!(expected), max_ulps = 2);
}

#[test]
fn morph_bivector() {
let scale = UniformScale::new(3.0);

let a = Meet::meet(scale.morph(VECTOR_A), scale.morph(VECTOR_B));
let b = scale.morph(Meet::meet(VECTOR_A, VECTOR_B));
assert_ulps_eq!(dbg!(a), dbg!(b), max_ulps = 90);
}

#[test]
fn morph_trivector() {
let scale = UniformScale::new(3.0);

let a = Meet::meet(scale.morph(VECTOR_A), scale.morph(BIVECTOR_A));
let b = scale.morph(Meet::meet(VECTOR_A, BIVECTOR_A));
assert_ulps_eq!(dbg!(a), dbg!(b), max_ulps = 2);
}

#[test]
fn morph_pseudoscalar() {
let scale = UniformScale::new(3.0);

let a = Meet::meet(scale.morph(VECTOR_A), scale.morph(TRIVECTOR_A));
let b = scale.morph(Meet::meet(VECTOR_A, TRIVECTOR_A));
assert_ulps_eq!(dbg!(a), dbg!(b), max_ulps = 1);
}

#[test]
fn morph_multivector() {
let scale = UniformScale::new(3.0);

let a = Meet::meet(scale.morph(MULTIVECTOR_A), scale.morph(MULTIVECTOR_B));
let b = scale.morph(Meet::meet(MULTIVECTOR_A, MULTIVECTOR_B));
assert_ulps_eq!(dbg!(a), dbg!(b), max_ulps = 10);
}
}

0 comments on commit 5a6fc90

Please sign in to comment.