1use core::{
2 cmp::Ordering,
3 f64::consts::PI,
4 fmt::Debug,
5 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign},
6};
7use libm::{atan, atan2, fabs, fmod, log, sin, sinh, sqrt};
8use serde::{Deserialize, Serialize};
9
10use crate::*;
12
13#[derive(Serialize, Deserialize, Debug, Clone, Default)]
15#[repr(C)]
16pub struct VectorPoint<M: Clone = MValue> {
17 pub x: f64,
19 pub y: f64,
21 pub z: Option<f64>,
23 #[serde(skip_serializing_if = "Option::is_none")]
25 pub m: Option<M>,
26 #[serde(skip)]
28 pub t: Option<f64>,
29}
30impl<M: Clone> GetXY for VectorPoint<M> {
31 fn x(&self) -> f64 {
32 self.x
33 }
34 fn y(&self) -> f64 {
35 self.y
36 }
37}
38impl<M: Clone> GetZ for VectorPoint<M> {
39 fn z(&self) -> f64 {
40 self.z.unwrap_or_default()
41 }
42}
43impl<M: Clone> GetM<M> for VectorPoint<M> {
44 fn m(&self) -> Option<&M> {
45 self.m.as_ref()
46 }
47}
48impl VectorPoint<MValue> {
49 pub fn from_xy(x: f64, y: f64) -> Self {
51 Self { x, y, z: None, m: None, t: None }
52 }
53
54 pub fn from_xyz(x: f64, y: f64, z: f64) -> Self {
56 Self { x, y, z: Some(z), m: None, t: None }
57 }
58}
59impl<M: Clone> VectorPoint<M> {
60 pub fn new(x: f64, y: f64, z: Option<f64>, m: Option<M>) -> Self {
62 Self { x, y, z, m, t: None }
63 }
64
65 pub fn new_xy(x: f64, y: f64, m: Option<M>) -> Self {
67 Self { x, y, z: None, m, t: None }
68 }
69
70 pub fn new_xyz(x: f64, y: f64, z: f64, m: Option<M>) -> Self {
72 Self { x, y, z: Some(z), m, t: None }
73 }
74
75 pub fn project(&mut self, bbox: Option<&mut BBox3D>) {
77 let y = self.y;
78 let x = self.x;
79 let sin = sin((y * PI) / 180.);
80 let y2 = 0.5 - (0.25 * log((1. + sin) / (1. - sin))) / PI;
81 self.x = x / 360. + 0.5;
82 self.y = y2.clamp(0., 1.);
83
84 if let Some(bbox) = bbox {
85 bbox.extend_from_point(self)
86 };
87 }
88
89 pub fn unproject(&mut self) {
91 let lon = (self.x - 0.5) * 360.;
92 let y2 = 0.5 - self.y;
93 let lat = atan(sinh(PI * (y2 * 2.))).to_degrees();
94
95 self.x = lon;
96 self.y = lat;
97 }
98
99 pub fn is_empty(&self) -> bool {
101 let zero = f64::default();
102 self.x == zero && self.y == zero && (self.z.is_none() || self.z.unwrap() == zero)
103 }
104
105 pub fn face(&self, f: u8) -> f64 {
107 if f == 0 {
108 self.x
109 } else if f == 1 {
110 self.y
111 } else {
112 self.z.unwrap_or(0.)
113 }
114 }
115
116 pub fn modulo(self, modulus: f64) -> Self {
118 let modulus = fabs(modulus); Self {
120 x: fmod(self.x, modulus),
121 y: fmod(self.y, modulus),
122 z: self.z.map(|z| fmod(z, modulus)),
123 m: self.m,
124 t: None,
125 }
126 }
127
128 pub fn angle<M2: Clone>(&self, b: &VectorPoint<M2>) -> f64 {
132 atan2(self.cross(b).norm(), self.dot(b))
133 }
134
135 pub fn cross<M2: Clone>(&self, b: &VectorPoint<M2>) -> Self {
137 if let (Some(z), Some(bz)) = (self.z, b.z) {
138 Self::new_xyz(
139 self.y * bz - z * b.y,
140 z * b.x - self.x * bz,
141 self.x * b.y - self.y * b.x,
142 None,
143 )
144 } else {
145 Self::new_xy(self.x * b.y - self.y * b.x, self.y * b.x - self.x * b.y, None)
146 }
147 }
148
149 pub fn dot<M2: Clone>(&self, b: &VectorPoint<M2>) -> f64 {
151 if let (Some(z), Some(bz)) = (self.z, b.z) {
152 self.x * b.x + self.y * b.y + z * bz
153 } else {
154 self.x * b.x + self.y * b.y
155 }
156 }
157
158 pub fn abs(&self) -> Self {
160 Self::new(fabs(self.x), fabs(self.y), self.z.map(fabs), None)
161 }
162
163 pub fn invert(&self) -> Self {
165 -self
166 }
167
168 pub fn len(&self) -> f64 {
170 self.norm()
171 }
172
173 pub fn norm(&self) -> f64 {
175 sqrt(self.norm2())
176 }
177
178 pub fn norm2(&self) -> f64 {
180 self.dot(self)
181 }
182
183 pub fn normalize(&mut self) {
185 let len = self.len();
186 if len > 0.0 {
187 self.x /= len;
188 self.y /= len;
189 if let Some(z) = self.z {
190 self.z = Some(z / len);
191 }
192 }
193 }
194
195 pub fn distance<M2: Clone>(&self, b: &VectorPoint<M2>) -> f64 {
197 let d: VectorPoint<M> = self - b;
198 d.len()
199 }
200
201 pub fn largest_abs_component(&self) -> u8 {
203 let tmp = self.abs();
204 let tmp_z = tmp.z.unwrap_or(-2.);
205 if tmp.x > tmp.y {
206 if tmp.x > tmp_z {
207 0
208 } else {
209 2
210 }
211 } else if tmp.y > tmp_z {
212 1
213 } else {
214 2
215 }
216 }
217
218 pub fn intermediate<M2: Clone>(&self, b: &VectorPoint<M2>, t: f64) -> Self {
220 if let (Some(z), Some(bz)) = (self.z, b.z) {
221 Self::new_xyz(
222 self.x + ((b.x - self.x) * (1.0 - t)),
223 self.y + ((b.y - self.y) * (1.0 - t)),
224 z + ((bz - z) * (1.0 - t)),
225 None,
226 )
227 } else {
228 Self::new_xy(
229 self.x + ((b.x - self.x) * (1.0 - t)),
230 self.y + ((b.y - self.y) * (1.0 - t)),
231 None,
232 )
233 }
234 }
235
236 pub fn perpendicular(&self) -> Self {
238 if let Some(z) = self.z {
239 let ref_point = if fabs(self.x) > fabs(z) {
240 Self::new_xyz(0., 0., 1., None)
241 } else {
242 Self::new_xyz(1., 0., 0., None)
243 };
244 let cross = self.cross(&ref_point);
245 Self::new_xyz(-self.y, self.x, cross.z.unwrap(), None)
246 } else {
247 Self::new_xy(-self.y, self.x, None)
248 }
249 }
250}
251impl<M: Clone> From<Point> for VectorPoint<M> {
252 fn from(p: Point) -> Self {
253 Self { x: p.0, y: p.1, z: None, m: None, t: None }
254 }
255}
256impl<M: Clone> From<&Point> for VectorPoint<M> {
257 fn from(p: &Point) -> Self {
258 Self { x: p.0, y: p.1, z: None, m: None, t: None }
259 }
260}
261impl<M: Clone> From<Point3D> for VectorPoint<M> {
262 fn from(p: Point3D) -> Self {
263 Self { x: p.0, y: p.1, z: Some(p.2), m: None, t: None }
264 }
265}
266impl<M: Clone> From<&Point3D> for VectorPoint<M> {
267 fn from(p: &Point3D) -> Self {
268 Self { x: p.0, y: p.1, z: Some(p.2), m: None, t: None }
269 }
270}
271impl<M1: Clone, M2: Clone> Add<&VectorPoint<M2>> for &VectorPoint<M1> {
272 type Output = VectorPoint<M1>;
273 fn add(self, other: &VectorPoint<M2>) -> Self::Output {
274 VectorPoint {
275 x: self.x + other.x,
276 y: self.y + other.y,
277 z: match (self.z, other.z) {
279 (Some(z1), Some(z2)) => Some(z1 + z2),
280 _ => None, },
282 m: None, t: None, }
285 }
286}
287impl<M1: Clone, M2: Clone> AddAssign<&VectorPoint<M2>> for VectorPoint<M1> {
288 fn add_assign(&mut self, other: &VectorPoint<M2>) {
289 self.x += other.x;
290 self.y += other.y;
291 if let (Some(z), Some(other_z)) = (self.z, other.z) {
292 self.z = Some(z + other_z);
293 }
294 }
295}
296impl<M: Clone> Add<f64> for &VectorPoint<M> {
297 type Output = VectorPoint<M>;
298 fn add(self, other: f64) -> Self::Output {
299 VectorPoint {
300 x: self.x + other,
301 y: self.y + other,
302 z: self.z.map(|z| z + other),
303 m: None,
304 t: None,
305 }
306 }
307}
308impl<M: Clone> AddAssign<f64> for VectorPoint<M> {
309 fn add_assign(&mut self, other: f64) {
310 self.x += other;
311 self.y += other;
312 if let Some(z) = self.z {
313 self.z = Some(z + other);
314 }
315 }
316}
317impl<M1: Clone, M2: Clone> Sub<&VectorPoint<M2>> for &VectorPoint<M1> {
319 type Output = VectorPoint<M1>;
320 fn sub(self, other: &VectorPoint<M2>) -> Self::Output {
321 VectorPoint {
322 x: self.x - other.x,
323 y: self.y - other.y,
324 z: match (self.z, other.z) {
325 (Some(z1), Some(z2)) => Some(z1 - z2),
326 _ => None, },
328 m: None, t: None, }
331 }
332}
333impl<M1: Clone, M2: Clone> SubAssign<&VectorPoint<M2>> for VectorPoint<M1> {
334 fn sub_assign(&mut self, other: &VectorPoint<M2>) {
335 self.x -= other.x;
336 self.y -= other.y;
337 if let (Some(z), Some(other_z)) = (self.z, other.z) {
338 self.z = Some(z - other_z);
339 }
340 }
341}
342impl<M: Clone> Sub<f64> for &VectorPoint<M> {
343 type Output = VectorPoint<M>;
344 fn sub(self, other: f64) -> Self::Output {
345 VectorPoint {
346 x: self.x - other,
347 y: self.y - other,
348 z: self.z.map(|z| z - other),
349 m: None,
350 t: None,
351 }
352 }
353}
354impl<M: Clone> SubAssign<f64> for VectorPoint<M> {
355 fn sub_assign(&mut self, other: f64) {
356 self.x -= other;
357 self.y -= other;
358 if let Some(z) = self.z {
359 self.z = Some(z - other);
360 }
361 }
362}
363impl<M: Clone> Neg for &VectorPoint<M> {
365 type Output = VectorPoint<M>;
366 fn neg(self) -> Self::Output {
367 VectorPoint { x: -self.x, y: -self.y, z: self.z.map(|z| -z), m: None, t: None }
368 }
369}
370impl<M1: Clone, M2: Clone> Div<&VectorPoint<M2>> for &VectorPoint<M1> {
372 type Output = VectorPoint<M1>;
373 fn div(self, other: &VectorPoint<M2>) -> Self::Output {
374 VectorPoint {
375 x: self.x / other.x,
376 y: self.y / other.y,
377 z: match (self.z, other.z) {
378 (Some(z1), Some(z2)) => Some(z1 / z2),
379 _ => None, },
381 m: None, t: None, }
384 }
385}
386impl<M1: Clone, M2: Clone> DivAssign<&VectorPoint<M2>> for VectorPoint<M1> {
387 fn div_assign(&mut self, other: &VectorPoint<M2>) {
388 self.x /= other.x;
389 self.y /= other.y;
390 if let (Some(z), Some(other_z)) = (self.z, other.z) {
391 self.z = Some(z / other_z);
392 }
393 }
394}
395impl<M: Clone> Div<f64> for &VectorPoint<M> {
396 type Output = VectorPoint<M>;
397 fn div(self, other: f64) -> Self::Output {
398 VectorPoint {
399 x: self.x / other,
400 y: self.y / other,
401 z: self.z.map(|z| z / other),
402 m: None,
403 t: None,
404 }
405 }
406}
407impl<M: Clone> DivAssign<f64> for VectorPoint<M> {
408 fn div_assign(&mut self, other: f64) {
409 self.x /= other;
410 self.y /= other;
411 if let Some(z) = self.z {
412 self.z = Some(z / other);
413 }
414 }
415}
416impl<M1: Clone, M2: Clone> Mul<&VectorPoint<M2>> for &VectorPoint<M1> {
418 type Output = VectorPoint<M1>;
419 fn mul(self, other: &VectorPoint<M2>) -> Self::Output {
420 VectorPoint {
421 x: self.x * other.x,
422 y: self.y * other.y,
423 z: match (self.z, other.z) {
424 (Some(z1), Some(z2)) => Some(z1 * z2),
425 _ => None, },
427 m: None, t: None, }
430 }
431}
432impl<M1: Clone, M2: Clone> MulAssign<&VectorPoint<M2>> for VectorPoint<M1> {
433 fn mul_assign(&mut self, other: &VectorPoint<M2>) {
434 self.x *= other.x;
435 self.y *= other.y;
436 if let (Some(z), Some(other_z)) = (self.z, other.z) {
437 self.z = Some(z * other_z);
438 }
439 }
440}
441impl<M: Clone> Mul<f64> for &VectorPoint<M> {
442 type Output = VectorPoint<M>;
443 fn mul(self, other: f64) -> Self::Output {
444 VectorPoint {
445 x: self.x * other,
446 y: self.y * other,
447 z: self.z.map(|z| z * other),
448 m: None,
449 t: None,
450 }
451 }
452}
453impl<M: Clone> MulAssign<f64> for VectorPoint<M> {
454 fn mul_assign(&mut self, other: f64) {
455 self.x *= other;
456 self.y *= other;
457 if let Some(z) = self.z {
458 self.z = Some(z * other);
459 }
460 }
461}
462impl<M: Clone> Rem<f64> for VectorPoint<M> {
463 type Output = VectorPoint<M>;
464
465 fn rem(self, modulus: f64) -> Self::Output {
466 self.modulo(modulus)
467 }
468}
469impl<M: Clone> RemAssign<f64> for VectorPoint<M> {
470 fn rem_assign(&mut self, modulus: f64) {
471 let modulus = fabs(modulus);
472 self.x = fmod(self.x, modulus);
473 self.y = fmod(self.y, modulus);
474 if let Some(z) = self.z {
475 self.z = Some(fmod(z, modulus));
476 }
477 }
478}
479impl<M: Clone> Eq for VectorPoint<M> {}
480impl<M: Clone> Ord for VectorPoint<M> {
481 fn cmp(&self, other: &VectorPoint<M>) -> Ordering {
482 match self.x.partial_cmp(&other.x) {
483 Some(Ordering::Equal) => {}
484 other => return other.unwrap_or(Ordering::Greater), }
486 match self.y.partial_cmp(&other.y) {
487 Some(Ordering::Equal) => {}
488 other => return other.unwrap_or(Ordering::Greater), }
490 match self.z.partial_cmp(&other.z) {
491 Some(order) => order,
492 None => Ordering::Equal, }
494 }
495}
496impl<M: Clone> PartialEq for VectorPoint<M> {
497 fn eq(&self, other: &VectorPoint<M>) -> bool {
498 self.x == other.x && self.y == other.y && self.z == other.z
499 }
500}
501impl<M: Clone> PartialOrd for VectorPoint<M> {
502 fn partial_cmp(&self, other: &VectorPoint<M>) -> Option<Ordering> {
503 Some(self.cmp(other))
504 }
505}