ccgeom/euclidean/
geometry.rs

1use std::marker::PhantomData;
2use num_traits::{Zero};
3use vecmat::{Vector, transform::{Transform, Shift, Rotation3}};
4use crate::{Geometry, Geometry3, Scalar};
5use super::Homogenous3;
6
7#[derive(Clone)]
8enum EmptyEnum {}
9
10#[allow(dead_code)]
11#[derive(Clone)]
12pub struct Euclidean3<T: Scalar = f64> {
13    phantom: PhantomData<T>,
14    empty_enum: EmptyEnum,
15}
16
17impl<T: Scalar> Euclidean3<T> {
18    /// Transformation that translates `pos` to the origin.
19    fn shift(pos: <Self as Geometry<T>>::Pos) -> <Self as Geometry<T>>::Map {
20        Homogenous3::new(pos.into(), Rotation3::identity())
21    }
22    fn rotate(axis: <Self as Geometry<T>>::Dir, phi: T) -> <Self as Geometry<T>>::Map {
23        Homogenous3::new(Shift::identity(), Rotation3::new(axis, phi))
24    }
25}
26
27impl<T: Scalar> Geometry<T> for Euclidean3<T> {
28    type Pos = Vector<T, 3>;
29    type Dir = Vector<T, 3>;
30    type Map = Homogenous3<T>;
31
32    fn origin() -> Self::Pos {
33        Self::Pos::zero()
34    }
35    fn default_dir() -> Self::Dir {
36        Self::Dir::from([T::zero(), T::zero(), -T::one()])
37    }
38
39    fn length(a: Self::Pos) -> T {
40        a.length()
41    }
42    fn distance(a: Self::Pos, b: Self::Pos) -> T {
43        (a - b).length()
44    }
45}
46
47impl<T: Scalar> Geometry3<T> for Euclidean3<T> {
48    fn dir_to_local(_pos: Self::Pos, dir: Self::Dir) -> Self::Dir {
49        dir
50    }
51    fn dir_from_local(_pos: Self::Pos, dir: Self::Dir) -> Self::Dir {
52        dir
53    }
54
55    fn dir_when_moved_at_pos(_src_pos: Self::Pos, src_dir: Self::Dir, _dst_pos: Self::Pos) -> Self::Dir {
56        src_dir
57    }
58
59    fn shift_x(dist: T) -> Self::Map {
60        Self::shift(Vector::from([dist, T::zero(), T::zero()]))
61    }
62    fn shift_y(dist: T) -> Self::Map {
63        Self::shift(Vector::from([T::zero(), dist, T::zero()]))
64    }
65    fn shift_z(dist: T) -> Self::Map {
66        Self::shift(Vector::from([T::zero(), T::zero(), dist]))
67    }
68
69    fn rotate_x(angle: T) -> Self::Map {
70        Self::rotate(Vector::from([T::one(), T::zero(), T::zero()]), angle)
71    }
72    fn rotate_y(angle: T) -> Self::Map {
73        Self::rotate(Vector::from([T::zero(), T::one(), T::zero()]), angle)
74    }
75    fn rotate_z(angle: T) -> Self::Map {
76        Self::rotate(Vector::from([T::zero(), T::zero(), T::one()]), angle)
77    }
78
79    fn look_at_pos(pos: Self::Pos) -> Self::Map {
80        Self::look_at_dir(pos.normalize())
81    }
82    fn look_at_dir(dir: Self::Dir) -> Self::Map {
83        Homogenous3::new(Shift::identity(), Rotation3::look_at_any(dir))
84    }
85
86    fn move_at_pos(pos: Self::Pos) -> Self::Map {
87        Self::shift(pos)
88    }
89    fn move_at_dir(dir: Self::Dir, dist: T) -> Self::Map {
90        Self::move_at_pos(dir * dist)
91    }
92}