1use core::iter::{IntoIterator, Sum};
2use core::slice;
3
4use super::*;
5use super::Point;
7
8#[derive(Debug, Copy, Clone)]
15pub struct PointN<T, const N: usize>([T; N]);
16
17impl<T, const N: usize> PointN<T, N> {
18 pub fn new(array: [T; N]) -> Self {
19 PointN(array)
20 }
21}
22
23impl<T: Default + Copy, const N: usize> Default for PointN<T, N> {
25 fn default() -> Self {
26 PointN([T::default(); N])
27 }
28}
29
30impl<T, const N: usize> PartialEq for PointN<T, N>
31where
32 T: PartialOrd,
33{
34 fn eq(&self, other: &Self) -> bool {
35 for i in 0..N {
36 if self.0[i] != other.0[i] {
37 return false;
38 }
39 }
40 true
41 }
42}
43
44impl<T, const N: usize> Add for PointN<T, N>
45where
46 T: Add<Output = T> + Clone + Copy,
47{
48 type Output = Self;
49
50 fn add(self, other: PointN<T, N>) -> PointN<T, N> {
51 let mut res = self;
52 for i in 0..N {
53 res.0[i] = self.0[i] + other.0[i];
54 }
55 res
56 }
57}
58
59impl<T, const N: usize> Add<T> for PointN<T, N>
62where
63 T: Add<Output = T> + Clone + Copy,
64{
65 type Output = Self;
66
67 fn add(self, _rhs: T) -> PointN<T, N> {
68 let mut res = self;
69 for i in 0..N {
70 res.0[i] = self.0[i] + _rhs;
71 }
72 res
73 }
74}
75
76impl<T, const N: usize> Sub for PointN<T, N>
77where
78 T: Sub<Output = T> + Clone + Copy,
79{
80 type Output = Self;
81
82 fn sub(self, other: PointN<T, N>) -> PointN<T, N> {
83 let mut res = self;
84 for i in 0..N {
85 res.0[i] = self.0[i] - other.0[i];
86 }
87 res
88 }
89}
90
91impl<T, const N: usize> Sub<T> for PointN<T, N>
94where
95 T: Sub<Output = T> + Clone + Copy,
96{
97 type Output = Self;
98
99 fn sub(self, _rhs: T) -> PointN<T, N> {
100 let mut res = self;
101 for i in 0..N {
102 res.0[i] = self.0[i] - _rhs;
103 }
104 res
105 }
106}
107
108impl<T, const N: usize, U> Mul<U> for PointN<T, N>
109where
110 T: Mul<U, Output = T> + Clone + Copy, U: Clone + Copy,
115{
116 type Output = PointN<T, N>;
117
118 fn mul(self, _rhs: U) -> PointN<T, N> {
119 let mut res = self;
120 for i in 0..res.0.len() {
121 res.0[i] = res.0[i] * _rhs;
122 }
123 res
124 }
125}
126
127impl<T, const N: usize> IntoIterator for PointN<T, N> {
128 type Item = T;
129 type IntoIter = core::array::IntoIter<Self::Item, N>;
130
131 fn into_iter(self) -> Self::IntoIter {
132 IntoIterator::into_iter(self.0)
133 }
134}
135
136impl<'a, T, const N: usize> IntoIterator for &'a mut PointN<T, N> {
137 type Item = &'a mut T;
138 type IntoIter = slice::IterMut<'a, T>;
139
140 fn into_iter(self) -> slice::IterMut<'a, T> {
141 self.0.iter_mut()
142 }
143}
144
145impl<T, const N: usize> Point for PointN<T, N>
146where
147 T: Float
148 + Copy
149 + Default
150 + Add<T, Output = T>
151 + Add<NativeFloat, Output = T>
152 + Sub<T, Output = T>
153 + Sub<NativeFloat, Output = T>
154 + Mul<T, Output = T>
155 + Mul<NativeFloat, Output = T>
156 + Sum<NativeFloat>
157 + From<NativeFloat>
158 + Into<NativeFloat>,
159{
160 type Scalar = NativeFloat;
161 const DIM: usize = { N };
162
163 fn axis(&self, index: usize) -> Self::Scalar {
164 assert!(index <= N);
165 self.0[index].into()
166 }
167
168 fn squared_length(&self) -> Self::Scalar {
169 let mut sqr_dist = 0.0;
170 for i in 0..N {
171 sqr_dist += (self.0[i] * self.0[i]).into();
172 }
173 sqr_dist
174 }
175}