vecmat/transform/
shift.rs

1#[cfg(feature = "rand")]
2use crate::distr::Normal;
3use crate::{Transform, Vector, transform::Directional};
4#[cfg(feature = "approx")]
5use approx::{abs_diff_eq, AbsDiffEq};
6use core::ops::Neg;
7use num_traits::{Num, Zero};
8#[cfg(feature = "rand")]
9use rand_::{distributions::Distribution, Rng};
10
11/// Shift transformation.
12#[repr(transparent)]
13#[derive(Clone, Copy, PartialEq, Debug)]
14pub struct Shift<T, const N: usize> {
15    pos: Vector<T, N>,
16}
17
18pub type Shift2<T> = Shift<T, 2>;
19pub type Shift3<T> = Shift<T, 3>;
20pub type Shift4<T> = Shift<T, 4>;
21
22impl<T, const N: usize> Shift<T, N> {
23    pub fn from_vector(pos: Vector<T, N>) -> Self {
24        Self { pos }
25    }
26    pub fn into_vector(self) -> Vector<T, N> {
27        self.pos
28    }
29}
30impl<T, const N: usize> From<Vector<T, N>> for Shift<T, N> {
31    fn from(pos: Vector<T, N>) -> Self {
32        Self::from_vector(pos)
33    }
34}
35impl<T, const N: usize> From<Shift<T, N>> for Vector<T, N> {
36    fn from(shift: Shift<T, N>) -> Self {
37        shift.into_vector()
38    }
39}
40
41impl<T, const N: usize> Transform<Vector<T, N>> for Shift<T, N>
42where
43    T: Neg<Output = T> + Num + Copy,
44{
45    fn identity() -> Self {
46        Self {
47            pos: Vector::zero(),
48        }
49    }
50    fn inv(self) -> Self {
51        Self { pos: -self.pos }
52    }
53    fn apply(&self, pos: Vector<T, N>) -> Vector<T, N> {
54        pos + self.pos
55    }
56    fn deriv(&self, _pos: Vector<T, N>, dir: Vector<T, N>) -> Vector<T, N> {
57        dir
58    }
59    fn chain(self, other: Self) -> Self {
60        Self {
61            pos: self.pos + other.pos,
62        }
63    }
64}
65
66impl<T, const N: usize> Directional<Vector<T, N>> for Shift<T, N>
67where
68    Self: Transform<Vector<T, N>>
69{
70    fn apply_dir(&self, _: Vector<T, N>, dir: Vector<T, N>) -> Vector<T, N> {
71        dir
72    }
73    fn apply_normal(&self, _: Vector<T, N>, normal: Vector<T, N>) -> Vector<T, N> {
74        normal
75    }
76}
77
78#[cfg(feature = "rand")]
79impl<T, const N: usize> Distribution<Shift<T, N>> for Normal
80where
81    Normal: Distribution<Vector<T, N>>,
82{
83    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Shift<T, N> {
84        Shift::from(self.sample(rng))
85    }
86}
87
88#[cfg(feature = "approx")]
89impl<T, const N: usize> AbsDiffEq for Shift<T, N>
90where
91    T: AbsDiffEq<Epsilon = T> + Copy,
92{
93    type Epsilon = T;
94    fn default_epsilon() -> Self::Epsilon {
95        T::default_epsilon()
96    }
97    fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
98        abs_diff_eq!(self.pos, other.pos, epsilon = epsilon)
99    }
100}