1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//!
//! Structs to dereference the algebraic types into to access their elements as if they
//! were fields.
//!
//! This module mostly just wraps [`na::base::coordinates`], but a couple extra structs were added
//! in order to support some of the structures unique to this crate
//!

use std::ops::{Deref, DerefMut};

use na::Scalar;

use crate::algebra::*;
pub use na::base::coordinates::*;

/// Fields for scalar and psuedoscalar types
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub struct ScalarCoords<T:Scalar> {
    pub value: T,
}

/// Fields specifically for 4D bivectors
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub struct BiVec4Coords<T:Scalar> {
    pub yz: T,
    pub zx: T,
    pub xy: T,
    pub xw: T,
    pub yw: T,
    pub zw: T,
}

/// Fields for 2D [`Even`]s that emulate the components of complex numbers
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub struct ReIm<T:Scalar> {
    pub re:T,
    pub im:T,
}

///
/// Fields for 3D [`Even`]s that emulate the components of quaternions
///
/// The order here is different from `nalgebra`'s [quaternions](na::geometry::Quaternion).
/// (`nalgebra` uses [ijkw](IJKW) order)
///
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub struct WIJK<T:Scalar> {
    pub w:T,
    pub i:T,
    pub j:T,
    pub k:T
}

macro_rules! impl_coords {
    ($($Ty:ident = $Coords:ident;)*) => {
        $(
            impl<T:Scalar> Deref for $Ty<T> {
                type Target = $Coords<T>;
                fn deref(&self) -> &$Coords<T> {
                    unsafe {
                        &*(&self[0] as *const T as *const $Coords::<T>)
                    }
                }
            }

            impl<T:Scalar> DerefMut for $Ty<T> {
                fn deref_mut(&mut self) -> &mut $Coords<T> {
                    unsafe {
                        &mut *(&mut self[0] as *mut T as *mut $Coords::<T>)
                    }
                }
            }
        )*
    }
}

impl_coords! {

    //Scalars
    Scalar0 = ScalarCoords;
    Scalar1 = ScalarCoords;
    Scalar2 = ScalarCoords;
    Scalar3 = ScalarCoords;
    Scalar4 = ScalarCoords;
    Scalar5 = ScalarCoords;
    Scalar6 = ScalarCoords;

    //Vectors
    Vec1 = X;
    Vec2 = XY;
    Vec3 = XYZ;
    Vec4 = XYZW;
    Vec5 = XYZWA;
    Vec6 = XYZWAB;

    //BiVec4
    BiVec4 = BiVec4Coords;

    //Psuedovectors
    BiVec3   = XYZ;
    TriVec4  = XYZW;
    QuadVec5 = XYZWA;
    PentVec6 = XYZWAB;

    //Psuedoscalars
    BiVec2   = ScalarCoords;
    TriVec3  = ScalarCoords;
    QuadVec4 = ScalarCoords;
    PentVec5 = ScalarCoords;
    HexVec6  = ScalarCoords;

    //The even algebras as Complex numbers and quaternions
    Even2 = ReIm;
    Even3 = WIJK;

}