honeycomb_core/cmap/dim2/
orbits.rs1use std::collections::{BTreeSet, VecDeque};
7
8use crate::cmap::{CMap2, DartIdType, OrbitPolicy, NULL_DART_ID};
9use crate::geometry::CoordsFloat;
10
11pub struct Orbit2<'a, T: CoordsFloat> {
38 map_handle: &'a CMap2<T>,
40 orbit_policy: OrbitPolicy,
42 marked: BTreeSet<DartIdType>,
44 pending: VecDeque<DartIdType>,
46}
47
48impl<'a, T: CoordsFloat> Orbit2<'a, T> {
49 #[must_use = "unused return value"]
64 pub fn new(map_handle: &'a CMap2<T>, orbit_policy: OrbitPolicy, dart: DartIdType) -> Self {
65 let mut marked = BTreeSet::<DartIdType>::new();
66 marked.insert(NULL_DART_ID); marked.insert(dart); let pending = VecDeque::from([dart]);
69 Self {
75 map_handle,
76 orbit_policy,
77 marked,
78 pending,
79 }
80 }
81}
82
83impl<T: CoordsFloat> Iterator for Orbit2<'_, T> {
84 type Item = DartIdType;
85
86 fn next(&mut self) -> Option<Self::Item> {
87 if let Some(d) = self.pending.pop_front() {
88 match self.orbit_policy {
89 OrbitPolicy::Vertex => {
90 let image1 = self.map_handle.beta::<1>(self.map_handle.beta::<2>(d));
92 if self.marked.insert(image1) {
93 self.pending.push_back(image1);
96 }
97 let image2 = self.map_handle.beta::<2>(self.map_handle.beta::<0>(d));
98 if self.marked.insert(image2) {
99 self.pending.push_back(image2);
102 }
103 }
104 OrbitPolicy::VertexLinear => {
105 let image = self.map_handle.beta::<1>(self.map_handle.beta::<2>(d));
107 if self.marked.insert(image) {
108 self.pending.push_back(image);
111 }
112 }
113 OrbitPolicy::Edge => {
114 let image = self.map_handle.beta::<2>(d);
116 if self.marked.insert(image) {
117 self.pending.push_back(image);
120 }
121 }
122 OrbitPolicy::Face => {
123 let image1 = self.map_handle.beta::<1>(d);
125 if self.marked.insert(image1) {
126 self.pending.push_back(image1);
129 }
130 let image2 = self.map_handle.beta::<0>(d);
131 if self.marked.insert(image2) {
132 self.pending.push_back(image2);
135 }
136 }
137 OrbitPolicy::FaceLinear => {
138 let image = self.map_handle.beta::<1>(d);
140 if self.marked.insert(image) {
141 self.pending.push_back(image);
144 }
145 }
146 OrbitPolicy::Custom(beta_slice) => {
147 for beta_id in beta_slice {
148 let image = self.map_handle.beta_rt(*beta_id, d);
149 if self.marked.insert(image) {
150 self.pending.push_back(image);
153 }
154 }
155 }
156 OrbitPolicy::Volume | OrbitPolicy::VolumeLinear => {
157 unimplemented!("3-cells aren't defined for 2-maps")
158 }
159 }
160 Some(d)
161 } else {
162 None
163 }
164 }
165}
166
167#[allow(unused_mut)]
170#[cfg(test)]
171mod tests {
172 use super::*;
173
174 fn simple_map() -> CMap2<f64> {
175 let mut map: CMap2<f64> = CMap2::new(11);
176 map.force_link::<1>(1, 2).unwrap();
178 map.force_link::<1>(2, 3).unwrap();
179 map.force_link::<1>(3, 1).unwrap();
180 map.force_link::<1>(4, 5).unwrap();
182 map.force_link::<1>(5, 6).unwrap();
183 map.force_link::<1>(6, 4).unwrap();
184 map.force_link::<1>(7, 8).unwrap();
186 map.force_link::<1>(8, 9).unwrap();
187 map.force_link::<1>(9, 10).unwrap();
188 map.force_link::<1>(10, 11).unwrap();
189 map.force_link::<1>(11, 7).unwrap();
190
191 map.force_link::<2>(2, 4).unwrap();
193 map.force_link::<2>(6, 7).unwrap();
194
195 assert!(map.force_write_vertex(1, (0.0, 0.0)).is_none());
196 assert!(map.force_write_vertex(2, (1.0, 0.0)).is_none());
197 assert!(map.force_write_vertex(6, (1.0, 1.0)).is_none());
198 assert!(map.force_write_vertex(3, (0.0, 1.0)).is_none());
199 assert!(map.force_write_vertex(9, (1.5, 1.5)).is_none());
200 assert!(map.force_write_vertex(10, (0.5, 2.0)).is_none());
201 assert!(map.force_write_vertex(11, (-0.5, 1.5)).is_none());
202
203 map
204 }
205
206 #[test]
207 fn full_map_from_orbit() {
208 let map = simple_map();
209 let orbit = Orbit2::new(&map, OrbitPolicy::Custom(&[1, 2]), 3);
210 let darts: Vec<DartIdType> = orbit.collect();
211 assert_eq!(darts.len(), 11);
212 assert_eq!(&darts, &[3, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11]);
214 }
215
216 #[test]
217 fn orbit_variants() {
218 let map = simple_map();
219
220 let face: Vec<DartIdType> = Orbit2::new(&map, OrbitPolicy::Face, 7).collect();
222 let face_linear: Vec<DartIdType> = Orbit2::new(&map, OrbitPolicy::FaceLinear, 7).collect();
223 let face_custom: Vec<DartIdType> =
224 Orbit2::new(&map, OrbitPolicy::Custom(&[0, 1]), 7).collect();
225 assert_eq!(&face, &[7, 8, 11, 9, 10]);
226 assert_eq!(&face_linear, &[7, 8, 9, 10, 11]);
227 assert_eq!(&face_custom, &[7, 11, 8, 10, 9]);
228
229 let vertex: Vec<DartIdType> = Orbit2::new(&map, OrbitPolicy::Vertex, 4).collect();
231 let vertex_linear: Vec<DartIdType> =
232 Orbit2::new(&map, OrbitPolicy::VertexLinear, 4).collect();
233 assert_eq!(&vertex, &[4, 3, 7]);
234 assert_eq!(&vertex_linear, &[4, 3]);
235 }
236
237 #[test]
238 fn face_from_orbit() {
239 let map = simple_map();
240 let face_orbit = Orbit2::new(&map, OrbitPolicy::Face, 1);
241 let darts: Vec<DartIdType> = face_orbit.collect();
242 assert_eq!(darts.len(), 3);
243 assert_eq!(&darts, &[1, 2, 3]);
244 let other_face_orbit = Orbit2::new(&map, OrbitPolicy::Custom(&[1]), 5);
245 let other_darts: Vec<DartIdType> = other_face_orbit.collect();
246 assert_eq!(other_darts.len(), 3);
247 assert_eq!(&other_darts, &[5, 6, 4]);
248 }
249
250 #[test]
251 fn edge_from_orbit() {
252 let map = simple_map();
253 let face_orbit = Orbit2::new(&map, OrbitPolicy::Edge, 1);
254 let darts: Vec<DartIdType> = face_orbit.collect();
255 assert_eq!(darts.len(), 1);
256 assert_eq!(&darts, &[1]); let other_face_orbit = Orbit2::new(&map, OrbitPolicy::Custom(&[2]), 4);
258 let other_darts: Vec<DartIdType> = other_face_orbit.collect();
259 assert_eq!(other_darts.len(), 2);
260 assert_eq!(&other_darts, &[4, 2]);
261 }
262
263 #[test]
264 fn vertex_from_orbit() {
265 let map = simple_map();
266 let orbit = Orbit2::new(&map, OrbitPolicy::Vertex, 4);
267 let darts: Vec<DartIdType> = orbit.collect();
268 assert_eq!(darts.len(), 3);
269 assert_eq!(&darts, &[4, 3, 7]);
270 }
271
272 #[test]
273 fn empty_orbit_policy() {
274 let map = simple_map();
275 let darts: Vec<DartIdType> = Orbit2::new(&map, OrbitPolicy::Custom(&[]), 3).collect();
276 assert_eq!(&darts, &[3]);
277 }
278
279 #[test]
280 #[should_panic(expected = "assertion failed: i < 3")]
281 fn invalid_orbit_policy() {
282 let map = simple_map();
283 let orbit = Orbit2::new(&map, OrbitPolicy::Custom(&[6]), 3);
284 let _: Vec<DartIdType> = orbit.collect();
285 }
286}