mesh_graph/plane_slice/
polygon.rs1use std::collections::VecDeque;
2
3use glam::{Mat4, Vec2, Vec3, Vec4Swizzles};
4use itertools::Itertools;
5
6#[derive(Debug, Clone, Copy)]
7pub enum PolygonTerminal {
8 Start,
9 End,
10}
11
12#[derive(Debug, Clone, PartialEq)]
13pub struct Polygon2 {
14 pub vertices: VecDeque<Vec2>,
15}
16
17#[derive(Debug, Clone, PartialEq)]
18pub struct Polygon3 {
19 pub vertices: VecDeque<Vec3>,
20}
21
22impl Polygon2 {
23 pub fn terminal(&self, terminal: PolygonTerminal) -> Vec2 {
24 match terminal {
25 PolygonTerminal::Start => self.vertices[0],
26 PolygonTerminal::End => self.vertices[self.vertices.len() - 1],
27 }
28 }
29
30 pub fn extend_by_line(&mut self, terminal: PolygonTerminal, other_line_end: Vec2) {
31 match terminal {
32 PolygonTerminal::Start => self.vertices.push_front(other_line_end),
33 PolygonTerminal::End => self.vertices.push_back(other_line_end),
34 }
35 }
36
37 pub fn merge_polygon(
39 &mut self,
40 my_terminal: PolygonTerminal,
41 mut other: Polygon2,
42 other_terminal: PolygonTerminal,
43 ) {
44 let mut vertices = VecDeque::new();
45
46 match my_terminal {
47 PolygonTerminal::Start => {
48 match other_terminal {
49 PolygonTerminal::Start => vertices.extend(other.vertices.into_iter().rev()),
50 PolygonTerminal::End => vertices.append(&mut other.vertices),
51 }
52
53 vertices.append(&mut self.vertices);
54 }
55 PolygonTerminal::End => {
56 vertices.append(&mut self.vertices);
57
58 match other_terminal {
59 PolygonTerminal::Start => vertices.append(&mut other.vertices),
60 PolygonTerminal::End => vertices.extend(other.vertices.into_iter().rev()),
61 }
62 }
63 }
64
65 self.vertices = vertices;
66 }
67
68 pub fn is_closed(&self) -> bool {
69 if let (Some(front), Some(back)) = (self.vertices.front(), self.vertices.back()) {
70 front.distance_squared(*back) < 1e-6
71 } else {
72 false
73 }
74 }
75
76 pub fn close(&mut self) {
77 if !self.is_closed() {
78 self.vertices.push_back(self.vertices[0]);
79 }
80 }
81
82 pub fn length(&self) -> f32 {
83 self.vertices
84 .iter()
85 .tuple_windows()
86 .map(|(a, b)| a.distance(*b))
87 .sum()
88 }
89
90 #[cfg(feature = "rerun")]
91 pub fn log_rerun(&self, name: &str) {
92 use crate::utils::vec2_array;
93
94 crate::RR
95 .log(
96 name,
97 &rerun::LineStrips3D::new([self.vertices.iter().copied().map(vec2_array)]),
98 )
99 .unwrap();
100 }
101}
102
103impl Polygon3 {
104 pub fn from_polygon2_with_transform(polygon: Polygon2, transform: Mat4) -> Self {
105 let vertices = polygon
106 .vertices
107 .into_iter()
108 .map(|v| (transform * v.extend(0.0).extend(1.0)).xyz())
109 .collect();
110
111 Self { vertices }
112 }
113
114 pub fn length(&self) -> f32 {
115 self.vertices
116 .iter()
117 .tuple_windows()
118 .map(|(a, b)| a.distance(*b))
119 .sum()
120 }
121
122 #[cfg(feature = "rerun")]
123 pub fn log_rerun<'a>(
124 rr: &rerun::RecordingStream,
125 name: &str,
126 polygons: impl IntoIterator<Item = &'a Self>,
127 ) {
128 use crate::utils::vec3_array;
129
130 rr.log(
131 name,
132 &rerun::LineStrips3D::new(
133 polygons
134 .into_iter()
135 .map(|p| p.vertices.iter().copied().map(vec3_array)),
136 ),
137 )
138 .unwrap();
139 }
140}