simplify_polyline/
point.rs1use std::ops::{Add, Mul, Sub};
2
3use crate::ExtendedNumOps;
4
5#[derive(Clone, Copy, PartialEq, Eq, Debug)]
27pub struct Point<const D: usize, T: ExtendedNumOps> {
28 pub vec: [T; D],
30}
31
32impl<const D: usize, T: ExtendedNumOps> Point<D, T> {
33 #[inline(always)]
35 pub fn sq_dist(&self, other: &Point<D, T>) -> T {
36 match D {
37 2 => {
38 let xdist = other.vec[0] - self.vec[0];
39 let ydist = other.vec[1] - self.vec[1];
40 (xdist * xdist) + (ydist * ydist)
41 }
42 3 => {
43 let xdist = other.vec[0] - self.vec[0];
44 let ydist = other.vec[1] - self.vec[1];
45 let zdist = other.vec[2] - self.vec[2];
46 (xdist * xdist) + (ydist * ydist) + (zdist * zdist)
47 }
48 4 => {
49 let xdist = other.vec[0] - self.vec[0];
50 let ydist = other.vec[1] - self.vec[1];
51 let zdist = other.vec[2] - self.vec[2];
52 let wdist = other.vec[3] - self.vec[3];
53 (xdist * xdist) + (ydist * ydist) + (zdist * zdist) + (wdist * wdist)
54 }
55 _ => self
56 .vec
57 .iter()
58 .zip(other.vec)
59 .map(|(a, b)| b - *a)
60 .reduce(|acc, v| acc + (v * v))
61 .unwrap_or_else(|| T::zero()),
62 }
63 }
64
65 #[inline(always)]
67 pub fn sq_dist_origin(&self) -> T {
68 match D {
69 2 => (self.vec[0] * self.vec[0]) + (self.vec[1] * self.vec[1]),
70 3 => {
71 (self.vec[0] * self.vec[0])
72 + (self.vec[1] * self.vec[1])
73 + (self.vec[2] * self.vec[2])
74 }
75 4 => {
76 (self.vec[0] * self.vec[0])
77 + (self.vec[1] * self.vec[1])
78 + (self.vec[2] * self.vec[2])
79 + (self.vec[3] * self.vec[3])
80 }
81 _ => self.sq_dist(&Point {
82 vec: [T::zero(); D],
83 }),
84 }
85 }
86
87 #[inline(always)]
89 pub fn value_sum(&self) -> T {
90 match D {
91 2 => self.vec[0] + self.vec[1],
92 3 => self.vec[0] + self.vec[1] + self.vec[2],
93 4 => self.vec[0] + self.vec[1] + self.vec[2] + self.vec[3],
94 _ => self
95 .vec
96 .into_iter()
97 .reduce(|acc, v| acc + v)
98 .unwrap_or_else(|| T::zero()),
99 }
100 }
101
102 #[inline(always)]
104 pub fn is_origin(&self) -> bool {
105 let zero = T::zero();
106 match D {
107 2 => self.vec[0] == zero && self.vec[1] == zero,
108 3 => self.vec[0] == zero && self.vec[1] == zero && self.vec[2] == zero,
109 4 => {
110 self.vec[0] == zero
111 && self.vec[1] == zero
112 && self.vec[2] == zero
113 && self.vec[3] == zero
114 }
115 _ => self.vec.iter().all(|v| v == &zero),
116 }
117 }
118}
119
120macro_rules! impl_ref_op {
121 (impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
122 impl<'a, const D: usize, T: ExtendedNumOps> $imp<$u> for &'a $t {
123 type Output = $t;
124
125 #[inline(always)]
126 fn $method(self, other: $u) -> Self::Output {
127 $imp::$method(*self, other)
128 }
129 }
130
131 impl<'b, const D: usize, T: ExtendedNumOps> $imp<&'b $u> for $t {
132 type Output = $t;
133
134 #[inline(always)]
135 fn $method(self, other: &'b $u) -> Self::Output {
136 $imp::$method(self, *other)
137 }
138 }
139
140 impl<'a, 'b, const D: usize, T: ExtendedNumOps> $imp<&'b $u> for &'a $t {
141 type Output = $t;
142
143 #[inline(always)]
144 fn $method(self, other: &'b $u) -> Self::Output {
145 $imp::$method(*self, *other)
146 }
147 }
148 };
149}
150
151impl<const D: usize, T: ExtendedNumOps> Add<Point<D, T>> for Point<D, T> {
152 type Output = Point<D, T>;
153
154 #[inline(always)]
155 fn add(self, rhs: Point<D, T>) -> Self::Output {
156 let mut new_values = [T::zero(); D];
157 match D {
158 2 => {
159 new_values[0] = self.vec[0] + rhs.vec[0];
160 new_values[1] = self.vec[1] + rhs.vec[1];
161 }
162 3 => {
163 new_values[0] = self.vec[0] + rhs.vec[0];
164 new_values[1] = self.vec[1] + rhs.vec[1];
165 new_values[2] = self.vec[2] + rhs.vec[2];
166 }
167 4 => {
168 new_values[0] = self.vec[0] + rhs.vec[0];
169 new_values[1] = self.vec[1] + rhs.vec[1];
170 new_values[2] = self.vec[2] + rhs.vec[2];
171 new_values[3] = self.vec[3] + rhs.vec[3];
172 }
173 _ => {
174 let mut i = 0usize;
175 while i < self.vec.len() {
176 new_values[i] = self.vec[i] + rhs.vec[i];
177 i += 1;
178 }
179 }
180 }
181 Point { vec: new_values }
182 }
183}
184impl_ref_op!(impl Add, add for Point<D, T>, Point<D, T>);
185
186impl<const D: usize, T: ExtendedNumOps> Sub<Point<D, T>> for Point<D, T> {
187 type Output = Point<D, T>;
188
189 #[inline(always)]
190 fn sub(self, rhs: Point<D, T>) -> Self::Output {
191 match D {
192 2 => {
193 let mut new_values = [T::zero(); D];
194 new_values[0] = self.vec[0] - rhs.vec[0];
195 new_values[1] = self.vec[1] - rhs.vec[1];
196 Point { vec: new_values }
197 }
198 _ => {
199 let mut i = 0usize;
200 let mut new_values = [T::zero(); D];
201 while i < self.vec.len() {
202 new_values[i] = self.vec[i] - rhs.vec[i];
203 i += 1;
204 }
205 Point { vec: new_values }
206 }
207 }
208 }
209}
210impl_ref_op!(impl Sub, sub for Point<D, T>, Point<D, T>);
211
212impl<const D: usize, T: ExtendedNumOps> Mul<Point<D, T>> for Point<D, T> {
213 type Output = Point<D, T>;
214
215 #[inline(always)]
216 fn mul(self, rhs: Point<D, T>) -> Self::Output {
217 let mut new_values = [T::zero(); D];
218 match D {
219 2 => {
220 new_values[0] = self.vec[0] * rhs.vec[0];
221 new_values[1] = self.vec[1] * rhs.vec[1];
222 }
223 3 => {
224 new_values[0] = self.vec[0] * rhs.vec[0];
225 new_values[1] = self.vec[1] * rhs.vec[1];
226 new_values[2] = self.vec[2] * rhs.vec[2];
227 }
228 4 => {
229 new_values[0] = self.vec[0] * rhs.vec[0];
230 new_values[1] = self.vec[1] * rhs.vec[1];
231 new_values[2] = self.vec[2] * rhs.vec[2];
232 new_values[3] = self.vec[3] * rhs.vec[3];
233 }
234 _ => {
235 let mut i = 0usize;
236 while i < self.vec.len() {
237 new_values[i] = self.vec[i] * rhs.vec[i];
238 i += 1;
239 }
240 }
241 }
242 Point { vec: new_values }
243 }
244}
245impl_ref_op!(impl Mul, mul for Point<D, T>, Point<D, T>);
246
247impl<const D: usize, T: ExtendedNumOps> Mul<T> for Point<D, T> {
248 type Output = Point<D, T>;
249
250 #[inline(always)]
251 fn mul(self, rhs: T) -> Self::Output {
252 let mut new_values = [T::zero(); D];
253 match D {
254 2 => {
255 new_values[0] = self.vec[0] * rhs;
256 new_values[1] = self.vec[1] * rhs;
257 }
258 3 => {
259 new_values[0] = self.vec[0] * rhs;
260 new_values[1] = self.vec[1] * rhs;
261 new_values[2] = self.vec[2] * rhs;
262 }
263 4 => {
264 new_values[0] = self.vec[0] * rhs;
265 new_values[1] = self.vec[1] * rhs;
266 new_values[2] = self.vec[2] * rhs;
267 new_values[3] = self.vec[3] * rhs;
268 }
269 _ => {
270 let mut i = 0usize;
271 let mut new_values = [T::zero(); D];
272 while i < self.vec.len() {
273 new_values[i] = self.vec[i] * rhs;
274 i += 1;
275 }
276 }
277 }
278 Point { vec: new_values }
279 }
280}
281impl_ref_op!(impl Mul, mul for Point<D, T>, T);
282
283#[macro_export]
299macro_rules! point {
300 ($($values:expr),+) => {
301 Point { vec: [$($values),+] }
302 };
303}
304
305#[macro_export]
323macro_rules! points {
324 ($(($($values:expr),+)),*) => {
325 [$(Point { vec: [$($values),+] }),*]
326 };
327}