diff --git a/src/cdt.rs b/src/cdt.rs index 3eda667..be91f2f 100644 --- a/src/cdt.rs +++ b/src/cdt.rs @@ -236,6 +236,29 @@ where } } + /// Removes a vertex from the triangulation. + /// + /// This operation runs in O(n²), where n is the degree of the + /// removed vertex. + /// + /// # Handle invalidation + /// This method will invalidate all vertex, edge and face handles. + fn remove(&mut self, vertex: FixedVertexHandle) -> V { + let removed_constraints = self + .dcel + .vertex(vertex) + .out_edges() + .filter(|edge| edge.is_constraint_edge()) + .map(|e| e.as_undirected().fix()) + .collect::>(); + + for e in removed_constraints { + self.remove_constraint_edge(e); + } + + self.remove_and_notify(vertex) + } + fn into_parts( self, ) -> ( @@ -393,23 +416,15 @@ where Ok(result) } - /// Removes a vertex from the triangulation. - /// - /// This operation runs in O(n²), where n is the degree of the - /// removed vertex. - /// /// # Handle invalidation - /// This method will invalidate all vertex, edge and face handles. + /// See [Triangulation::remove]. This function was accidentally implemented separately for CDTs and will be removed in future releases. + /// Use the method from the trait instead. + #[deprecated( + since = "2.14.0", + note = "Please use `remove` from trait `Triangulation` instead." + )] pub fn remove(&mut self, vertex: FixedVertexHandle) -> V { - let num_removed_constraints = self - .dcel - .vertex(vertex) - .out_edges() - .map(|edge| edge.is_constraint_edge()) - .filter(|b| *b) - .count(); - self.num_constraints -= num_removed_constraints; - self.remove_and_notify(vertex) + ::remove(self, vertex) } /// Returns the number of constraint edges. @@ -2051,6 +2066,30 @@ mod test { Ok(()) } + #[test] + fn test_remove_vertex_respects_constraints() -> Result<(), InsertionError> { + let mut triangulation = + ConstrainedDelaunayTriangulation::>::bulk_load_cdt_stable( + vec![ + Point2::new(-1.0, 0.0), + Point2::new(0.0, 0.0), + Point2::new(0.0, 1.0), + Point2::new(1.0, 1.0), + ], + vec![[0, 1], [1, 2], [2, 3]], + )?; + + let mut copy = triangulation.clone(); + + triangulation.remove(FixedVertexHandle::from_index(1)); + triangulation.cdt_sanity_check(); + + copy.locate_and_remove(Point2::new(0.0, 0.0)); + copy.cdt_sanity_check(); + + Ok(()) + } + #[test] fn test_remove_constraint_edge() -> Result<(), InsertionError> { let mut cdt = get_cdt_for_try_add_constraint()?; diff --git a/src/delaunay_core/bulk_load.rs b/src/delaunay_core/bulk_load.rs index 73bc145..9d51f0e 100644 --- a/src/delaunay_core/bulk_load.rs +++ b/src/delaunay_core/bulk_load.rs @@ -788,7 +788,7 @@ impl Hull { const INVALID: usize = usize::MAX; self.buckets - .extend(core::iter::repeat(INVALID).take(target_size)); + .extend(core::iter::repeat_n(INVALID, target_size)); let (first_index, current_node) = self .data diff --git a/src/delaunay_core/hint_generator.rs b/src/delaunay_core/hint_generator.rs index b0340cd..e710b02 100644 --- a/src/delaunay_core/hint_generator.rs +++ b/src/delaunay_core/hint_generator.rs @@ -26,7 +26,7 @@ use alloc::vec::Vec; /// fulfill most needs: /// - A heuristic that uses the last inserted vertex as hint ([LastUsedVertexHintGenerator]) /// - A hint generator based on a hierarchy of triangulations that improves walk time to `O(log(n))` -/// ([HierarchyHintGenerator]) +/// ([HierarchyHintGenerator]) pub trait HintGenerator: Default { /// Returns a vertex handle that should be close to a given position. /// diff --git a/src/lib.rs b/src/lib.rs index 472a081..ff0fc65 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -84,7 +84,7 @@ mod test_utilities; /// Reference handles come in one of four variants: /// * [FaceHandle](handles::FaceHandle)s refer to a single face (triangle) of the triangulation. /// They are used get the triangle's adjacent vertices and edges. They also may refer to -/// the single outer face. +/// the single outer face. /// * [VertexHandle](handles::VertexHandle)s refer to a single vertex of the triangulation. They /// allow to retrieve the vertex position and its outgoing edges. /// * [DirectedEdgeHandle](handles::DirectedEdgeHandle)s refer to a single directed edge. They diff --git a/src/triangulation.rs b/src/triangulation.rs index 81b93e3..384e4d9 100644 --- a/src/triangulation.rs +++ b/src/triangulation.rs @@ -496,7 +496,7 @@ pub trait Triangulation: Default { point: Point2<::Scalar>, ) -> Option { match self.locate_with_hint_option_core(point, None) { - PositionInTriangulation::OnVertex(handle) => Some(self.remove_and_notify(handle)), + PositionInTriangulation::OnVertex(handle) => Some(self.remove(handle)), _ => None, } }