diff --git a/src/main.rs b/src/main.rs index e4b4fff..b28cb6a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,14 +27,14 @@ use macroquad::prelude::Color; use macroquad::input::MouseButton; use std::sync::Arc; -const BG: Color = Color::new(0.16863, 0.23922, 0.21176, 1.0); -const FG: Color = Color::new(0.91569, 0.71765, 0.00000, 1.0); +const BG: Color = Color::new(0.16863, 0.23922, 0.21176, 1.0); +const FG: Color = Color::new(0.91569, 0.71765, 0.00000, 1.0); const DIM_FG: Color = Color::new(0.29412, 0.27451, 0.13333, 1.0); const HIL_FG: Color = Color::new(0.25806, 0.61290, 1.09032, 1.0); -const SPEED: f64 = 0.1; +const SPEED: f64 = 0.1; const BOING_RADIUS: f64 = 30.0; -const HILITE: bool = false; +const HILITE: bool = false; #[macroquad::main("BasicShapes")] async fn main() { @@ -343,72 +343,72 @@ impl Triangle { c.distance(point) < r } - pub fn common_edge(&self, other: &Triangle) -> Result<&Edge, String> { - let common_edge = self.edges.iter() - .filter(|e| other.edges.contains(e)) - .collect::>(); + pub fn common_edge(&self, other: &Triangle) -> Result<&Edge, String> { + let common_edge = self.edges.iter() + .filter(|e| other.edges.contains(e)) + .collect::>(); - if common_edge.len() > 1 { - Err(format!( - "Tried to call common_edge on two triangles which share more \ - than one common edge?: {:?} and {:?}.", - self, other - )) - } else if let Some(common_edge) = common_edge.first() { - Ok(common_edge) - } else { - Err(format!( - "Tried to call common_edge on two triangles which don't \ - share a common edges: {:?} and {:?}.", - self, other - )) - } - } + if common_edge.len() > 1 { + Err(format!( + "Tried to call common_edge on two triangles which share more \ + than one common edge?: {:?} and {:?}.", + self, other + )) + } else if let Some(common_edge) = common_edge.first() { + Ok(common_edge) + } else { + Err(format!( + "Tried to call common_edge on two triangles which don't \ + share a common edges: {:?} and {:?}.", + self, other + )) + } + } - pub fn point_not_on(&self, edge: &Edge) -> Result<&NodeRef, String> { - self.nodes.iter() - .filter(|n| - !Arc::ptr_eq(n, &edge.0) && - !Arc::ptr_eq(n, &edge.1) - ) - .next() - .ok_or_else(||format!( - ".point_not_on called on {:?} with edge {:?}, but no points were found \ - not on this edge", - self, edge - )) - } + pub fn point_not_on(&self, edge: &Edge) -> Result<&NodeRef, String> { + self.nodes.iter() + .filter(|n| + !Arc::ptr_eq(n, &edge.0) && + !Arc::ptr_eq(n, &edge.1) + ) + .next() + .ok_or_else(||format!( + ".point_not_on called on {:?} with edge {:?}, but no points were found \ + not on this edge", + self, edge + )) + } - pub fn invalidated_by_neighbor(&self, other: &Triangle) -> Result { + pub fn invalidated_by_neighbor(&self, other: &Triangle) -> Result { - let common_edge = self.common_edge(other)?; + let common_edge = self.common_edge(other)?; - let self_point = self.point_not_on(common_edge)?; - let othr_point = other.point_not_on(common_edge)?; + let self_point = self.point_not_on(common_edge)?; + let othr_point = other.point_not_on(common_edge)?; - let common_distance = common_edge.0.get().distance(*common_edge.1.get()); - let self_sidea = common_edge.0.get().distance(*self_point.get()); - let self_sideb = common_edge.1.get().distance(*self_point.get()); - let othr_sidea = common_edge.0.get().distance(*othr_point.get()); - let othr_sideb = common_edge.1.get().distance(*othr_point.get()); + let common_distance = common_edge.0.get().distance(*common_edge.1.get()); + let self_sidea = common_edge.0.get().distance(*self_point.get()); + let self_sideb = common_edge.1.get().distance(*self_point.get()); + let othr_sidea = common_edge.0.get().distance(*othr_point.get()); + let othr_sideb = common_edge.1.get().distance(*othr_point.get()); - let self_angle = f64::acos( - ( - self_sidea.powf(2.0) - + self_sideb.powf(2.0) - - common_distance.powf(2.0) - ) / (2.0 * self_sidea * self_sideb) - ); - let othr_angle = f64::acos( - ( - othr_sidea.powf(2.0) - + othr_sideb.powf(2.0) - - common_distance.powf(2.0) - ) / (2.0 * othr_sidea * othr_sideb) - ); + let self_angle = f64::acos( + ( + self_sidea.powf(2.0) + + self_sideb.powf(2.0) + - common_distance.powf(2.0) + ) / (2.0 * self_sidea * self_sideb) + ); + let othr_angle = f64::acos( + ( + othr_sidea.powf(2.0) + + othr_sideb.powf(2.0) + - common_distance.powf(2.0) + ) / (2.0 * othr_sidea * othr_sideb) + ); - return Ok(self_angle + othr_angle > PI) - } + return Ok(self_angle + othr_angle > PI) + } } impl PartialEq for Triangle { @@ -577,10 +577,10 @@ impl DelaunayDemo { self.move_point(node); } } - if let Err(msg) = self.re_delaunize() { - eprintln!("POISONED: {}", msg); - self.poisoned = true; - } + if let Err(msg) = self.re_delaunize() { + eprintln!("POISONED: {}", msg); + self.poisoned = true; + } } fn click(&mut self, pos: Vec2) { @@ -773,139 +773,139 @@ impl DelaunayDemo { new_pos.1.x = -new_pos.1.x; } - node.set(node_inner); + node.set(new_pos); } - fn get_neighbors(&self, triangle: &Triangle) -> Result, String> { - triangle.edges.iter() - .filter_map(|e| - match self.adjacency.get(e) { - Some((Occupant(a), Friend(b))) => { - if a != triangle && b == triangle { - Some(Ok(a)) - } else if a == triangle && b != triangle { - Some(Ok(b)) - } else if a == triangle && b == triangle { - Some(Err(format!( - "{:?} has {:?} in adjacency graph which lists itself as \ - its own neighbor", - triangle, e - ))) - } else { - Some(Err(format!( - "{:?} has {:?}, but the adjacency graph reports that the \ - triangles next to this edge are {:?} and {:?}", - triangle, e, a, b - ))) - } - }, - Some((Border, Friend(tri))) => { - if tri == triangle { - None - } else { - Some(Err(format!( - "{:?} has {:?}, but the adjacency graph reports that \ - this edge is an edge between the graph hull and {:?}", - triangle, e, tri - ))) - } - }, - Some((Occupant(tri), Hole)) => { - if tri == triangle { - None - } else { - Some(Err(format!( - "{:?} has {:?}, but the adjacency graph reports that \ - this edge is an edge between a polygonal hole and {:?}", - triangle, e, tri - ))) - } - }, - Some((Border, Hole)) => { - Some(Err(format!( - "{:?} has {:?}, but the adjacency graph lists this edge as \ - being between the graph hull and a polygonal hole (aka, it \ - has no neighbors", - triangle, e - ))) - }, - None => { - Some(Err(format!( - "get_neighbors called on {:?}, but its edge {:?} is not \ - present in the adjacency graph.", - triangle, e - ))) - }, - } - ) - .collect() - } + fn get_neighbors(&self, triangle: &Triangle) -> Result, String> { + triangle.edges.iter() + .filter_map(|e| + match self.adjacency.get(e) { + Some((Occupant(a), Friend(b))) => { + if a != triangle && b == triangle { + Some(Ok(a)) + } else if a == triangle && b != triangle { + Some(Ok(b)) + } else if a == triangle && b == triangle { + Some(Err(format!( + "{:?} has {:?} in adjacency graph which lists itself as \ + its own neighbor", + triangle, e + ))) + } else { + Some(Err(format!( + "{:?} has {:?}, but the adjacency graph reports that the \ + triangles next to this edge are {:?} and {:?}", + triangle, e, a, b + ))) + } + }, + Some((Border, Friend(tri))) => { + if tri == triangle { + None + } else { + Some(Err(format!( + "{:?} has {:?}, but the adjacency graph reports that \ + this edge is an edge between the graph hull and {:?}", + triangle, e, tri + ))) + } + }, + Some((Occupant(tri), Hole)) => { + if tri == triangle { + None + } else { + Some(Err(format!( + "{:?} has {:?}, but the adjacency graph reports that \ + this edge is an edge between a polygonal hole and {:?}", + triangle, e, tri + ))) + } + }, + Some((Border, Hole)) => { + Some(Err(format!( + "{:?} has {:?}, but the adjacency graph lists this edge as \ + being between the graph hull and a polygonal hole (aka, it \ + has no neighbors", + triangle, e + ))) + }, + None => { + Some(Err(format!( + "get_neighbors called on {:?}, but its edge {:?} is not \ + present in the adjacency graph.", + triangle, e + ))) + }, + } + ) + .collect() + } - fn flip_triangles( - &mut self, - tri1: &Triangle, - tri2: &Triangle - ) -> Result<(Triangle, &Triangle), String> { - let mut indices = self.triangles.iter() - .enumerate() - .filter(|(_, t)| t == &tri1 || t == &tri2) - .map(|(i, _)| i); - let err = || format!( - "flip_triangles called on {:?} and {:?}, but not both of these were found in \ - the list of triangles", - tri1, tri2 - ); + fn flip_triangles( + &mut self, + tri1: &Triangle, + tri2: &Triangle + ) -> Result<(Triangle, &Triangle), String> { + let mut indices = self.triangles.iter() + .enumerate() + .filter(|(_, t)| t == &tri1 || t == &tri2) + .map(|(i, _)| i); + let err = || format!( + "flip_triangles called on {:?} and {:?}, but not both of these were found in \ + the list of triangles", + tri1, tri2 + ); - let mut indices = [ - indices.next().ok_or_else(err)?, - indices.next().ok_or_else(err)?, - ]; - indices.sort_unstable(); + let mut indices = [ + indices.next().ok_or_else(err)?, + indices.next().ok_or_else(err)?, + ]; + indices.sort_unstable(); - let tri1 = self.remove_triangle(indices[1])?; - let tri2 = self.remove_triangle(indices[0])?; + let tri1 = self.remove_triangle(indices[1])?; + let tri2 = self.remove_triangle(indices[0])?; - let common_edge = tri1.common_edge(&tri2)?; + let common_edge = tri1.common_edge(&tri2)?; - let tri1_point = tri1.point_not_on(common_edge)?; - let tri2_point = tri2.point_not_on(common_edge)?; + let tri1_point = tri1.point_not_on(common_edge)?; + let tri2_point = tri2.point_not_on(common_edge)?; - Ok(( - self.create_triangle([ - Edge(tri1_point.clone(), common_edge.0.clone()), - Edge(tri2_point.clone(), common_edge.0.clone()), - Edge(tri1_point.clone(), tri2_point.clone()), - ])?.clone(), - self.create_triangle([ - Edge(tri1_point.clone(), common_edge.1.clone()), - Edge(tri2_point.clone(), common_edge.1.clone()), - Edge(tri1_point.clone(), tri2_point.clone()), - ])?, - )) - } + Ok(( + self.create_triangle([ + Edge(tri1_point.clone(), common_edge.0.clone()), + Edge(tri2_point.clone(), common_edge.0.clone()), + Edge(tri1_point.clone(), tri2_point.clone()), + ])?.clone(), + self.create_triangle([ + Edge(tri1_point.clone(), common_edge.1.clone()), + Edge(tri2_point.clone(), common_edge.1.clone()), + Edge(tri1_point.clone(), tri2_point.clone()), + ])?, + )) + } - fn re_delaunize(&mut self) -> Result<(), String> { + fn re_delaunize(&mut self) -> Result<(), String> { let mut i = 0; - while i < self.triangles.len() { + while i < self.triangles.len() { let triangle = &self.triangles[i]; - let neighbors: Vec<_> = self.get_neighbors(triangle)? - .into_iter() - .cloned() - .collect(); + let neighbors: Vec<_> = self.get_neighbors(triangle)? + .into_iter() + .cloned() + .collect(); let mut flipped = false; - for neighbor in neighbors { - if triangle.invalidated_by_neighbor(&neighbor)? { + for neighbor in neighbors { + if triangle.invalidated_by_neighbor(&neighbor)? { let triangle = triangle.clone(); - self.flip_triangles(&triangle, &neighbor)?; + self.flip_triangles(&triangle, &neighbor)?; i = 0; flipped = true; break; - } - } + } + } if !flipped { i = i + 1; } - } - Ok(()) - } + } + Ok(()) + } }