Skip to main content

ear_algae/
normal.rs

1use std::{
2    array,
3    ops::{Add, Div, Index, Mul, Neg, Sub},
4};
5
6use culit::culit;
7
8use crate::{
9    Vect,
10    op_wrapper::Sc,
11    ops::Dot,
12    ops::{AngleTo, Cross, ProjRej},
13    traits::Field,
14};
15
16#[derive(Copy, Clone, PartialEq, Eq, Hash)]
17pub struct Nrml<const N: usize, S: Field>([S; N]);
18
19impl<S: Field, const N: usize> Nrml<N, S> {
20    /// .
21    ///
22    /// # Safety
23    ///
24    /// This is safe if the values are actually normalized.
25    ///
26    /// They should have just been divided by their magnitude.
27    ///
28    /// .
29    pub const unsafe fn new_unchecked(array: [S; N]) -> Nrml<N, S> {
30        Nrml(array)
31    }
32
33    #[culit]
34    pub const fn axis(i: usize) -> Self {
35        let mut v = [0S; N];
36        v[i] = 1S;
37        Self(v)
38    }
39}
40
41impl<const N: usize> Nrml<N, f32> {
42    pub fn to_f64(self) -> Nrml<N, f64> {
43        Nrml(self.0.map(|x| x as _))
44    }
45}
46
47impl<const N: usize> Nrml<N, f64> {
48    pub fn to_f32(self) -> Nrml<N, f32> {
49        Nrml(self.0.map(|x| x as _))
50    }
51}
52
53impl<S: Field, const N: usize> From<Nrml<N, S>> for Vect<N, S> {
54    fn from(value: Nrml<N, S>) -> Self {
55        Vect(value.0)
56    }
57}
58
59impl<S: Field, const N: usize> Index<usize> for Nrml<N, S> {
60    type Output = S;
61
62    fn index(&self, i: usize) -> &Self::Output {
63        &self.0[i]
64    }
65}
66
67impl<S: Field, const N: usize> Nrml<N, S> {
68    pub fn array(self) -> [S; N] {
69        self.0
70    }
71}
72
73impl<S: Field, const N: usize> Add for Nrml<N, S> {
74    type Output = Vect<N, S>;
75
76    fn add(self, rhs: Self) -> Self::Output {
77        Vect::from_fn(|i| self[i].add(rhs[i]))
78    }
79}
80
81impl<S: Field, const N: usize> Add<Vect<N, S>> for Nrml<N, S> {
82    type Output = Vect<N, S>;
83
84    fn add(self, rhs: Vect<N, S>) -> Self::Output {
85        Vect::from_fn(|i| self[i].add(rhs[i]))
86    }
87}
88
89impl<S: Field, const N: usize> Add<Nrml<N, S>> for Vect<N, S> {
90    type Output = Vect<N, S>;
91
92    fn add(self, rhs: Nrml<N, S>) -> Self::Output {
93        Vect::from_fn(|i| self[i].add(rhs[i]))
94    }
95}
96
97impl<S: Field, const N: usize> Sub for Nrml<N, S> {
98    type Output = Vect<N, S>;
99
100    fn sub(self, rhs: Self) -> Self::Output {
101        Vect::from_fn(|i| self[i].sub(rhs[i]))
102    }
103}
104
105impl<S: Field, const N: usize> Sub<Vect<N, S>> for Nrml<N, S> {
106    type Output = Vect<N, S>;
107
108    fn sub(self, rhs: Vect<N, S>) -> Self::Output {
109        Vect::from_fn(|i| self[i].sub(rhs[i]))
110    }
111}
112
113impl<S: Field, const N: usize> Sub<Nrml<N, S>> for Vect<N, S> {
114    type Output = Vect<N, S>;
115
116    fn sub(self, rhs: Nrml<N, S>) -> Self::Output {
117        Vect::from_fn(|i| self[i].sub(rhs[i]))
118    }
119}
120
121impl<S: Field, const N: usize> Neg for Nrml<N, S> {
122    type Output = Self;
123
124    fn neg(self) -> Self::Output {
125        Self(array::from_fn(|i| self[i].neg()))
126    }
127}
128
129impl<S: Field, const N: usize> Mul<S> for Nrml<N, S> {
130    type Output = Vect<N, S>;
131
132    fn mul(self, rhs: S) -> Self::Output {
133        Vect::from_fn(|i| self[i].mul(rhs))
134    }
135}
136
137impl<S: Field, const N: usize> Div<S> for Nrml<N, S> {
138    type Output = Vect<N, S>;
139
140    fn div(self, rhs: S) -> Self::Output {
141        Vect::from_fn(|i| self[i].div(rhs))
142    }
143}
144
145impl<S: Field, const N: usize> Dot<Self> for Nrml<N, S> {
146    #[culit]
147    fn dot(self, other: Self) -> S {
148        let dot = (0..N)
149            .map(|i| self[i].mul(other[i]))
150            .fold(S::ZERO, |c, n| c.add(n));
151        if dot > S::ONE {
152            S::ONE
153        } else if Sc(dot) < -1Sc {
154            (-1Sc).0
155        } else {
156            dot
157        }
158    }
159
160    type Output = S;
161}
162
163impl<S: Field, const N: usize> Dot<Vect<N, S>> for Nrml<N, S> {
164    fn dot(self, other: Vect<N, S>) -> S {
165        Vect::from(self).dot(other)
166    }
167
168    type Output = S;
169}
170
171impl<S: Field, const N: usize> Dot<Nrml<N, S>> for Vect<N, S> {
172    fn dot(self, other: Nrml<N, S>) -> S {
173        self.dot(Vect::from(other))
174    }
175
176    type Output = S;
177}
178
179impl<S: Field, const N: usize> Cross for Nrml<N, S>
180where
181    Vect<N, S>: Cross,
182{
183    type Output = <Vect<N, S> as Cross>::Output;
184
185    fn cross(self, other: Self) -> Self::Output {
186        Vect::from(self).cross(Vect::from(other))
187    }
188}
189
190impl<S: Field, const N: usize> Cross<Vect<N, S>> for Nrml<N, S>
191where
192    Vect<N, S>: Cross,
193{
194    type Output = <Vect<N, S> as Cross>::Output;
195
196    fn cross(self, other: Vect<N, S>) -> Self::Output {
197        Vect::from(self).cross(other)
198    }
199}
200
201impl<S: Field, const N: usize> Cross<Nrml<N, S>> for Vect<N, S>
202where
203    Self: Cross,
204{
205    type Output = <Self as Cross>::Output;
206
207    fn cross(self, other: Nrml<N, S>) -> Self::Output {
208        self.cross(Vect::from(other))
209    }
210}
211
212impl<S: Field, const N: usize> AngleTo for Nrml<N, S> {
213    type Output = S;
214
215    fn angle_to(self, other: Self) -> Self::Output {
216        self.dot(other).acos()
217    }
218}
219
220impl<S: Field, const N: usize> AngleTo<Option<Self>> for Nrml<N, S> {
221    type Output = S;
222
223    fn angle_to(self, other: Option<Self>) -> Self::Output {
224        match other {
225            Some(other) => self.angle_to(other),
226            None => S::ZERO,
227        }
228    }
229}
230
231impl<S: Field, const N: usize> AngleTo<Nrml<N, S>> for Option<Nrml<N, S>> {
232    type Output = S;
233
234    fn angle_to(self, other: Nrml<N, S>) -> Self::Output {
235        match self {
236            Some(s) => s.angle_to(other),
237            None => S::ZERO,
238        }
239    }
240}
241
242impl<S: Field, const N: usize> AngleTo for Option<Nrml<N, S>> {
243    type Output = S;
244
245    fn angle_to(self, other: Self) -> Self::Output {
246        match (self, other) {
247            (Some(a), Some(b)) => a.angle_to(b),
248            _ => S::ZERO,
249        }
250    }
251}
252
253impl<S: Field, const N: usize> ProjRej<Nrml<N, S>> for Nrml<N, S> {
254    type Output = Vect<N, S>;
255
256    fn proj(self, axis: Nrml<N, S>) -> Vect<N, S> {
257        axis * self.dot(axis)
258    }
259
260    fn rej(self, axis: Nrml<N, S>) -> Vect<N, S> {
261        self - self.proj(axis)
262    }
263
264    fn proj_rej(self, axis: Nrml<N, S>) -> (Vect<N, S>, Vect<N, S>) {
265        let proj = self.proj(axis);
266        (proj, self - proj)
267    }
268}
269
270impl<S: Field, const N: usize> ProjRej<Option<Nrml<N, S>>> for Nrml<N, S> {
271    type Output = Vect<N, S>;
272
273    fn proj(self, axis: Option<Nrml<N, S>>) -> Self::Output {
274        match axis {
275            Some(axis) => self.proj(axis),
276            None => Vect::ZERO,
277        }
278    }
279
280    fn rej(self, axis: Option<Nrml<N, S>>) -> Self::Output {
281        self - self.proj(axis)
282    }
283
284    fn proj_rej(self, axis: Option<Nrml<N, S>>) -> (Self::Output, Self::Output) {
285        let proj = self.proj(axis);
286        (proj, self - proj)
287    }
288}
289impl<S: Field> Nrml<1, S> {
290    pub fn x(self) -> S {
291        self[0]
292    }
293}
294
295impl<S: Field> Nrml<2, S> {
296    pub fn x(self) -> S {
297        self[0]
298    }
299
300    pub fn y(self) -> S {
301        self[1]
302    }
303}
304
305impl<S: Field> Nrml<3, S> {
306    pub fn x(self) -> S {
307        self[0]
308    }
309
310    pub fn y(self) -> S {
311        self[1]
312    }
313
314    pub fn z(self) -> S {
315        self[2]
316    }
317}
318
319impl<S: Field> Nrml<4, S> {
320    pub fn x(self) -> S {
321        self[0]
322    }
323
324    pub fn y(self) -> S {
325        self[1]
326    }
327
328    pub fn z(self) -> S {
329        self[2]
330    }
331
332    pub fn w(self) -> S {
333        self[3]
334    }
335}