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 VectorPoint<MValue> {
31 pub fn from_xy(x: f64, y: f64) -> Self {
33 Self { x, y, z: None, m: None, t: None }
34 }
35
36 pub fn from_xyz(x: f64, y: f64, z: f64) -> Self {
38 Self { x, y, z: Some(z), m: None, t: None }
39 }
40}
41impl<M: Clone> VectorPoint<M> {
42 pub fn new(x: f64, y: f64, z: Option<f64>, m: Option<M>) -> Self {
44 Self { x, y, z, m, t: None }
45 }
46
47 pub fn new_xy(x: f64, y: f64, m: Option<M>) -> Self {
49 Self { x, y, z: None, m, t: None }
50 }
51
52 pub fn new_xyz(x: f64, y: f64, z: f64, m: Option<M>) -> Self {
54 Self { x, y, z: Some(z), m, t: None }
55 }
56
57 pub fn project(&mut self, bbox: Option<&mut BBox3D>) {
59 let y = self.y;
60 let x = self.x;
61 let sin = sin((y * PI) / 180.);
62 let y2 = 0.5 - (0.25 * log((1. + sin) / (1. - sin))) / PI;
63 self.x = x / 360. + 0.5;
64 self.y = y2.clamp(0., 1.);
65
66 if let Some(bbox) = bbox {
67 bbox.extend_from_point(self)
68 };
69 }
70
71 pub fn unproject(&mut self) {
73 let lon = (self.x - 0.5) * 360.;
74 let y2 = 0.5 - self.y;
75 let lat = atan(sinh(PI * (y2 * 2.))).to_degrees();
76
77 self.x = lon;
78 self.y = lat;
79 }
80
81 pub fn is_empty(&self) -> bool {
83 let zero = f64::default();
84 self.x == zero && self.y == zero && (self.z.is_none() || self.z.unwrap() == zero)
85 }
86
87 pub fn face(&self, f: u8) -> f64 {
89 if f == 0 {
90 self.x
91 } else if f == 1 {
92 self.y
93 } else {
94 self.z.unwrap_or(0.)
95 }
96 }
97
98 pub fn modulo(self, modulus: f64) -> Self {
100 let modulus = fabs(modulus); Self {
102 x: fmod(self.x, modulus),
103 y: fmod(self.y, modulus),
104 z: self.z.map(|z| fmod(z, modulus)),
105 m: self.m,
106 t: None,
107 }
108 }
109
110 pub fn angle<M2: Clone>(&self, b: &VectorPoint<M2>) -> f64 {
114 atan2(self.cross(b).norm(), self.dot(b))
115 }
116
117 pub fn cross<M2: Clone>(&self, b: &VectorPoint<M2>) -> Self {
119 if let (Some(z), Some(bz)) = (self.z, b.z) {
120 Self::new_xyz(
121 self.y * bz - z * b.y,
122 z * b.x - self.x * bz,
123 self.x * b.y - self.y * b.x,
124 None,
125 )
126 } else {
127 Self::new_xy(self.x * b.y - self.y * b.x, self.y * b.x - self.x * b.y, None)
128 }
129 }
130
131 pub fn dot<M2: Clone>(&self, b: &VectorPoint<M2>) -> f64 {
133 if let (Some(z), Some(bz)) = (self.z, b.z) {
134 self.x * b.x + self.y * b.y + z * bz
135 } else {
136 self.x * b.x + self.y * b.y
137 }
138 }
139
140 pub fn abs(&self) -> Self {
142 Self::new(fabs(self.x), fabs(self.y), self.z.map(fabs), None)
143 }
144
145 pub fn invert(&self) -> Self {
147 -self
148 }
149
150 pub fn len(&self) -> f64 {
152 self.norm()
153 }
154
155 pub fn norm(&self) -> f64 {
157 sqrt(self.norm2())
158 }
159
160 pub fn norm2(&self) -> f64 {
162 self.dot(self)
163 }
164
165 pub fn normalize(&mut self) {
167 let len = self.len();
168 if len > 0.0 {
169 self.x /= len;
170 self.y /= len;
171 if let Some(z) = self.z {
172 self.z = Some(z / len);
173 }
174 }
175 }
176
177 pub fn distance<M2: Clone>(&self, b: &VectorPoint<M2>) -> f64 {
179 let d: VectorPoint<M> = self - b;
180 d.len()
181 }
182
183 pub fn largest_abs_component(&self) -> u8 {
185 let tmp = self.abs();
186 let tmp_z = tmp.z.unwrap_or(-2.);
187 if tmp.x > tmp.y {
188 if tmp.x > tmp_z {
189 0
190 } else {
191 2
192 }
193 } else if tmp.y > tmp_z {
194 1
195 } else {
196 2
197 }
198 }
199
200 pub fn intermediate<M2: Clone>(&self, b: &VectorPoint<M2>, t: f64) -> Self {
202 if let (Some(z), Some(bz)) = (self.z, b.z) {
203 Self::new_xyz(
204 self.x + ((b.x - self.x) * (1.0 - t)),
205 self.y + ((b.y - self.y) * (1.0 - t)),
206 z + ((bz - z) * (1.0 - t)),
207 None,
208 )
209 } else {
210 Self::new_xy(
211 self.x + ((b.x - self.x) * (1.0 - t)),
212 self.y + ((b.y - self.y) * (1.0 - t)),
213 None,
214 )
215 }
216 }
217
218 pub fn perpendicular(&self) -> Self {
220 if let Some(z) = self.z {
221 let ref_point = if fabs(self.x) > fabs(z) {
222 Self::new_xyz(0., 0., 1., None)
223 } else {
224 Self::new_xyz(1., 0., 0., None)
225 };
226 let cross = self.cross(&ref_point);
227 Self::new_xyz(-self.y, self.x, cross.z.unwrap(), None)
228 } else {
229 Self::new_xy(-self.y, self.x, None)
230 }
231 }
232}
233impl<M: Clone> From<Point> for VectorPoint<M> {
234 fn from(p: Point) -> Self {
235 Self { x: p.0, y: p.1, z: None, m: None, t: None }
236 }
237}
238impl<M: Clone> From<&Point> for VectorPoint<M> {
239 fn from(p: &Point) -> Self {
240 Self { x: p.0, y: p.1, z: None, m: None, t: None }
241 }
242}
243impl<M: Clone> From<Point3D> for VectorPoint<M> {
244 fn from(p: Point3D) -> Self {
245 Self { x: p.0, y: p.1, z: Some(p.2), m: None, t: None }
246 }
247}
248impl<M: Clone> From<&Point3D> for VectorPoint<M> {
249 fn from(p: &Point3D) -> Self {
250 Self { x: p.0, y: p.1, z: Some(p.2), m: None, t: None }
251 }
252}
253impl<M1: Clone, M2: Clone> Add<&VectorPoint<M2>> for &VectorPoint<M1> {
254 type Output = VectorPoint<M1>;
255 fn add(self, other: &VectorPoint<M2>) -> Self::Output {
256 VectorPoint {
257 x: self.x + other.x,
258 y: self.y + other.y,
259 z: match (self.z, other.z) {
261 (Some(z1), Some(z2)) => Some(z1 + z2),
262 _ => None, },
264 m: None, t: None, }
267 }
268}
269impl<M1: Clone, M2: Clone> AddAssign<&VectorPoint<M2>> for VectorPoint<M1> {
270 fn add_assign(&mut self, other: &VectorPoint<M2>) {
271 self.x += other.x;
272 self.y += other.y;
273 if let (Some(z), Some(other_z)) = (self.z, other.z) {
274 self.z = Some(z + other_z);
275 }
276 }
277}
278impl<M: Clone> Add<f64> for &VectorPoint<M> {
279 type Output = VectorPoint<M>;
280 fn add(self, other: f64) -> Self::Output {
281 VectorPoint {
282 x: self.x + other,
283 y: self.y + other,
284 z: self.z.map(|z| z + other),
285 m: None,
286 t: None,
287 }
288 }
289}
290impl<M: Clone> AddAssign<f64> for VectorPoint<M> {
291 fn add_assign(&mut self, other: f64) {
292 self.x += other;
293 self.y += other;
294 if let Some(z) = self.z {
295 self.z = Some(z + other);
296 }
297 }
298}
299impl<M1: Clone, M2: Clone> Sub<&VectorPoint<M2>> for &VectorPoint<M1> {
301 type Output = VectorPoint<M1>;
302 fn sub(self, other: &VectorPoint<M2>) -> Self::Output {
303 VectorPoint {
304 x: self.x - other.x,
305 y: self.y - other.y,
306 z: match (self.z, other.z) {
307 (Some(z1), Some(z2)) => Some(z1 - z2),
308 _ => None, },
310 m: None, t: None, }
313 }
314}
315impl<M1: Clone, M2: Clone> SubAssign<&VectorPoint<M2>> for VectorPoint<M1> {
316 fn sub_assign(&mut self, other: &VectorPoint<M2>) {
317 self.x -= other.x;
318 self.y -= other.y;
319 if let (Some(z), Some(other_z)) = (self.z, other.z) {
320 self.z = Some(z - other_z);
321 }
322 }
323}
324impl<M: Clone> Sub<f64> for &VectorPoint<M> {
325 type Output = VectorPoint<M>;
326 fn sub(self, other: f64) -> Self::Output {
327 VectorPoint {
328 x: self.x - other,
329 y: self.y - other,
330 z: self.z.map(|z| z - other),
331 m: None,
332 t: None,
333 }
334 }
335}
336impl<M: Clone> SubAssign<f64> for VectorPoint<M> {
337 fn sub_assign(&mut self, other: f64) {
338 self.x -= other;
339 self.y -= other;
340 if let Some(z) = self.z {
341 self.z = Some(z - other);
342 }
343 }
344}
345impl<M: Clone> Neg for &VectorPoint<M> {
347 type Output = VectorPoint<M>;
348 fn neg(self) -> Self::Output {
349 VectorPoint { x: -self.x, y: -self.y, z: self.z.map(|z| -z), m: None, t: None }
350 }
351}
352impl<M1: Clone, M2: Clone> Div<&VectorPoint<M2>> for &VectorPoint<M1> {
354 type Output = VectorPoint<M1>;
355 fn div(self, other: &VectorPoint<M2>) -> Self::Output {
356 VectorPoint {
357 x: self.x / other.x,
358 y: self.y / other.y,
359 z: match (self.z, other.z) {
360 (Some(z1), Some(z2)) => Some(z1 / z2),
361 _ => None, },
363 m: None, t: None, }
366 }
367}
368impl<M1: Clone, M2: Clone> DivAssign<&VectorPoint<M2>> for VectorPoint<M1> {
369 fn div_assign(&mut self, other: &VectorPoint<M2>) {
370 self.x /= other.x;
371 self.y /= other.y;
372 if let (Some(z), Some(other_z)) = (self.z, other.z) {
373 self.z = Some(z / other_z);
374 }
375 }
376}
377impl<M: Clone> Div<f64> for &VectorPoint<M> {
378 type Output = VectorPoint<M>;
379 fn div(self, other: f64) -> Self::Output {
380 VectorPoint {
381 x: self.x / other,
382 y: self.y / other,
383 z: self.z.map(|z| z / other),
384 m: None,
385 t: None,
386 }
387 }
388}
389impl<M: Clone> DivAssign<f64> for VectorPoint<M> {
390 fn div_assign(&mut self, other: f64) {
391 self.x /= other;
392 self.y /= other;
393 if let Some(z) = self.z {
394 self.z = Some(z / other);
395 }
396 }
397}
398impl<M1: Clone, M2: Clone> Mul<&VectorPoint<M2>> for &VectorPoint<M1> {
400 type Output = VectorPoint<M1>;
401 fn mul(self, other: &VectorPoint<M2>) -> Self::Output {
402 VectorPoint {
403 x: self.x * other.x,
404 y: self.y * other.y,
405 z: match (self.z, other.z) {
406 (Some(z1), Some(z2)) => Some(z1 * z2),
407 _ => None, },
409 m: None, t: None, }
412 }
413}
414impl<M1: Clone, M2: Clone> MulAssign<&VectorPoint<M2>> for VectorPoint<M1> {
415 fn mul_assign(&mut self, other: &VectorPoint<M2>) {
416 self.x *= other.x;
417 self.y *= other.y;
418 if let (Some(z), Some(other_z)) = (self.z, other.z) {
419 self.z = Some(z * other_z);
420 }
421 }
422}
423impl<M: Clone> Mul<f64> for &VectorPoint<M> {
424 type Output = VectorPoint<M>;
425 fn mul(self, other: f64) -> Self::Output {
426 VectorPoint {
427 x: self.x * other,
428 y: self.y * other,
429 z: self.z.map(|z| z * other),
430 m: None,
431 t: None,
432 }
433 }
434}
435impl<M: Clone> MulAssign<f64> for VectorPoint<M> {
436 fn mul_assign(&mut self, other: f64) {
437 self.x *= other;
438 self.y *= other;
439 if let Some(z) = self.z {
440 self.z = Some(z * other);
441 }
442 }
443}
444impl<M: Clone> Rem<f64> for VectorPoint<M> {
445 type Output = VectorPoint<M>;
446
447 fn rem(self, modulus: f64) -> Self::Output {
448 self.modulo(modulus)
449 }
450}
451impl<M: Clone> RemAssign<f64> for VectorPoint<M> {
452 fn rem_assign(&mut self, modulus: f64) {
453 let modulus = fabs(modulus);
454 self.x = fmod(self.x, modulus);
455 self.y = fmod(self.y, modulus);
456 if let Some(z) = self.z {
457 self.z = Some(fmod(z, modulus));
458 }
459 }
460}
461impl<M: Clone> Eq for VectorPoint<M> {}
462impl<M: Clone> Ord for VectorPoint<M> {
463 fn cmp(&self, other: &VectorPoint<M>) -> Ordering {
464 match self.x.partial_cmp(&other.x) {
465 Some(Ordering::Equal) => {}
466 other => return other.unwrap_or(Ordering::Greater), }
468 match self.y.partial_cmp(&other.y) {
469 Some(Ordering::Equal) => {}
470 other => return other.unwrap_or(Ordering::Greater), }
472 match self.z.partial_cmp(&other.z) {
473 Some(order) => order,
474 None => Ordering::Equal, }
476 }
477}
478impl<M: Clone> PartialEq for VectorPoint<M> {
479 fn eq(&self, other: &VectorPoint<M>) -> bool {
480 self.x == other.x && self.y == other.y && self.z == other.z
481 }
482}
483impl<M: Clone> PartialOrd for VectorPoint<M> {
484 fn partial_cmp(&self, other: &VectorPoint<M>) -> Option<Ordering> {
485 Some(self.cmp(other))
486 }
487}
488
489#[cfg(test)]
490mod tests {
491 use super::*;
492
493 #[test]
494 fn size() {
495 assert_eq!(size_of::<VectorPoint<()>>(), 56);
496 assert_eq!(size_of::<VectorPoint<MValue>>(), 80);
497 }
498
499 #[test]
500 fn new() {
501 let vector_point: VectorPoint = VectorPoint::new(1.0, 2.0, None, None);
502 assert_eq!(vector_point.x, 1.0);
503 assert_eq!(vector_point.y, 2.0);
504 assert_eq!(vector_point.z, None);
505 assert_eq!(vector_point.m, None);
506 assert_eq!(vector_point.t, None);
507 }
508
509 #[test]
510 fn new_xy() {
511 let vector_point: VectorPoint = VectorPoint::new_xy(1.0, 2.0, None);
512 assert_eq!(vector_point.x, 1.0);
513 assert_eq!(vector_point.y, 2.0);
514 assert_eq!(vector_point.z, None);
515 assert_eq!(vector_point.m, None);
516 assert_eq!(vector_point.t, None);
517 }
518
519 #[test]
520 fn new_xyz() {
521 let vector_point: VectorPoint = VectorPoint::new_xyz(1.0, 2.0, 3.0, None);
522 assert_eq!(vector_point.x, 1.0);
523 assert_eq!(vector_point.y, 2.0);
524 assert_eq!(vector_point.z, Some(3.0));
525 assert_eq!(vector_point.m, None);
526 assert_eq!(vector_point.t, None);
527 }
528
529 #[test]
530 fn from_xy() {
531 let vector_point: VectorPoint = VectorPoint::from_xy(1.0, 2.0);
532 assert_eq!(vector_point.x, 1.0);
533 assert_eq!(vector_point.y, 2.0);
534 assert_eq!(vector_point.z, None);
535 assert_eq!(vector_point.m, None);
536 assert_eq!(vector_point.t, None);
537 }
538
539 #[test]
540 fn from_xyz() {
541 let vector_point: VectorPoint = VectorPoint::from_xyz(1.0, 2.0, 3.0);
542 assert_eq!(vector_point.x, 1.0);
543 assert_eq!(vector_point.y, 2.0);
544 assert_eq!(vector_point.z, Some(3.0));
545 assert_eq!(vector_point.m, None);
546 assert_eq!(vector_point.t, None);
547 }
548
549 #[test]
550 fn project() {
551 let mut vector_point: VectorPoint = VectorPoint::new(1.0, 2.0, Some(-3.), None);
552 let mut bbox: BBox3D = BBox3D::new(1., 1., 0., 0., 0., 1.);
553 vector_point.project(Some(&mut bbox));
554 assert_eq!(vector_point.x, 0.5027777777777778);
555 assert_eq!(vector_point.y, 0.4944433158879836);
556 assert_eq!(vector_point.z, Some(-3.));
557 assert_eq!(vector_point.m, None);
558 assert_eq!(vector_point.t, None);
559
560 assert_eq!(bbox.left, 0.5027777777777778);
561 assert_eq!(bbox.bottom, 0.4944433158879836);
562 assert_eq!(bbox.right, 0.5027777777777778);
563 assert_eq!(bbox.top, 0.4944433158879836);
564 assert_eq!(bbox.near, -3.);
565 assert_eq!(bbox.far, 1.0);
566 }
567
568 #[test]
569 fn project_no_bbox() {
570 let mut vector_point: VectorPoint = VectorPoint::new(1.0, 2.0, Some(-3.), None);
571 vector_point.project(None);
572 assert_eq!(vector_point.x, 0.5027777777777778);
573 assert_eq!(vector_point.y, 0.4944433158879836);
574 assert_eq!(vector_point.z, Some(-3.));
575 assert_eq!(vector_point.m, None);
576 assert_eq!(vector_point.t, None);
577 }
578
579 #[test]
580 fn unproject() {
581 let mut vector_point: VectorPoint =
582 VectorPoint::new(0.5027777777777778, 0.4944433158879836, Some(-3.), None);
583 vector_point.unproject();
584
585 assert_eq!(vector_point.x, 0.9999999999999964);
586 assert_eq!(vector_point.y, 2.0000000000000093);
587 assert_eq!(vector_point.z, Some(-3.));
588 assert_eq!(vector_point.m, None);
589 assert_eq!(vector_point.t, None);
590 }
591
592 #[test]
593 fn test_distance() {
594 let vector_point: VectorPoint = VectorPoint::new(1.0, 2.0, None, None);
595 let other: VectorPoint = VectorPoint::new(3.0, 4.0, None, None);
596 assert_eq!(vector_point.distance(&other), 2.8284271247461903);
597 }
598
599 #[test]
600 fn from_point() {
601 let point = Point(1.0, 2.0);
602 let vector_point: VectorPoint = point.into();
603 assert_eq!(vector_point.x, 1.0);
604 assert_eq!(vector_point.y, 2.0);
605 assert_eq!(vector_point.z, None);
606 assert_eq!(vector_point.m, None);
607 assert_eq!(vector_point.t, None);
608
609 let point = Point(1.0, 2.0);
610 let vector_point: VectorPoint = (&point).into();
611 assert_eq!(vector_point.x, 1.0);
612 assert_eq!(vector_point.y, 2.0);
613 assert_eq!(vector_point.z, None);
614 assert_eq!(vector_point.m, None);
615 assert_eq!(vector_point.t, None);
616 }
617
618 #[test]
619 fn from_point_3d() {
620 let point: Point3D = Point3D(1.0, 2.0, 3.0);
621 let vector_point: VectorPoint = point.into();
622 assert_eq!(vector_point.x, 1.0);
623 assert_eq!(vector_point.y, 2.0);
624 assert_eq!(vector_point.z, Some(3.0));
625 assert_eq!(vector_point.m, None);
626 assert_eq!(vector_point.t, None);
627
628 let point: Point3D = Point3D(1.0, 2.0, 3.0);
629 let vector_point: VectorPoint = (&point).into();
630 assert_eq!(vector_point.x, 1.0);
631 assert_eq!(vector_point.y, 2.0);
632 assert_eq!(vector_point.z, Some(3.0));
633 assert_eq!(vector_point.m, None);
634 assert_eq!(vector_point.t, None);
635 }
636
637 #[test]
638 fn vector_point() {
639 let vector_point: VectorPoint =
640 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
641 assert_eq!(vector_point.x, 1.0);
642 assert_eq!(vector_point.y, 2.0);
643 assert_eq!(vector_point.z, Some(3.0));
644 assert_eq!(vector_point.m, None);
645 assert_eq!(vector_point.t, None);
646 }
647
648 #[test]
649 fn vector_neg() {
650 let vector_point = VectorPoint::<MValue> { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
651 let result = -&vector_point;
652 assert_eq!(result.x, -1.0);
653 assert_eq!(result.y, -2.0);
654 assert_eq!(result.z, Some(-3.0));
655 assert_eq!(result.m, None);
656 assert_eq!(result.t, None);
657 }
658
659 #[test]
660 fn vector_point_add() {
661 let vector_point1: VectorPoint =
662 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
663 let vector_point2: VectorPoint =
664 VectorPoint { x: 4.0, y: 5.0, z: Some(6.0), m: None, t: Some(5.2) };
665 let result = &vector_point1 + &vector_point2;
666 assert_eq!(result.x, 5.0);
667 assert_eq!(result.y, 7.0);
668 assert_eq!(result.z, Some(9.0));
669 assert_eq!(result.m, None);
670 assert_eq!(result.t, None);
671
672 let vector_point1 = VectorPoint::from_xy(1., 2.);
673 let vector_point2 = VectorPoint::from_xy(4., 5.);
674 let result = &vector_point1 + &vector_point2;
675 assert_eq!(result.x, 5.0);
676 assert_eq!(result.y, 7.0);
677 assert_eq!(result.z, None);
678 assert_eq!(result.m, None);
679 assert_eq!(result.t, None);
680
681 let mut vector_point1 = VectorPoint::from_xyz(1., 2., 3.);
683 let vector_point2 = VectorPoint::from_xyz(4., 5., 6.);
684 vector_point1 += &vector_point2;
685 assert_eq!(vector_point1.x, 5.0);
686 assert_eq!(vector_point1.y, 7.0);
687 assert_eq!(vector_point1.z, Some(9.0));
688 assert_eq!(vector_point1.m, None);
689 assert_eq!(vector_point1.t, None);
690 }
691
692 #[test]
693 fn vector_point_add_f64() {
694 let vector_point1: VectorPoint =
695 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
696 let float: f64 = 4.0;
697 let result = &vector_point1 + float;
698 assert_eq!(result.x, 5.0);
699 assert_eq!(result.y, 6.0);
700 assert_eq!(result.z, Some(7.0));
701 assert_eq!(result.m, None);
702 assert_eq!(result.t, None);
703
704 let mut vector_point1: VectorPoint =
706 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
707 let float: f64 = 4.0;
708 vector_point1 += float;
709 assert_eq!(vector_point1.x, 5.0);
710 assert_eq!(vector_point1.y, 6.0);
711 assert_eq!(vector_point1.z, Some(7.0));
712 assert_eq!(vector_point1.m, None);
713 assert_eq!(vector_point1.t, None);
714 }
715
716 #[test]
717 fn vector_point_sub() {
718 let vector_point1 =
719 VectorPoint::<MValue> { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
720 let vector_point2 =
721 VectorPoint::<MValue> { x: 4.0, y: 5.0, z: Some(6.0), m: None, t: Some(5.2) };
722 let result = &vector_point1 - &vector_point2;
723 assert_eq!(result.x, -3.0);
724 assert_eq!(result.y, -3.0);
725 assert_eq!(result.z, Some(-3.0));
726 assert_eq!(result.m, None);
727 assert_eq!(result.t, None);
728
729 let vector_point1 = VectorPoint::from_xy(1., 2.);
730 let vector_point2 = VectorPoint::from_xy(4., 5.);
731 let result = &vector_point1 - &vector_point2;
732 assert_eq!(result.x, -3.0);
733 assert_eq!(result.y, -3.0);
734 assert_eq!(result.z, None);
735 assert_eq!(result.m, None);
736 assert_eq!(result.t, None);
737
738 let mut vector_point1 = VectorPoint::from_xyz(1., 2., 3.);
740 let vector_point2 = VectorPoint::from_xyz(4., 5., 6.);
741 vector_point1 -= &vector_point2;
742 assert_eq!(vector_point1.x, -3.0);
743 assert_eq!(vector_point1.y, -3.0);
744 assert_eq!(vector_point1.z, Some(-3.0));
745 assert_eq!(vector_point1.m, None);
746 assert_eq!(vector_point1.t, None);
747 }
748
749 #[test]
750 fn vector_point_sub_f64() {
751 let vector_point1: VectorPoint =
752 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
753 let float: f64 = 4.0;
754 let result = &vector_point1 - float;
755 assert_eq!(result.x, -3.0);
756 assert_eq!(result.y, -2.0);
757 assert_eq!(result.z, Some(-1.0));
758 assert_eq!(result.m, None);
759 assert_eq!(result.t, None);
760
761 let mut vector_point1: VectorPoint =
763 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
764 let float: f64 = 4.0;
765 vector_point1 -= float;
766 assert_eq!(vector_point1.x, -3.0);
767 assert_eq!(vector_point1.y, -2.0);
768 assert_eq!(vector_point1.z, Some(-1.0));
769 assert_eq!(vector_point1.m, None);
770 assert_eq!(vector_point1.t, None);
771 }
772
773 #[test]
774 fn vector_point_mul() {
775 let vector_point1: VectorPoint =
776 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
777 let vector_point2: VectorPoint =
778 VectorPoint { x: 4.0, y: 5.0, z: Some(6.0), m: None, t: Some(5.2) };
779 let result = &vector_point1 * &vector_point2;
780 assert_eq!(result.x, 4.0);
781 assert_eq!(result.y, 10.0);
782 assert_eq!(result.z, Some(18.0));
783 assert_eq!(result.m, None);
784 assert_eq!(result.t, None);
785
786 let vector_point1 = VectorPoint::from_xy(1., 2.);
787 let vector_point2 = VectorPoint::from_xy(4., 5.);
788 let result = &vector_point1 * &vector_point2;
789 assert_eq!(result.x, 4.0);
790 assert_eq!(result.y, 10.0);
791 assert_eq!(result.z, None);
792 assert_eq!(result.m, None);
793 assert_eq!(result.t, None);
794
795 let mut vector_point1 = VectorPoint::from_xyz(1., 2., 3.);
797 let vector_point2 = VectorPoint::from_xyz(4., 5., 6.);
798 vector_point1 *= &vector_point2;
799 assert_eq!(vector_point1.x, 4.0);
800 assert_eq!(vector_point1.y, 10.0);
801 assert_eq!(vector_point1.z, Some(18.0));
802 assert_eq!(vector_point1.m, None);
803 assert_eq!(vector_point1.t, None);
804 }
805
806 #[test]
807 fn vector_point_mul_f64() {
808 let vector_point1: VectorPoint =
809 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
810 let float: f64 = 4.0;
811 let result = &vector_point1 * float;
812 assert_eq!(result.x, 4.0);
813 assert_eq!(result.y, 8.0);
814 assert_eq!(result.z, Some(12.0));
815 assert_eq!(result.m, None);
816 assert_eq!(result.t, None);
817
818 let mut vector_point1: VectorPoint =
820 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
821 let float: f64 = 4.0;
822 vector_point1 *= float;
823 assert_eq!(vector_point1.x, 4.0);
824 assert_eq!(vector_point1.y, 8.0);
825 assert_eq!(vector_point1.z, Some(12.0));
826 assert_eq!(vector_point1.m, None);
827 assert_eq!(vector_point1.t, None);
828 }
829
830 #[test]
831 fn vector_point_div() {
832 let vector_point1: VectorPoint =
833 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
834 let vector_point2: VectorPoint =
835 VectorPoint { x: 4.0, y: 5.0, z: Some(6.0), m: None, t: Some(5.2) };
836 let result = &vector_point1 / &vector_point2;
837 assert_eq!(result.x, 0.25);
838 assert_eq!(result.y, 0.4);
839 assert_eq!(result.z, Some(0.5));
840 assert_eq!(result.m, None);
841 assert_eq!(result.t, None);
842
843 let vector_point1 = VectorPoint::from_xy(1., 2.);
844 let vector_point2 = VectorPoint::from_xy(4., 5.);
845 let result = &vector_point1 / &vector_point2;
846 assert_eq!(result.x, 0.25);
847 assert_eq!(result.y, 0.4);
848 assert_eq!(result.z, None);
849 assert_eq!(result.m, None);
850 assert_eq!(result.t, None);
851
852 let mut vector_point1 = VectorPoint::from_xyz(1., 2., 3.);
854 let vector_point2 = VectorPoint::from_xyz(4., 5., 6.);
855 vector_point1 /= &vector_point2;
856 assert_eq!(vector_point1.x, 0.25);
857 assert_eq!(vector_point1.y, 0.4);
858 assert_eq!(vector_point1.z, Some(0.5));
859 assert_eq!(vector_point1.m, None);
860 assert_eq!(vector_point1.t, None);
861 }
862
863 #[test]
864 fn vector_point_div_f64() {
865 let vector_point1: VectorPoint =
866 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
867 let float: f64 = 4.0;
868 let result = &vector_point1 / float;
869 assert_eq!(result.x, 0.25);
870 assert_eq!(result.y, 0.5);
871 assert_eq!(result.z, Some(0.75));
872 assert_eq!(result.m, None);
873 assert_eq!(result.t, None);
874
875 let mut vector_point1: VectorPoint =
877 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
878 let float: f64 = 4.0;
879 vector_point1 /= float;
880 assert_eq!(vector_point1.x, 0.25);
881 assert_eq!(vector_point1.y, 0.5);
882 assert_eq!(vector_point1.z, Some(0.75));
883 assert_eq!(vector_point1.m, None);
884 assert_eq!(vector_point1.t, None);
885 }
886
887 #[test]
888 fn vector_point_rem() {
889 let vector_point1: VectorPoint =
890 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
891 let result = vector_point1 % 2.;
892 assert_eq!(result.x, 1.0);
893 assert_eq!(result.y, 0.0);
894 assert_eq!(result.z, Some(1.0));
895 assert_eq!(result.m, None);
896 assert_eq!(result.t, None);
897 }
898
899 #[test]
900 fn vector_point_rem_assigned() {
901 let mut vector_point1: VectorPoint =
902 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
903 vector_point1 %= 2.;
904 assert_eq!(vector_point1.x, 1.0);
905 assert_eq!(vector_point1.y, 0.0);
906 assert_eq!(vector_point1.z, Some(1.0));
907 assert_eq!(vector_point1.m, None);
908 assert_eq!(vector_point1.t, None);
909 }
910
911 #[test]
912 fn vector_equality() {
913 let vector_point1: VectorPoint =
914 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
915 let vector_point2: VectorPoint =
916 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
917 assert_eq!(vector_point1, vector_point2);
918
919 let vector_point1: VectorPoint =
920 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
921 let vector_point2: VectorPoint =
922 VectorPoint { x: 2.0, y: 3.0, z: Some(4.0), m: None, t: None };
923 assert_ne!(vector_point1, vector_point2);
924
925 let vector_point1: VectorPoint =
926 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
927 let vector_point2: VectorPoint = VectorPoint { x: 1.0, y: 2.0, z: None, m: None, t: None };
928 assert_ne!(vector_point1, vector_point2);
929
930 let vector_point1: VectorPoint =
931 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
932 let vector_point2: VectorPoint =
933 VectorPoint { x: 1.0, y: 2.0, z: Some(1.0), m: None, t: None };
934 assert_ne!(vector_point1, vector_point2);
935 }
936
937 #[test]
938 fn test_vectorpoint_ordering_x() {
939 let a: VectorPoint = VectorPoint { x: 1.0, y: 0.0, z: None, m: None, t: None };
940 let b: VectorPoint = VectorPoint { x: 2.0, y: 0.0, z: None, m: None, t: None };
941 assert_eq!(a.cmp(&b), Ordering::Less);
942 assert_eq!(b.cmp(&a), Ordering::Greater);
943 }
944
945 #[test]
946 fn test_vectorpoint_ordering_y() {
947 let a: VectorPoint = VectorPoint { x: 1.0, y: 1.0, z: None, m: None, t: None };
948 let b = VectorPoint { x: 1.0, y: 2.0, z: None, m: None, t: None };
949 assert_eq!(a.cmp(&b), Ordering::Less);
950 assert_eq!(b.cmp(&a), Ordering::Greater);
951 }
952
953 #[test]
954 fn test_vectorpoint_ordering_z() {
955 let a: VectorPoint = VectorPoint { x: 1.0, y: 1.0, z: Some(1.0), m: None, t: None };
956 let b = VectorPoint { x: 1.0, y: 1.0, z: Some(2.0), m: None, t: None };
957 assert_eq!(a.cmp(&b), Ordering::Less);
958 assert_eq!(b.cmp(&a), Ordering::Greater);
959 }
960
961 #[test]
962 fn test_vectorpoint_ordering_z_none() {
963 let a: VectorPoint = VectorPoint { x: 1.0, y: 1.0, z: None, m: None, t: None };
964 let b = VectorPoint { x: 1.0, y: 1.0, z: Some(2.0), m: None, t: None };
965 assert_eq!(a.cmp(&b), Ordering::Less); assert_eq!(b.cmp(&a), Ordering::Greater);
967 }
968
969 #[test]
970 fn test_vectorpoint_ordering_z_some() {
971 let a: VectorPoint = VectorPoint { x: 1.0, y: 1.0, z: Some(-1.0), m: None, t: None };
972 let b = VectorPoint { x: 1.0, y: 1.0, z: Some(2.0), m: None, t: None };
973 assert_eq!(a.cmp(&b), Ordering::Less); assert_eq!(b.cmp(&a), Ordering::Greater);
975 }
976
977 #[test]
978 fn test_vectorpoint_equality() {
979 let a: VectorPoint = VectorPoint { x: 1.0, y: 1.0, z: Some(1.0), m: None, t: None };
980 let b = VectorPoint { x: 1.0, y: 1.0, z: Some(1.0), m: None, t: None };
981 assert_eq!(a, b);
982 assert_eq!(a.cmp(&b), Ordering::Equal);
983 }
984
985 #[test]
986 fn test_vectorpoint_nan_handling() {
987 let nan_point: VectorPoint = VectorPoint { x: f64::NAN, y: 1.0, z: None, m: None, t: None };
988 let normal_point = VectorPoint { x: 1.0, y: 1.0, z: None, m: None, t: None };
989
990 assert_eq!(nan_point.cmp(&normal_point), Ordering::Greater);
992
993 let nan_point: VectorPoint =
995 VectorPoint { x: 1.0, y: 1.0, z: Some(f64::NAN), m: None, t: None };
996 let normal_point = VectorPoint { x: 1.0, y: 1.0, z: Some(1.0), m: None, t: None };
997 assert_eq!(nan_point.cmp(&normal_point), Ordering::Equal);
998 }
999
1000 #[test]
1001 fn test_vectorpoint_partial_comp() {
1002 let vector_point1: VectorPoint =
1003 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
1004 let vector_point2 = VectorPoint { x: 1.0, y: 2.0, z: Some(1.0), m: None, t: None };
1005
1006 assert_eq!(vector_point1.partial_cmp(&vector_point2), Some(Ordering::Greater));
1007 assert_eq!(vector_point2.partial_cmp(&vector_point1), Some(Ordering::Less));
1008 }
1009
1010 #[test]
1011 fn test_vectorpoint_with_m() {
1012 let vector_point1: VectorPoint<MValue> = VectorPoint {
1013 x: 1.0,
1014 y: 2.0,
1015 z: Some(3.0),
1016 m: Some(Value::from([
1017 ("class".into(), ValueType::Primitive(PrimitiveValue::String("ocean".into()))),
1018 ("offset".into(), ValueType::Primitive(PrimitiveValue::U64(22))),
1019 (
1020 "info".into(),
1021 ValueType::Nested(Value::from([
1022 (
1023 "name".into(),
1024 ValueType::Primitive(PrimitiveValue::String("Pacific Ocean".into())),
1025 ),
1026 ("value".into(), ValueType::Primitive(PrimitiveValue::F32(22.2))),
1027 ])),
1028 ),
1029 ])),
1030 t: Some(-1.2),
1031 };
1032 let vector_point2: VectorPoint<MValue> =
1033 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
1034 assert_eq!(vector_point1.partial_cmp(&vector_point2), Some(Ordering::Equal));
1035 assert!(vector_point1 == vector_point2);
1037 }
1038
1039 #[test]
1040 fn is_empty() {
1041 let vector_point1 = VectorPoint::from_xy(1.0, 2.0);
1042 assert!(!vector_point1.is_empty());
1043 let vector_point2 = VectorPoint::from_xyz(1.0, 2.0, 3.0);
1044 assert!(!vector_point2.is_empty());
1045 let vector_point3 = VectorPoint::from_xyz(0.0, 0.0, 0.0);
1046 assert!(vector_point3.is_empty());
1047 let vector_point4 = VectorPoint::from_xy(0.0, 0.0);
1048 assert!(vector_point4.is_empty());
1049 }
1050
1051 #[test]
1052 fn get_face() {
1053 let point = VectorPoint::from_xyz(1.0, 2.0, 3.0);
1054 assert_eq!(point.face(0), 1.);
1055 assert_eq!(point.face(1), 2.);
1056 assert_eq!(point.face(2), 3.);
1057 let point = VectorPoint::from_xy(1.0, 2.0);
1058 assert_eq!(point.face(0), 1.);
1059 assert_eq!(point.face(1), 2.);
1060 assert_eq!(point.face(2), 0.);
1061 }
1062
1063 #[test]
1064 #[allow(clippy::approx_constant)]
1065 fn angle() {
1066 let point1 = VectorPoint::from_xyz(1.0, 0.0, 0.0);
1067 let point2 = VectorPoint::from_xyz(0.0, 1.0, 0.0);
1068 assert_eq!(point1.angle(&point2), 1.5707963267948966);
1069
1070 let point1 = VectorPoint::from_xy(1.0, 0.0);
1071 let point2 = VectorPoint::from_xy(0.0, 1.0);
1072 assert_eq!(point1.angle(&point2), 1.5707963267948966);
1073 }
1074
1075 #[test]
1076 fn abs() {
1077 let point = VectorPoint::from_xyz(1.0, 2.0, 3.0);
1078 assert_eq!(point.abs(), VectorPoint::from_xyz(1.0, 2.0, 3.0));
1079
1080 let point = VectorPoint::from_xyz(-1.0, -2.0, -3.0);
1081 assert_eq!(point.abs(), VectorPoint::from_xyz(1.0, 2.0, 3.0));
1082
1083 let point = VectorPoint::from_xy(1.0, 2.0);
1084 assert_eq!(point.abs(), VectorPoint::from_xy(1.0, 2.0));
1085
1086 let point = VectorPoint::from_xy(-1.0, -2.0);
1087 assert_eq!(point.abs(), VectorPoint::from_xy(1.0, 2.0));
1088 }
1089
1090 #[test]
1091 fn invert() {
1092 let point = VectorPoint::from_xyz(1.0, 2.0, 3.0);
1093 assert_eq!(point.invert(), VectorPoint::from_xyz(-1.0, -2.0, -3.0));
1094
1095 let point = VectorPoint::from_xy(1.0, 2.0);
1096 assert_eq!(point.invert(), VectorPoint::from_xy(-1.0, -2.0));
1097 }
1098
1099 #[test]
1100 fn normalize() {
1101 let mut point = VectorPoint::from_xyz(1.0, 2.0, 3.0);
1102 point.normalize();
1103 assert_eq!(
1104 point,
1105 VectorPoint::from_xyz(0.2672612419124244, 0.5345224838248488, 0.8017837257372732)
1106 );
1107
1108 let mut point = VectorPoint::from_xyz(0.0, 0.0, 0.0);
1109 point.normalize();
1110 assert_eq!(point, VectorPoint::from_xyz(0.0, 0.0, 0.0));
1111 }
1112
1113 #[test]
1114 fn largest_abs_component() {
1115 let point = VectorPoint::from_xyz(1.0, 2.0, 3.0);
1116 assert_eq!(point.largest_abs_component(), 2);
1117 let point = VectorPoint::from_xyz(3.0, 2.0, 1.0);
1118 assert_eq!(point.largest_abs_component(), 0);
1119 let point = VectorPoint::from_xyz(1.0, 3.0, 2.0);
1120 assert_eq!(point.largest_abs_component(), 1);
1121 let point = VectorPoint::from_xyz(2.0, 1.0, 3.0);
1122 assert_eq!(point.largest_abs_component(), 2);
1123 }
1124
1125 #[test]
1126 fn intermediate() {
1127 let point1 = VectorPoint::from_xyz(1.0, 2.0, 3.0);
1128 let point2 = VectorPoint::from_xyz(4.0, 5.0, 6.0);
1129 assert_eq!(point1.intermediate(&point2, 0.5), VectorPoint::from_xyz(2.5, 3.5, 4.5));
1130
1131 let point1 = VectorPoint::from_xy(1.0, 2.0);
1132 let point2 = VectorPoint::from_xy(4.0, 5.0);
1133 assert_eq!(point1.intermediate(&point2, 0.5), VectorPoint::from_xy(2.5, 3.5));
1134 }
1135
1136 #[test]
1137 fn perpendicular() {
1138 let point = VectorPoint::from_xyz(1.0, 2.0, 3.0);
1139 assert_eq!(point.perpendicular(), VectorPoint::from_xyz(-2.0, 1.0, -2.0));
1140
1141 let point = VectorPoint::from_xyz(3.0, 2.0, 1.0);
1142 assert_eq!(point.perpendicular(), VectorPoint::from_xyz(-2.0, 3.0, 0.0));
1143
1144 let point = VectorPoint::from_xy(1.0, 2.0);
1145 assert_eq!(point.perpendicular(), VectorPoint::from_xy(-2., 1.));
1146 }
1147}