geo/algorithm/monotone/
segment.rs1use std::cell::{Ref, RefCell};
2use std::{cmp::Ordering, fmt::Debug, rc::Rc};
3
4use crate::sweep::{Event, EventType, LineOrPoint, SweepPoint};
5use crate::GeoNum;
6
7#[derive(Debug, Clone, Copy)]
11pub(crate) struct Segment<T: GeoNum, P> {
12 line: LineOrPoint<T>,
13 payload: P,
14}
15
16impl<T: GeoNum, P> Segment<T, P> {}
17
18impl<T: GeoNum, P> PartialOrd for Segment<T, P> {
19 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
20 self.line.partial_cmp(&other.line)
21 }
22}
23
24impl<T: GeoNum, P> PartialEq for Segment<T, P> {
25 fn eq(&self, other: &Self) -> bool {
26 self.partial_cmp(other) == Some(Ordering::Equal)
27 }
28}
29
30impl<T: GeoNum> From<LineOrPoint<T>> for Segment<T, ()> {
31 fn from(line: LineOrPoint<T>) -> Self {
32 Segment { line, payload: () }
33 }
34}
35
36impl<T: GeoNum, P> From<(LineOrPoint<T>, P)> for Segment<T, P> {
37 fn from((line, payload): (LineOrPoint<T>, P)) -> Self {
38 Segment { line, payload }
39 }
40}
41
42#[derive(Debug)]
43pub(crate) struct RcSegment<T: GeoNum, P>(Rc<RefCell<Segment<T, P>>>);
44
45impl<T: GeoNum, P> Clone for RcSegment<T, P> {
46 fn clone(&self) -> Self {
47 Self(self.0.clone())
48 }
49}
50
51impl<T: GeoNum, P: Clone + Debug> RcSegment<T, P> {
52 pub(crate) fn split_at(&self, pt: SweepPoint<T>) -> Self {
53 debug!("Splitting segment {:?} at {:?}", self, pt);
54 let mut borrow = RefCell::borrow_mut(&self.0);
55 let right = borrow.line.right();
56 borrow.line = LineOrPoint::from((borrow.line.left(), pt));
57
58 let new_seg = Segment::from((LineOrPoint::from((pt, right)), borrow.payload.clone()));
59 Self(Rc::new(new_seg.into()))
60 }
61}
62
63impl<T: GeoNum, P> RcSegment<T, P> {
64 pub(crate) fn payload(&self) -> Ref<P> {
65 let borrow = RefCell::borrow(&self.0);
66 Ref::map(borrow, |s| &s.payload)
67 }
68
69 pub(crate) fn line(&self) -> LineOrPoint<T> {
70 RefCell::borrow(&self.0).line
71 }
72
73 #[inline]
74 pub fn events(&self) -> [Event<T, RcSegment<T, P>>; 2] {
75 let geom = RefCell::borrow(&self.0).line;
76 let left = geom.left();
77 let right = geom.right();
78 [
79 Event {
80 point: left,
81 ty: if geom.is_line() {
82 EventType::LineLeft
83 } else {
84 EventType::PointLeft
85 },
86 payload: self.clone(),
87 },
88 Event {
89 point: right,
90 ty: if geom.is_line() {
91 EventType::LineRight
92 } else {
93 EventType::PointRight
94 },
95 payload: self.clone(),
96 },
97 ]
98 }
99}
100
101impl<T: GeoNum, P> From<Segment<T, P>> for RcSegment<T, P> {
102 fn from(value: Segment<T, P>) -> Self {
103 RcSegment(Rc::new(value.into()))
104 }
105}
106
107impl<T: GeoNum, P> PartialEq for RcSegment<T, P> {
109 fn eq(&self, other: &Self) -> bool {
110 self.0.eq(&other.0)
111 }
112}
113
114impl<T: GeoNum, P> PartialOrd for RcSegment<T, P> {
115 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
116 self.0.partial_cmp(&other.0)
117 }
118}