1use core::{
2 cmp::Ordering,
3 f64::consts::PI,
4 fmt::Debug,
5 ops::{Add, Div, Mul, Neg, Rem, RemAssign, Sub},
6};
7use libm::{atan, fabs, fmod, log, pow, sin, sinh, sqrt};
8use serde::{Deserialize, Serialize};
9
10use crate::*;
12
13#[derive(Serialize, Deserialize, Debug, Clone, Default)]
15pub struct VectorPoint<M: MValueCompatible = MValue> {
16 pub x: f64,
18 pub y: f64,
20 pub z: Option<f64>,
22 #[serde(skip_serializing_if = "Option::is_none")]
24 pub m: Option<M>,
25 #[serde(skip)]
27 pub t: Option<f64>,
28}
29impl VectorPoint<MValue> {
30 pub fn from_xy(x: f64, y: f64) -> Self {
32 Self { x, y, z: None, m: None, t: None }
33 }
34
35 pub fn from_xyz(x: f64, y: f64, z: f64) -> Self {
37 Self { x, y, z: Some(z), m: None, t: None }
38 }
39}
40impl<M: MValueCompatible> VectorPoint<M> {
41 pub fn new(x: f64, y: f64, z: Option<f64>, m: Option<M>) -> Self {
43 Self { x, y, z, m, t: None }
44 }
45
46 pub fn new_xy(x: f64, y: f64, m: Option<M>) -> Self {
48 Self { x, y, z: None, m, t: None }
49 }
50
51 pub fn new_xyz(x: f64, y: f64, z: f64, m: Option<M>) -> Self {
53 Self { x, y, z: Some(z), m, t: None }
54 }
55
56 pub fn project(&mut self, bbox: Option<&mut BBox3D>) {
58 let y = self.y;
59 let x = self.x;
60 let sin = sin((y * PI) / 180.);
61 let y2 = 0.5 - (0.25 * log((1. + sin) / (1. - sin))) / PI;
62 self.x = x / 360. + 0.5;
63 self.y = y2.clamp(0., 1.);
64
65 if let Some(bbox) = bbox {
66 bbox.extend_from_point(self)
67 };
68 }
69
70 pub fn unproject(&mut self) {
72 let lon = (self.x - 0.5) * 360.;
73 let y2 = 0.5 - self.y;
74 let lat = atan(sinh(PI * (y2 * 2.))).to_degrees();
75
76 self.x = lon;
77 self.y = lat;
78 }
79
80 pub fn distance<M2: MValueCompatible>(&self, other: &VectorPoint<M2>) -> f64 {
82 sqrt(pow(other.x - self.x, 2.) + pow(other.y - self.y, 2.))
83 }
84
85 pub fn modulo(self, modulus: f64) -> Self {
87 let modulus = fabs(modulus); Self {
89 x: fmod(self.x, modulus),
90 y: fmod(self.y, modulus),
91 z: self.z.map(|z| fmod(z, modulus)),
92 m: self.m,
93 t: None,
94 }
95 }
96}
97impl<M: MValueCompatible> From<Point> for VectorPoint<M> {
98 fn from(p: Point) -> Self {
99 Self { x: p.0, y: p.1, z: None, m: None, t: None }
100 }
101}
102impl<M: MValueCompatible> From<&Point> for VectorPoint<M> {
103 fn from(p: &Point) -> Self {
104 Self { x: p.0, y: p.1, z: None, m: None, t: None }
105 }
106}
107impl<M: MValueCompatible> From<Point3D> for VectorPoint<M> {
108 fn from(p: Point3D) -> Self {
109 Self { x: p.0, y: p.1, z: Some(p.2), m: None, t: None }
110 }
111}
112impl<M: MValueCompatible> From<&Point3D> for VectorPoint<M> {
113 fn from(p: &Point3D) -> Self {
114 Self { x: p.0, y: p.1, z: Some(p.2), m: None, t: None }
115 }
116}
117impl<M1: MValueCompatible, M2: MValueCompatible> Add<VectorPoint<M2>> for VectorPoint<M1> {
118 type Output = VectorPoint<M1>;
119 fn add(self, other: VectorPoint<M2>) -> Self::Output {
120 VectorPoint {
121 x: self.x + other.x,
122 y: self.y + other.y,
123 z: match (self.z, other.z) {
125 (Some(z1), Some(z2)) => Some(z1 + z2),
126 _ => None, },
128 m: self.m.clone(), t: self.t.or(other.t), }
131 }
132}
133impl<M: MValueCompatible> Add<f64> for VectorPoint<M> {
134 type Output = VectorPoint<M>;
135 fn add(self, other: f64) -> Self::Output {
136 VectorPoint {
137 x: self.x + other,
138 y: self.y + other,
139 z: self.z.map(|z| z + other),
140 m: self.m.clone(),
141 t: self.t,
142 }
143 }
144}
145impl<M1: MValueCompatible, M2: MValueCompatible> Sub<VectorPoint<M2>> for VectorPoint<M1> {
147 type Output = VectorPoint<M1>;
148 fn sub(self, other: VectorPoint<M2>) -> Self::Output {
149 VectorPoint {
150 x: self.x - other.x,
151 y: self.y - other.y,
152 z: match (self.z, other.z) {
153 (Some(z1), Some(z2)) => Some(z1 - z2),
154 _ => None, },
156 m: self.m.clone(), t: self.t.or(other.t), }
159 }
160}
161impl<M: MValueCompatible> Sub<f64> for VectorPoint<M> {
162 type Output = VectorPoint<M>;
163 fn sub(self, other: f64) -> Self::Output {
164 VectorPoint {
165 x: self.x - other,
166 y: self.y - other,
167 z: self.z.map(|z| z - other),
168 m: self.m.clone(),
169 t: self.t,
170 }
171 }
172}
173impl<M: MValueCompatible> Neg for VectorPoint<M> {
175 type Output = VectorPoint<M>;
176 fn neg(self) -> Self::Output {
177 VectorPoint { x: -self.x, y: -self.y, z: self.z.map(|z| -z), m: self.m.clone(), t: self.t }
178 }
179}
180impl<M1: MValueCompatible, M2: MValueCompatible> Div<VectorPoint<M2>> for VectorPoint<M1> {
182 type Output = VectorPoint<M1>;
183 fn div(self, other: VectorPoint<M2>) -> Self::Output {
184 VectorPoint {
185 x: self.x / other.x,
186 y: self.y / other.y,
187 z: match (self.z, other.z) {
188 (Some(z1), Some(z2)) => Some(z1 / z2),
189 _ => None, },
191 m: self.m.clone(), t: self.t.or(other.t), }
194 }
195}
196impl<M: MValueCompatible> Div<f64> for VectorPoint<M> {
197 type Output = VectorPoint<M>;
198 fn div(self, other: f64) -> Self::Output {
199 VectorPoint {
200 x: self.x / other,
201 y: self.y / other,
202 z: self.z.map(|z| z / other),
203 m: self.m.clone(),
204 t: self.t,
205 }
206 }
207}
208impl<M1: MValueCompatible, M2: MValueCompatible> Mul<VectorPoint<M2>> for VectorPoint<M1> {
210 type Output = VectorPoint<M1>;
211 fn mul(self, other: VectorPoint<M2>) -> Self::Output {
212 VectorPoint {
213 x: self.x * other.x,
214 y: self.y * other.y,
215 z: match (self.z, other.z) {
216 (Some(z1), Some(z2)) => Some(z1 * z2),
217 _ => None, },
219 m: self.m.clone(), t: self.t.or(other.t), }
222 }
223}
224impl<M: MValueCompatible> Mul<f64> for VectorPoint<M> {
225 type Output = VectorPoint<M>;
226 fn mul(self, other: f64) -> Self::Output {
227 VectorPoint {
228 x: self.x * other,
229 y: self.y * other,
230 z: self.z.map(|z| z * other),
231 m: self.m.clone(),
232 t: self.t,
233 }
234 }
235}
236impl<M: MValueCompatible> Rem<f64> for VectorPoint<M> {
237 type Output = VectorPoint<M>;
238
239 fn rem(self, modulus: f64) -> Self::Output {
240 self.modulo(modulus)
241 }
242}
243impl<M: MValueCompatible> RemAssign<f64> for VectorPoint<M> {
244 fn rem_assign(&mut self, modulus: f64) {
245 let modulus = fabs(modulus);
246 self.x = fmod(self.x, modulus);
247 self.y = fmod(self.y, modulus);
248 if let Some(z) = self.z {
249 self.z = Some(fmod(z, modulus));
250 }
251 }
252}
253impl<M: MValueCompatible> Eq for VectorPoint<M> {}
254impl<M: MValueCompatible> Ord for VectorPoint<M> {
255 fn cmp(&self, other: &VectorPoint<M>) -> Ordering {
256 match self.x.partial_cmp(&other.x) {
257 Some(Ordering::Equal) => {}
258 other => return other.unwrap_or(Ordering::Greater), }
260 match self.y.partial_cmp(&other.y) {
261 Some(Ordering::Equal) => {}
262 other => return other.unwrap_or(Ordering::Greater), }
264 match self.z.partial_cmp(&other.z) {
265 Some(order) => order,
266 None => Ordering::Equal, }
268 }
269}
270impl<M: MValueCompatible> PartialEq for VectorPoint<M> {
271 fn eq(&self, other: &VectorPoint<M>) -> bool {
272 self.x == other.x && self.y == other.y && self.z == other.z
273 }
274}
275impl<M: MValueCompatible> PartialOrd for VectorPoint<M> {
276 fn partial_cmp(&self, other: &VectorPoint<M>) -> Option<Ordering> {
277 Some(self.cmp(other))
278 }
279}
280
281#[cfg(test)]
282mod tests {
283 use super::*;
284
285 #[test]
286 fn new() {
287 let vector_point: VectorPoint = VectorPoint::new(1.0, 2.0, None, None);
288 assert_eq!(vector_point.x, 1.0);
289 assert_eq!(vector_point.y, 2.0);
290 assert_eq!(vector_point.z, None);
291 assert_eq!(vector_point.m, None);
292 assert_eq!(vector_point.t, None);
293 }
294
295 #[test]
296 fn new_xy() {
297 let vector_point: VectorPoint = VectorPoint::new_xy(1.0, 2.0, None);
298 assert_eq!(vector_point.x, 1.0);
299 assert_eq!(vector_point.y, 2.0);
300 assert_eq!(vector_point.z, None);
301 assert_eq!(vector_point.m, None);
302 assert_eq!(vector_point.t, None);
303 }
304
305 #[test]
306 fn new_xyz() {
307 let vector_point: VectorPoint = VectorPoint::new_xyz(1.0, 2.0, 3.0, None);
308 assert_eq!(vector_point.x, 1.0);
309 assert_eq!(vector_point.y, 2.0);
310 assert_eq!(vector_point.z, Some(3.0));
311 assert_eq!(vector_point.m, None);
312 assert_eq!(vector_point.t, None);
313 }
314
315 #[test]
316 fn from_xy() {
317 let vector_point: VectorPoint = VectorPoint::from_xy(1.0, 2.0);
318 assert_eq!(vector_point.x, 1.0);
319 assert_eq!(vector_point.y, 2.0);
320 assert_eq!(vector_point.z, None);
321 assert_eq!(vector_point.m, None);
322 assert_eq!(vector_point.t, None);
323 }
324
325 #[test]
326 fn from_xyz() {
327 let vector_point: VectorPoint = VectorPoint::from_xyz(1.0, 2.0, 3.0);
328 assert_eq!(vector_point.x, 1.0);
329 assert_eq!(vector_point.y, 2.0);
330 assert_eq!(vector_point.z, Some(3.0));
331 assert_eq!(vector_point.m, None);
332 assert_eq!(vector_point.t, None);
333 }
334
335 #[test]
336 fn project() {
337 let mut vector_point: VectorPoint = VectorPoint::new(1.0, 2.0, Some(-3.), None);
338 let mut bbox: BBox3D = BBox3D::new(1., 1., 0., 0., 0., 1.);
339 vector_point.project(Some(&mut bbox));
340 assert_eq!(vector_point.x, 0.5027777777777778);
341 assert_eq!(vector_point.y, 0.4944433158879836);
342 assert_eq!(vector_point.z, Some(-3.));
343 assert_eq!(vector_point.m, None);
344 assert_eq!(vector_point.t, None);
345
346 assert_eq!(bbox.left, 0.5027777777777778);
347 assert_eq!(bbox.bottom, 0.4944433158879836);
348 assert_eq!(bbox.right, 0.5027777777777778);
349 assert_eq!(bbox.top, 0.4944433158879836);
350 assert_eq!(bbox.near, -3.);
351 assert_eq!(bbox.far, 1.0);
352 }
353
354 #[test]
355 fn unproject() {
356 let mut vector_point: VectorPoint =
357 VectorPoint::new(0.5027777777777778, 0.4944433158879836, Some(-3.), None);
358 vector_point.unproject();
359
360 assert_eq!(vector_point.x, 0.9999999999999964);
361 assert_eq!(vector_point.y, 2.0000000000000093);
362 assert_eq!(vector_point.z, Some(-3.));
363 assert_eq!(vector_point.m, None);
364 assert_eq!(vector_point.t, None);
365 }
366
367 #[test]
368 fn test_distance() {
369 let vector_point: VectorPoint = VectorPoint::new(1.0, 2.0, None, None);
370 let other: VectorPoint = VectorPoint::new(3.0, 4.0, None, None);
371 assert_eq!(vector_point.distance(&other), 2.8284271247461903);
372 }
373
374 #[test]
375 fn from_point() {
376 let point = Point(1.0, 2.0);
377 let vector_point: VectorPoint = point.into();
378 assert_eq!(vector_point.x, 1.0);
379 assert_eq!(vector_point.y, 2.0);
380 assert_eq!(vector_point.z, None);
381 assert_eq!(vector_point.m, None);
382 assert_eq!(vector_point.t, None);
383
384 let point = Point(1.0, 2.0);
385 let vector_point: VectorPoint = (&point).into();
386 assert_eq!(vector_point.x, 1.0);
387 assert_eq!(vector_point.y, 2.0);
388 assert_eq!(vector_point.z, None);
389 assert_eq!(vector_point.m, None);
390 assert_eq!(vector_point.t, None);
391 }
392
393 #[test]
394 fn from_point_3d() {
395 let point: Point3D = Point3D(1.0, 2.0, 3.0);
396 let vector_point: VectorPoint = point.into();
397 assert_eq!(vector_point.x, 1.0);
398 assert_eq!(vector_point.y, 2.0);
399 assert_eq!(vector_point.z, Some(3.0));
400 assert_eq!(vector_point.m, None);
401 assert_eq!(vector_point.t, None);
402
403 let point: Point3D = Point3D(1.0, 2.0, 3.0);
404 let vector_point: VectorPoint = (&point).into();
405 assert_eq!(vector_point.x, 1.0);
406 assert_eq!(vector_point.y, 2.0);
407 assert_eq!(vector_point.z, Some(3.0));
408 assert_eq!(vector_point.m, None);
409 assert_eq!(vector_point.t, None);
410 }
411
412 #[test]
413 fn vector_point() {
414 let vector_point: VectorPoint =
415 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
416 assert_eq!(vector_point.x, 1.0);
417 assert_eq!(vector_point.y, 2.0);
418 assert_eq!(vector_point.z, Some(3.0));
419 assert_eq!(vector_point.m, None);
420 assert_eq!(vector_point.t, None);
421 }
422
423 #[test]
424 fn vector_neg() {
425 let vector_point = VectorPoint::<MValue> { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
426 let result = -vector_point;
427 assert_eq!(result.x, -1.0);
428 assert_eq!(result.y, -2.0);
429 assert_eq!(result.z, Some(-3.0));
430 assert_eq!(result.m, None);
431 assert_eq!(result.t, None);
432 }
433
434 #[test]
435 fn vector_point_add() {
436 let vector_point1: VectorPoint =
437 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
438 let vector_point2: VectorPoint =
439 VectorPoint { x: 4.0, y: 5.0, z: Some(6.0), m: None, t: Some(5.2) };
440 let result = vector_point1 + vector_point2;
441 assert_eq!(result.x, 5.0);
442 assert_eq!(result.y, 7.0);
443 assert_eq!(result.z, Some(9.0));
444 assert_eq!(result.m, None);
445 assert_eq!(result.t, Some(5.2));
446 }
447
448 #[test]
449 fn vector_point_add_f64() {
450 let vector_point1: VectorPoint =
451 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
452 let float: f64 = 4.0;
453 let result = vector_point1 + float;
454 assert_eq!(result.x, 5.0);
455 assert_eq!(result.y, 6.0);
456 assert_eq!(result.z, Some(7.0));
457 assert_eq!(result.m, None);
458 assert_eq!(result.t, None);
459 }
460
461 #[test]
462 fn vector_point_sub() {
463 let vector_point1 =
464 VectorPoint::<MValue> { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
465 let vector_point2 =
466 VectorPoint::<MValue> { x: 4.0, y: 5.0, z: Some(6.0), m: None, t: Some(5.2) };
467 let result = vector_point1 - vector_point2;
468 assert_eq!(result.x, -3.0);
469 assert_eq!(result.y, -3.0);
470 assert_eq!(result.z, Some(-3.0));
471 assert_eq!(result.m, None);
472 assert_eq!(result.t, Some(5.2));
473 }
474
475 #[test]
476 fn vector_point_sub_f64() {
477 let vector_point1: VectorPoint =
478 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
479 let float: f64 = 4.0;
480 let result = vector_point1 - float;
481 assert_eq!(result.x, -3.0);
482 assert_eq!(result.y, -2.0);
483 assert_eq!(result.z, Some(-1.0));
484 assert_eq!(result.m, None);
485 assert_eq!(result.t, None);
486 }
487
488 #[test]
489 fn vector_point_mul() {
490 let vector_point1: VectorPoint =
491 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
492 let vector_point2: VectorPoint =
493 VectorPoint { x: 4.0, y: 5.0, z: Some(6.0), m: None, t: Some(5.2) };
494 let result = vector_point1 * vector_point2;
495 assert_eq!(result.x, 4.0);
496 assert_eq!(result.y, 10.0);
497 assert_eq!(result.z, Some(18.0));
498 assert_eq!(result.m, None);
499 assert_eq!(result.t, Some(5.2));
500 }
501
502 #[test]
503 fn vector_point_mul_f64() {
504 let vector_point1: VectorPoint =
505 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
506 let float: f64 = 4.0;
507 let result = vector_point1 * float;
508 assert_eq!(result.x, 4.0);
509 assert_eq!(result.y, 8.0);
510 assert_eq!(result.z, Some(12.0));
511 assert_eq!(result.m, None);
512 assert_eq!(result.t, None);
513 }
514
515 #[test]
516 fn vector_point_div() {
517 let vector_point1: VectorPoint =
518 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
519 let vector_point2: VectorPoint =
520 VectorPoint { x: 4.0, y: 5.0, z: Some(6.0), m: None, t: Some(5.2) };
521 let result = vector_point1 / vector_point2;
522 assert_eq!(result.x, 0.25);
523 assert_eq!(result.y, 0.4);
524 assert_eq!(result.z, Some(0.5));
525 assert_eq!(result.m, None);
526 assert_eq!(result.t, Some(5.2));
527 }
528
529 #[test]
530 fn vector_point_div_f64() {
531 let vector_point1: VectorPoint =
532 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
533 let float: f64 = 4.0;
534 let result = vector_point1 / float;
535 assert_eq!(result.x, 0.25);
536 assert_eq!(result.y, 0.5);
537 assert_eq!(result.z, Some(0.75));
538 assert_eq!(result.m, None);
539 assert_eq!(result.t, None);
540 }
541
542 #[test]
543 fn vector_point_rem() {
544 let vector_point1: VectorPoint =
545 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
546 let result = vector_point1 % 2.;
547 assert_eq!(result.x, 1.0);
548 assert_eq!(result.y, 0.0);
549 assert_eq!(result.z, Some(1.0));
550 assert_eq!(result.m, None);
551 assert_eq!(result.t, None);
552 }
553
554 #[test]
555 fn vector_point_rem_assigned() {
556 let mut vector_point1: VectorPoint =
557 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
558 vector_point1 %= 2.;
559 assert_eq!(vector_point1.x, 1.0);
560 assert_eq!(vector_point1.y, 0.0);
561 assert_eq!(vector_point1.z, Some(1.0));
562 assert_eq!(vector_point1.m, None);
563 assert_eq!(vector_point1.t, None);
564 }
565
566 #[test]
567 fn vector_equality() {
568 let vector_point1: VectorPoint =
569 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
570 let vector_point2: VectorPoint =
571 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
572 assert_eq!(vector_point1, vector_point2);
573
574 let vector_point1: VectorPoint =
575 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
576 let vector_point2: VectorPoint =
577 VectorPoint { x: 2.0, y: 3.0, z: Some(4.0), m: None, t: None };
578 assert_ne!(vector_point1, vector_point2);
579
580 let vector_point1: VectorPoint =
581 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
582 let vector_point2: VectorPoint = VectorPoint { x: 1.0, y: 2.0, z: None, m: None, t: None };
583 assert_ne!(vector_point1, vector_point2);
584
585 let vector_point1: VectorPoint =
586 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
587 let vector_point2: VectorPoint =
588 VectorPoint { x: 1.0, y: 2.0, z: Some(1.0), m: None, t: None };
589 assert_ne!(vector_point1, vector_point2);
590 }
591
592 #[test]
593 fn test_vectorpoint_ordering_x() {
594 let a: VectorPoint = VectorPoint { x: 1.0, y: 0.0, z: None, m: None, t: None };
595 let b: VectorPoint = VectorPoint { x: 2.0, y: 0.0, z: None, m: None, t: None };
596 assert_eq!(a.cmp(&b), Ordering::Less);
597 assert_eq!(b.cmp(&a), Ordering::Greater);
598 }
599
600 #[test]
601 fn test_vectorpoint_ordering_y() {
602 let a: VectorPoint = VectorPoint { x: 1.0, y: 1.0, z: None, m: None, t: None };
603 let b = VectorPoint { x: 1.0, y: 2.0, z: None, m: None, t: None };
604 assert_eq!(a.cmp(&b), Ordering::Less);
605 assert_eq!(b.cmp(&a), Ordering::Greater);
606 }
607
608 #[test]
609 fn test_vectorpoint_ordering_z() {
610 let a: VectorPoint = VectorPoint { x: 1.0, y: 1.0, z: Some(1.0), m: None, t: None };
611 let b = VectorPoint { x: 1.0, y: 1.0, z: Some(2.0), m: None, t: None };
612 assert_eq!(a.cmp(&b), Ordering::Less);
613 assert_eq!(b.cmp(&a), Ordering::Greater);
614 }
615
616 #[test]
617 fn test_vectorpoint_ordering_z_none() {
618 let a: VectorPoint = VectorPoint { x: 1.0, y: 1.0, z: None, m: None, t: None };
619 let b = VectorPoint { x: 1.0, y: 1.0, z: Some(2.0), m: None, t: None };
620 assert_eq!(a.cmp(&b), Ordering::Less); assert_eq!(b.cmp(&a), Ordering::Greater);
622 }
623
624 #[test]
625 fn test_vectorpoint_ordering_z_some() {
626 let a: VectorPoint = VectorPoint { x: 1.0, y: 1.0, z: Some(-1.0), m: None, t: None };
627 let b = VectorPoint { x: 1.0, y: 1.0, z: Some(2.0), m: None, t: None };
628 assert_eq!(a.cmp(&b), Ordering::Less); assert_eq!(b.cmp(&a), Ordering::Greater);
630 }
631
632 #[test]
633 fn test_vectorpoint_equality() {
634 let a: VectorPoint = VectorPoint { x: 1.0, y: 1.0, z: Some(1.0), m: None, t: None };
635 let b = VectorPoint { x: 1.0, y: 1.0, z: Some(1.0), m: None, t: None };
636 assert_eq!(a, b);
637 assert_eq!(a.cmp(&b), Ordering::Equal);
638 }
639
640 #[test]
641 fn test_vectorpoint_nan_handling() {
642 let nan_point: VectorPoint = VectorPoint { x: f64::NAN, y: 1.0, z: None, m: None, t: None };
643 let normal_point = VectorPoint { x: 1.0, y: 1.0, z: None, m: None, t: None };
644
645 assert_eq!(nan_point.cmp(&normal_point), Ordering::Greater);
647
648 let nan_point: VectorPoint =
650 VectorPoint { x: 1.0, y: 1.0, z: Some(f64::NAN), m: None, t: None };
651 let normal_point = VectorPoint { x: 1.0, y: 1.0, z: Some(1.0), m: None, t: None };
652 assert_eq!(nan_point.cmp(&normal_point), Ordering::Equal);
653 }
654
655 #[test]
656 fn test_vectorpoint_partial_comp() {
657 let vector_point1: VectorPoint =
658 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
659 let vector_point2 = VectorPoint { x: 1.0, y: 2.0, z: Some(1.0), m: None, t: None };
660
661 assert_eq!(vector_point1.partial_cmp(&vector_point2), Some(Ordering::Greater));
662 assert_eq!(vector_point2.partial_cmp(&vector_point1), Some(Ordering::Less));
663 }
664
665 #[test]
666 fn test_vectorpoint_with_m() {
667 let vector_point1: VectorPoint<MValue> = VectorPoint {
668 x: 1.0,
669 y: 2.0,
670 z: Some(3.0),
671 m: Some(Value::from([
672 ("class".into(), ValueType::Primitive(PrimitiveValue::String("ocean".into()))),
673 ("offset".into(), ValueType::Primitive(PrimitiveValue::U64(22))),
674 (
675 "info".into(),
676 ValueType::Nested(Value::from([
677 (
678 "name".into(),
679 ValueType::Primitive(PrimitiveValue::String("Pacific Ocean".into())),
680 ),
681 ("value".into(), ValueType::Primitive(PrimitiveValue::F32(22.2))),
682 ])),
683 ),
684 ])),
685 t: Some(-1.2),
686 };
687 let vector_point2: VectorPoint<MValue> =
688 VectorPoint { x: 1.0, y: 2.0, z: Some(3.0), m: None, t: None };
689 assert_eq!(vector_point1.partial_cmp(&vector_point2), Some(Ordering::Equal));
690 assert!(vector_point1 == vector_point2);
692 }
693}