geo/algorithm/sweep/
point.rs1use std::{cmp::Ordering, ops::Deref};
2
3use geo_types::Coord;
4
5use crate::GeoNum;
6
7#[derive(PartialEq, Clone, Copy)]
17pub struct SweepPoint<T: GeoNum>(Coord<T>);
18
19impl<T: GeoNum> std::fmt::Debug for SweepPoint<T> {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 f.debug_tuple("SPt")
22 .field(&self.0.x)
23 .field(&self.0.y)
24 .finish()
25 }
26}
27
28impl<T: GeoNum> PartialOrd for SweepPoint<T> {
31 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
32 match self.0.x.partial_cmp(&other.0.x) {
33 Some(Ordering::Equal) => self.0.y.partial_cmp(&other.0.y),
34 o => o,
35 }
36 }
37}
38
39impl<T: GeoNum> Ord for SweepPoint<T> {
41 fn cmp(&self, other: &Self) -> Ordering {
42 self.partial_cmp(other).unwrap()
43 }
44}
45
46impl<T: GeoNum> Eq for SweepPoint<T> {}
48
49impl<T: GeoNum, X: Into<Coord<T>>> From<X> for SweepPoint<T> {
51 fn from(pt: X) -> Self {
52 SweepPoint(pt.into())
53 }
54}
55
56impl<T: GeoNum> Deref for SweepPoint<T> {
57 type Target = Coord<T>;
58
59 fn deref(&self) -> &Self::Target {
60 &self.0
61 }
62}
63
64#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn test_sweep_point_ordering() {
77 let p1 = SweepPoint::from(Coord { x: 0., y: 0. });
78 let p2 = SweepPoint::from(Coord { x: 1., y: 0. });
79 let p3 = SweepPoint::from(Coord { x: 1., y: 1. });
80 let p4 = SweepPoint::from(Coord { x: 1., y: 1. });
81
82 assert!(p1 < p2);
83 assert!(p1 < p3);
84 assert!(p2 < p3);
85 assert!(p3 <= p4);
86 }
87}