diff --git a/examples/2d_plot.rs b/examples/2d_plot.rs index 0ec6e98..56c51fe 100644 --- a/examples/2d_plot.rs +++ b/examples/2d_plot.rs @@ -43,7 +43,6 @@ fn create_random_points(length: usize) -> Vec { } fn main() -> Result<(), Box> { - let args: Vec = env::args().collect(); if args.len() != 2 { eprintln!("Usage: cargo run --example 2d_plot [number_of_points]"); @@ -68,10 +67,7 @@ fn main() -> Result<(), Box> { root.fill(&WHITE)?; let mut chart = ChartBuilder::on(&root) - .caption( - format!("Delaunay for {} points", num_points), - "sans-serif", - ) + .caption(format!("Delaunay for {} points", num_points), "sans-serif") .build_cartesian_2d(-2.0..2.0, -2.0..2.0)?; let num_triangle = res.len(); diff --git a/examples/simple_2d_triangulation.rs b/examples/simple_2d_triangulation.rs index 378345d..c327238 100644 --- a/examples/simple_2d_triangulation.rs +++ b/examples/simple_2d_triangulation.rs @@ -1,11 +1,26 @@ fn main() { - // Start indexing from 1 let square = vec![ - meshing::Point2D { index: 1, x: 0.0, y: 0.0 }, - meshing::Point2D { index: 2, x: 1.0, y: 0.0 }, - meshing::Point2D { index: 3, x: 0.0, y: 1.0 }, - meshing::Point2D { index: 4, x: 1.0, y: 1.0 }, + meshing::Point2D { + index: 1, + x: 0.0, + y: 0.0, + }, + meshing::Point2D { + index: 2, + x: 1.0, + y: 0.0, + }, + meshing::Point2D { + index: 3, + x: 0.0, + y: 1.0, + }, + meshing::Point2D { + index: 4, + x: 1.0, + y: 1.0, + }, ]; let res = meshing::bowyer_watson(square); println!("{:?}", res); diff --git a/src/geometry.rs b/src/geometry.rs new file mode 100644 index 0000000..b1e4d61 --- /dev/null +++ b/src/geometry.rs @@ -0,0 +1,72 @@ +use crate::{Edge, Point2D, Triangle}; + +pub fn create_super_triangle(points: &Vec) -> Triangle { + match points.is_empty() { + true => panic!("The input points vector should not be empty."), + false => {} + } + + let index = 0; + let mut min_x = f64::MAX; + let mut min_y = f64::MAX; + let mut max_x = f64::MIN; + let mut max_y = f64::MIN; + + for point in points { + if point.x < min_x { + min_x = point.x; + } + if point.y < min_y { + min_y = point.y; + } + if point.x > max_x { + max_x = point.x; + } + if point.y > max_y { + max_y = point.y; + } + } + + let margin = 100.0; + + let a = Point2D { + index, + x: min_x - margin, + y: min_y - margin, + }; + let b = Point2D { + index, + x: max_x + margin, + y: min_y - margin, + }; + let c = Point2D { + index, + x: (min_x + max_x) / 2.0, + y: max_y + margin, + }; + + Triangle { a, b, c } +} + +pub fn edge_is_shared_by_triangles(edge: &Edge, triangles: &Vec) -> bool { + for triangle in triangles { + let edges_of_triangle = triangle.edges(); + for edge_of_triangle in edges_of_triangle { + if edge_of_triangle == *edge { + return true; + } + if edge_of_triangle.reverse() == *edge { + return true; + } + } + } + false +} + +pub fn retriangulate(edge: &Edge, point: &Point2D) -> Triangle { + Triangle { + a: edge.start, + b: edge.end, + c: *point, + } +} diff --git a/src/lib.rs b/src/lib.rs index aebd601..10db3f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,10 @@ +use geometry::{create_super_triangle, edge_is_shared_by_triangles, retriangulate}; pub use model::{Edge, Point2D, Triangle}; +use triangle_utils::remove_triangles_with_vertices_from_super_triangle; +mod geometry; mod model; +mod triangle_utils; pub fn bowyer_watson(points: Vec) -> Vec { let mut triangulation: Vec = Vec::new(); @@ -46,111 +50,6 @@ pub fn bowyer_watson(points: Vec) -> Vec { remove_triangles_with_vertices_from_super_triangle(&mut triangulation, &super_triangle) } -fn create_super_triangle(points: &Vec) -> Triangle { - match points.is_empty() { - true => panic!("The input points vector should not be empty."), - false => {} - } - - let index = 0; - let mut min_x = f64::MAX; - let mut min_y = f64::MAX; - let mut max_x = f64::MIN; - let mut max_y = f64::MIN; - - for point in points { - if point.x < min_x { - min_x = point.x; - } - if point.y < min_y { - min_y = point.y; - } - if point.x > max_x { - max_x = point.x; - } - if point.y > max_y { - max_y = point.y; - } - } - - let margin = 100.0; - - let a = Point2D { - index, - x: min_x - margin, - y: min_y - margin, - }; - let b = Point2D { - index, - x: max_x + margin, - y: min_y - margin, - }; - let c = Point2D { - index, - x: (min_x + max_x) / 2.0, - y: max_y + margin, - }; - - Triangle { a, b, c } -} - -fn edge_is_shared_by_triangles(edge: &Edge, triangles: &Vec) -> bool { - for triangle in triangles { - let edges_of_triangle = triangle.edges(); - for edge_of_triangle in edges_of_triangle { - if edge_of_triangle == *edge { - return true; - } - if edge_of_triangle.reverse() == *edge { - return true; - } - } - } - false -} - -fn retriangulate(edge: &Edge, point: &Point2D) -> Triangle { - Triangle { - a: edge.start, - b: edge.end, - c: *point, - } -} - -fn triangle_contains_vertex_from_super_triangle( - triangle: &Triangle, - super_triangle: &Triangle, -) -> bool { - let super_triangle_vertices = super_triangle.vertices(); - let triangle_vertices = triangle.vertices(); - for super_triangle_vertex in super_triangle_vertices { - if super_triangle_vertex == triangle_vertices[0] { - return true; - } - if super_triangle_vertex == triangle_vertices[1] { - return true; - } - if super_triangle_vertex == triangle_vertices[2] { - return true; - } - } - false -} - -fn remove_triangles_with_vertices_from_super_triangle( - triangles: &Vec, - super_triangle: &Triangle, -) -> Vec { - let mut res: Vec = Vec::new(); - - for triangle in triangles { - if !triangle_contains_vertex_from_super_triangle(triangle, super_triangle) { - res.push(*triangle); - } - } - res -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/model/triangle.rs b/src/model/triangle.rs index a7a2931..79b9406 100644 --- a/src/model/triangle.rs +++ b/src/model/triangle.rs @@ -35,7 +35,11 @@ impl Triangle { * (self.b.x - self.c.x)) / d; - Point2D { index: i64::MAX, x: ux, y: uy } + Point2D { + index: i64::MAX, + x: ux, + y: uy, + } } pub fn generate_circumcircle(&self) -> Circle { diff --git a/src/triangle_utils.rs b/src/triangle_utils.rs new file mode 100644 index 0000000..028cf16 --- /dev/null +++ b/src/triangle_utils.rs @@ -0,0 +1,35 @@ +use crate::Triangle; + +pub fn triangle_contains_vertex_from_super_triangle( + triangle: &Triangle, + super_triangle: &Triangle, +) -> bool { + let super_triangle_vertices = super_triangle.vertices(); + let triangle_vertices = triangle.vertices(); + for super_triangle_vertex in super_triangle_vertices { + if super_triangle_vertex == triangle_vertices[0] { + return true; + } + if super_triangle_vertex == triangle_vertices[1] { + return true; + } + if super_triangle_vertex == triangle_vertices[2] { + return true; + } + } + false +} + +pub fn remove_triangles_with_vertices_from_super_triangle( + triangles: &Vec, + super_triangle: &Triangle, +) -> Vec { + let mut res: Vec = Vec::new(); + + for triangle in triangles { + if !triangle_contains_vertex_from_super_triangle(triangle, super_triangle) { + res.push(*triangle); + } + } + res +}