rgeometry/data/
intersection_set.rs1use crate::data::IndexEdge;
2use crate::data::PointId;
3use crate::utils::SparseIndex;
4use crate::utils::SparseVec;
5
6use rand::Rng;
7use std::ops::{Index, IndexMut};
8
9#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
10#[non_exhaustive]
11pub struct IndexIntersection {
12 pub min: IndexEdge,
13 pub max: IndexEdge,
14}
15
16impl std::fmt::Debug for IndexIntersection {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
18 f.debug_tuple("IndexIntersection")
19 .field(&self.min)
20 .field(&self.max)
21 .finish()
22 }
23}
24
25impl IndexIntersection {
26 pub fn new(a: IndexEdge, b: IndexEdge) -> IndexIntersection {
27 IndexIntersection {
28 min: std::cmp::min(a, b),
29 max: std::cmp::max(a, b),
30 }
31 }
32}
33
34impl From<Isect> for IndexIntersection {
35 fn from(isect: Isect) -> IndexIntersection {
36 IndexIntersection::new(isect.edge0.into(), isect.edge1.into())
37 }
38}
39
40pub struct IndexIntersectionSet {
41 vertices: usize,
42 by_idx: SparseVec<Isect>,
44 by_edge: Vec<Option<SparseIndex>>,
45}
46
47impl IndexIntersectionSet {
48 pub fn new(vertices: usize) -> IndexIntersectionSet {
50 let size = vertices * (vertices - 1);
51 let by_edge = vec![None; size];
52 IndexIntersectionSet {
53 vertices,
54 by_idx: SparseVec::new(),
55 by_edge,
56 }
57 }
58
59 pub fn push(&mut self, isect: IndexIntersection) {
61 let idx = self.by_idx.push(Isect::new(isect));
62
63 for &edge in &[isect.min, isect.max] {
64 if let Some(loc) = self[edge] {
65 assert_ne!(loc, idx);
66 self.by_idx[loc][edge].prev = Some(idx);
67 self.by_idx[idx][edge].next = Some(loc);
68 }
69 self[edge] = Some(idx);
70 }
71 }
72
73 fn remove(&mut self, idx: SparseIndex) {
75 let isect = self.by_idx.remove(idx);
76
77 for &edge in &[isect.edge0, isect.edge1] {
80 match edge.prev {
81 Some(prev) => self.by_idx[prev][IndexEdge::from(edge)].next = edge.next,
82 None => self[IndexEdge::from(edge)] = edge.next,
83 }
84 if let Some(next) = edge.next {
85 self.by_idx[next][IndexEdge::from(edge)].prev = edge.prev;
86 }
87 }
88 }
89
90 pub fn remove_all(&mut self, edge: impl Into<IndexEdge>) {
92 let key = edge.into();
93 while let Some(idx) = self[key] {
94 self.remove(idx)
95 }
96 }
97
98 pub fn random<R>(&mut self, rng: &mut R) -> Option<IndexIntersection>
100 where
101 R: Rng + ?Sized,
102 {
103 let idx = self.by_idx.random(rng)?;
104 let isect = self.by_idx[idx];
105 Some(IndexIntersection::new(
106 IndexEdge::new(isect.edge0.vertex0, isect.edge0.vertex1),
107 IndexEdge::new(isect.edge1.vertex0, isect.edge1.vertex1),
108 ))
109 }
110
111 pub fn iter(&self) -> impl Iterator<Item = IndexIntersection> + '_ {
112 self.by_idx.iter().map(|&isect| isect.into())
113 }
114}
115
116impl IndexMut<IndexEdge> for IndexIntersectionSet {
117 fn index_mut(&mut self, index: IndexEdge) -> &mut Option<SparseIndex> {
118 self
119 .by_edge
120 .index_mut(index.max.usize() + self.vertices * index.min.usize())
121 }
122}
123
124impl Index<IndexEdge> for IndexIntersectionSet {
125 type Output = Option<SparseIndex>;
126 fn index(&self, index: IndexEdge) -> &Option<SparseIndex> {
127 self
128 .by_edge
129 .index(index.max.usize() + self.vertices * index.min.usize())
130 }
131}
132
133impl PartialEq<IndexEdge> for IsectEdge {
134 fn eq(&self, other: &IndexEdge) -> bool {
135 self.vertex0 == other.min && self.vertex1 == other.max
136 }
137}
138
139impl PartialEq for IsectEdge {
140 fn eq(&self, other: &IsectEdge) -> bool {
141 self.vertex0 == other.vertex0 && self.vertex1 == other.vertex1
142 }
143}
144
145#[derive(Clone, Copy, Debug)]
149struct Isect {
151 edge0: IsectEdge,
152 edge1: IsectEdge,
153}
154
155impl Default for Isect {
156 fn default() -> Isect {
157 Isect {
158 edge0: IsectEdge {
159 vertex0: PointId::INVALID,
160 vertex1: PointId::INVALID,
161 next: None,
162 prev: None,
163 },
164 edge1: IsectEdge {
165 vertex0: PointId::INVALID,
166 vertex1: PointId::INVALID,
167 next: None,
168 prev: None,
169 },
170 }
171 }
172}
173
174impl Isect {
175 fn new(intersection: IndexIntersection) -> Isect {
176 Isect {
177 edge0: IsectEdge::new(intersection.min),
178 edge1: IsectEdge::new(intersection.max),
179 }
180 }
181}
182
183impl IndexMut<IsectEdge> for Isect {
184 fn index_mut(&mut self, index: IsectEdge) -> &mut IsectEdge {
185 if self.edge0 == index {
186 &mut self.edge0
187 } else {
188 assert_eq!(self.edge1, index);
189 &mut self.edge1
190 }
191 }
192}
193
194impl Index<IsectEdge> for Isect {
195 type Output = IsectEdge;
196 fn index(&self, index: IsectEdge) -> &IsectEdge {
197 if self.edge0 == index {
198 &self.edge0
199 } else {
200 assert_eq!(self.edge1, index);
201 &self.edge1
202 }
203 }
204}
205
206impl IndexMut<IndexEdge> for Isect {
207 fn index_mut(&mut self, index: IndexEdge) -> &mut IsectEdge {
208 if self.edge0 == index {
209 &mut self.edge0
210 } else {
211 assert_eq!(self.edge1, index);
212 &mut self.edge1
213 }
214 }
215}
216
217impl Index<IndexEdge> for Isect {
218 type Output = IsectEdge;
219 fn index(&self, index: IndexEdge) -> &IsectEdge {
220 if self.edge0 == index {
221 &self.edge0
222 } else {
223 assert_eq!(self.edge1, index);
224 &self.edge1
225 }
226 }
227}
228
229#[derive(Clone, Copy, Debug)]
230struct IsectEdge {
232 vertex0: PointId,
233 vertex1: PointId,
234 next: Option<SparseIndex>,
235 prev: Option<SparseIndex>,
236}
237
238impl IsectEdge {
239 fn new(edge: IndexEdge) -> IsectEdge {
241 IsectEdge {
242 vertex0: edge.min,
243 vertex1: edge.max,
244 next: None,
245 prev: None,
246 }
247 }
248}
249
250impl From<IsectEdge> for IndexEdge {
251 fn from(e: IsectEdge) -> IndexEdge {
252 IndexEdge::new(e.vertex0, e.vertex1)
253 }
254}