axiolid_arrangement/
query.rs1use axiolid_core::Point2;
9
10use crate::id::{FaceId, HalfEdgeId, VertexId};
11use crate::Arrangement;
12
13impl Arrangement {
14 #[must_use]
19 pub fn face_halfedges(&self, face: FaceId) -> Vec<HalfEdgeId> {
20 let Some(start) = self.faces[face.index()].boundary else {
21 return Vec::new();
22 };
23 let mut out = vec![start];
24 let mut current = self.halfedges[start.index()].next;
25 while current != start && out.len() <= self.halfedges.len() {
28 out.push(current);
29 current = self.halfedges[current.index()].next;
30 }
31 out
32 }
33
34 #[must_use]
36 pub fn face_outline(&self, face: FaceId) -> Vec<Point2> {
37 self.face_halfedges(face)
38 .into_iter()
39 .map(|h| self.vertices[self.halfedges[h.index()].origin.index()].position)
40 .collect()
41 }
42
43 #[must_use]
49 pub fn face_area(&self, face: FaceId) -> f64 {
50 if face == FaceId::OUTER {
51 return 0.0;
52 }
53 let outline = self.face_outline(face);
54 if outline.len() < 3 {
55 return 0.0;
56 }
57 let base = outline[0];
60 let mut twice = 0.0;
61 for window in outline[1..].windows(2) {
62 let a = window[0] - base;
63 let b = window[1] - base;
64 twice += a.x * b.y - a.y * b.x;
65 }
66 twice / 2.0
67 }
68
69 #[must_use]
74 pub fn neighbour_across(&self, edge: HalfEdgeId) -> FaceId {
75 let twin = self.halfedges[edge.index()].twin;
76 self.halfedges[twin.index()].face
77 }
78
79 pub fn bounded_faces(&self) -> impl Iterator<Item = FaceId> + '_ {
85 (1..self.faces.len()).map(FaceId::from_index)
86 }
87
88 #[must_use]
90 pub fn vertex_halfedges(&self, vertex: VertexId) -> Vec<HalfEdgeId> {
91 let Some(start) = self.vertices[vertex.index()].outgoing else {
92 return Vec::new();
93 };
94 let mut out = vec![start];
95 let mut current = self.halfedges[self.halfedges[start.index()].twin.index()].next;
98 while current != start && out.len() <= self.halfedges.len() {
99 out.push(current);
100 current = self.halfedges[self.halfedges[current.index()].twin.index()].next;
101 }
102 out
103 }
104
105 #[must_use]
107 pub fn degree(&self, vertex: VertexId) -> usize {
108 self.vertex_halfedges(vertex).len()
109 }
110
111 #[must_use]
113 pub fn halfedge_origin(&self, edge: HalfEdgeId) -> VertexId {
114 self.halfedges[edge.index()].origin
115 }
116
117 #[must_use]
119 pub fn halfedge_face(&self, edge: HalfEdgeId) -> FaceId {
120 self.halfedges[edge.index()].face
121 }
122}