spade/
triangulation.rs

1use num_traits::Float;
2
3use crate::delaunay_core::iterators::HullIterator;
4use crate::delaunay_core::InnerOuterMarker;
5use crate::flood_fill_iterator::CircleMetric;
6use crate::flood_fill_iterator::EdgesInShapeIterator;
7use crate::flood_fill_iterator::FloodFillIterator;
8use crate::flood_fill_iterator::RectangleMetric;
9use crate::flood_fill_iterator::VerticesInShapeIterator;
10use crate::iterators::*;
11use crate::Barycentric;
12use crate::DelaunayTriangulation;
13use crate::HintGenerator;
14use crate::{delaunay_core::Dcel, handles::*};
15use crate::{HasPosition, InsertionError, Point2, TriangulationExt};
16
17use alloc::vec::Vec;
18
19/// Describes a position in a triangulation.
20///
21/// The position is set in relation to the triangulation's vertices, edges and faces.
22/// This type is usually the result of calling [Triangulation::locate]
23#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
24pub enum PositionInTriangulation {
25    /// A position lies exactly on an existing vertex. The verticis handle is given.
26    OnVertex(FixedVertexHandle),
27
28    /// A position lies exactly on an edge. The edge's handle is given.
29    OnEdge(FixedDirectedEdgeHandle),
30
31    /// A position lies in the interior of a face. The face's handle is given.
32    OnFace(FixedFaceHandle<InnerTag>),
33
34    /// A position lies outside the convex hull. The given edge handle refers to an edge
35    /// of the convex hull which has both the point and the outer face on its left side.
36    ///
37    /// *Note*: The given edge is *not* necessarily the *closest* edge to a position.
38    OutsideOfConvexHull(FixedDirectedEdgeHandle),
39
40    /// The triangulation contains either no vertices or exactly one vertex which has a
41    /// different position than the query point.
42    NoTriangulation,
43}
44
45/// Defines common operations on triangulations.
46///
47/// These operations are both available for
48/// [ConstrainedDelaunayTriangulations](crate::ConstrainedDelaunayTriangulation) and
49/// regular [DelaunayTriangulations](crate::DelaunayTriangulation).
50pub trait Triangulation: Default {
51    /// The triangulation's vertex type.
52    type Vertex: HasPosition;
53    /// The triangulation's edge type. Any new edge is created by using the `Default` trait.
54    type DirectedEdge: Default;
55    /// The triangulation's undirected edge type. Any new edge is created by using the `Default` trait.
56    type UndirectedEdge: Default;
57    /// The triangulation's face type. Any new face is created by using the `Default` trait.
58    type Face: Default;
59
60    /// The hint generator used by the triangulation. See [HintGenerator] for more information.
61    type HintGenerator: HintGenerator<<Self::Vertex as HasPosition>::Scalar>;
62
63    #[doc(hidden)]
64    fn s(&self) -> &Dcel<Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face>;
65
66    #[doc(hidden)]
67    fn s_mut(
68        &mut self,
69    ) -> &mut Dcel<Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face>;
70
71    #[doc(hidden)]
72    fn is_defined_legal(&self, _: FixedUndirectedEdgeHandle) -> bool {
73        false
74    }
75
76    #[doc(hidden)]
77    fn handle_legal_edge_split(&mut self, _: [FixedDirectedEdgeHandle; 2]) {}
78
79    #[doc(hidden)]
80    fn hint_generator(&self) -> &Self::HintGenerator;
81
82    #[doc(hidden)]
83    fn hint_generator_mut(&mut self) -> &mut Self::HintGenerator;
84
85    #[doc(hidden)]
86    fn from_parts(
87        dcel: Dcel<Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face>,
88        hint_generator: Self::HintGenerator,
89        num_constraints: usize,
90    ) -> Self;
91
92    #[doc(hidden)]
93    #[allow(clippy::type_complexity)]
94    fn into_parts(
95        self,
96    ) -> (
97        Dcel<Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face>,
98        Self::HintGenerator,
99        usize,
100    );
101
102    /// Creates a new triangulation.
103    ///
104    /// A newly created triangulation contains no vertices, no edges and the single
105    /// outer face.
106    ///
107    /// # Example
108    /// ```
109    /// use spade::{DelaunayTriangulation, Point2, Triangulation};
110    ///
111    /// let mut triangulation: DelaunayTriangulation<Point2<f64>> = DelaunayTriangulation::new();
112    /// // An empty triangulation has no vertices and one face
113    /// assert_eq!(triangulation.num_vertices(), 0);
114    /// assert_eq!(triangulation.num_all_faces(), 1);
115    /// assert_eq!(triangulation.num_inner_faces(), 0); // This count excludes the outer face
116    /// assert_eq!(triangulation.num_directed_edges(), 0);
117    ///
118    /// triangulation.insert(Point2::new(0.0, 1.0));
119    /// assert_eq!(triangulation.num_vertices(), 1);
120    /// assert_eq!(triangulation.num_inner_faces(), 0);
121    ///
122    /// triangulation.insert(Point2::new(1.0, 1.0));
123    /// // Two vertices define the first edge
124    /// assert_eq!(triangulation.num_undirected_edges(), 1);
125    ///
126    /// triangulation.insert(Point2::new(1.0, 0.0));
127    /// assert_eq!(triangulation.num_vertices(), 3);
128    // // The third point will generate the first inner face!
129    /// assert_eq!(triangulation.num_inner_faces(), 1);
130    /// ```
131    fn new() -> Self {
132        Self::default()
133    }
134
135    /// Creates a new triangulation and pre-allocates some space for vertices, edges and faces
136    fn with_capacity(num_vertices: usize, num_undirected_edges: usize, num_faces: usize) -> Self {
137        let mut result = Self::new();
138        result
139            .s_mut()
140            .reserve_capacity(num_vertices, num_undirected_edges, num_faces);
141        result
142    }
143
144    /// Removes all edges, faces and vertices from the triangulation.
145    ///
146    /// This method does not change the allocated internal capacity.
147    fn clear(&mut self) {
148        self.s_mut().clear();
149        let new_hint_generator = HintGenerator::initialize_from_triangulation(self);
150        *self.hint_generator_mut() = new_hint_generator;
151    }
152
153    /// Creates a new triangulation populated with some vertices.
154    ///
155    /// This will usually be more efficient than inserting the elements sequentially by calling
156    /// [insert](Triangulation::insert).
157    ///
158    /// Returns an [InsertionError] if any input coordinate is invalid. This method should never fail
159    /// if all vertices were successfully checked with [crate::validate_vertex].
160    ///
161    /// # Runtime
162    ///
163    /// This method has a run time of `O(n)` but will run near linearly in practice.
164    /// The runtime can be as bad as `O(n²)` if the inputs are very degenerate, e.g.
165    /// if all input vertices lie on the same line.
166    ///
167    /// # Comparison to incremental insertion
168    ///
169    /// This graph shows the difference between incremental and bulk loading for a different number of random points - bulk loading becomes
170    /// more efficient very quickly.
171    #[doc = include_str!("../images/bulk_load_vs_incremental_graph.svg")]
172    fn bulk_load(elements: Vec<Self::Vertex>) -> Result<Self, InsertionError> {
173        let with_incorrect_hint_generator: DelaunayTriangulation<_, _, _, _> =
174            crate::delaunay_core::bulk_load(elements)?;
175        let hint_generator =
176            Self::HintGenerator::initialize_from_triangulation(&with_incorrect_hint_generator);
177        let (dcel, _, _) = with_incorrect_hint_generator.into_parts();
178
179        Ok(Self::from_parts(dcel, hint_generator, 0))
180    }
181
182    /// Converts a fixed vertex handle to a reference vertex handle.
183    ///
184    /// *See also the [handles](crate::handles) module for more information.*
185    fn vertex(
186        &self,
187        handle: FixedVertexHandle,
188    ) -> VertexHandle<'_, Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face> {
189        self.s().vertex(handle)
190    }
191
192    /// Returns a mutable reference to the associated data of a vertex.
193    fn vertex_data_mut(&mut self, handle: FixedVertexHandle) -> &mut Self::Vertex {
194        self.s_mut().vertex_data_mut(handle)
195    }
196
197    /// Converts a fixed face handle to a reference face handle.
198    ///
199    /// *See also the [handles](crate::handles) module for more information.*
200    fn face<InnerOuter: InnerOuterMarker>(
201        &self,
202        handle: FixedFaceHandle<InnerOuter>,
203    ) -> FaceHandle<
204        '_,
205        InnerOuter,
206        Self::Vertex,
207        Self::DirectedEdge,
208        Self::UndirectedEdge,
209        Self::Face,
210    > {
211        self.s().face(handle)
212    }
213
214    /// Returns a reference handle to the single outer face of this triangulation.
215    fn outer_face(
216        &self,
217    ) -> FaceHandle<
218        '_,
219        PossiblyOuterTag,
220        Self::Vertex,
221        Self::DirectedEdge,
222        Self::UndirectedEdge,
223        Self::Face,
224    > {
225        self.s().outer_face()
226    }
227
228    /// Converts a fixed directed edge handle to a reference directed edge handle.
229    ///
230    /// *See also the [handles](crate::handles) module for more information.*
231    fn directed_edge(
232        &self,
233        handle: FixedDirectedEdgeHandle,
234    ) -> DirectedEdgeHandle<'_, Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face>
235    {
236        DirectedEdgeHandle::new(self.s(), handle)
237    }
238
239    /// Converts a fixed undirected edge handle to a reference undirected edge handle.
240    ///
241    /// *See also the [handles](crate::handles) module for more information.*
242    fn undirected_edge(
243        &self,
244        handle: FixedUndirectedEdgeHandle,
245    ) -> UndirectedEdgeHandle<'_, Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face>
246    {
247        UndirectedEdgeHandle::new(self.s(), handle)
248    }
249
250    /// Returns a mutable reference ot the associated data of an undirected edge.
251    fn undirected_edge_data_mut(
252        &mut self,
253        handle: FixedUndirectedEdgeHandle,
254    ) -> &mut Self::UndirectedEdge {
255        self.s_mut().undirected_edge_data_mut(handle)
256    }
257
258    /// Returns the number of all faces, including the single outer face, of this
259    /// triangulation.
260    ///
261    /// This is always equal to `triangulation.num_inner_faces() + 1`.
262    fn num_all_faces(&self) -> usize {
263        self.s().num_faces()
264    }
265
266    /// Returns the number of inner faces in this triangulation.
267    fn num_inner_faces(&self) -> usize {
268        self.s().num_faces() - 1
269    }
270
271    /// Returns the number of undirected edges in this triangulation.
272    fn num_undirected_edges(&self) -> usize {
273        self.s().num_undirected_edges()
274    }
275
276    /// Returns the number of directed edges in this triangulation.
277    fn num_directed_edges(&self) -> usize {
278        self.s().num_directed_edges()
279    }
280
281    /// Returns the number of edges of the convex hull.
282    ///
283    /// *See also [convex_hull](Triangulation::convex_hull)*
284    ///
285    /// # Complexity
286    /// This method does not need to iterate through the convex hull and has a complexity of O(1)
287    fn convex_hull_size(&self) -> usize {
288        if self.all_vertices_on_line() {
289            self.num_directed_edges()
290        } else {
291            let num_inner_edges = self.num_inner_faces() * 3;
292            self.num_directed_edges() - num_inner_edges
293        }
294    }
295
296    /// An iterator visiting all directed edges.
297    ///
298    /// The iterator type is [DirectedEdgeHandle].
299    fn directed_edges(
300        &self,
301    ) -> DirectedEdgeIterator<'_, Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face>
302    {
303        self.s().directed_edges()
304    }
305
306    /// An iterator over all undirected edges.
307    ///
308    /// The iterator type is [UndirectedEdgeHandle]
309    fn undirected_edges(
310        &self,
311    ) -> UndirectedEdgeIterator<
312        '_,
313        Self::Vertex,
314        Self::DirectedEdge,
315        Self::UndirectedEdge,
316        Self::Face,
317    > {
318        self.s().undirected_edges()
319    }
320
321    /// Returns the number vertices in this triangulation.
322    fn num_vertices(&self) -> usize {
323        self.s().num_vertices()
324    }
325
326    /// An iterator visiting all vertices.
327    ///
328    /// The iterator type is [VertexHandle]
329    fn vertices(
330        &self,
331    ) -> VertexIterator<'_, Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face>
332    {
333        self.s().vertices()
334    }
335
336    /// An iterator visiting all vertices.
337    ///
338    /// The iterator type is [FixedVertexHandle]
339    fn fixed_vertices(&self) -> FixedVertexIterator {
340        self.s().fixed_vertices()
341    }
342
343    /// Get a vertex by its index
344    ///
345    /// To get the handle, wrap your local index in a FixedVertexHandle:
346    /// `let handle = FixedVertexHandle::from_index(my_index);`
347    #[allow(clippy::type_complexity)]
348    fn get_vertex(
349        &self,
350        handle: FixedVertexHandle,
351    ) -> Option<VertexHandle<'_, Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face>>
352    {
353        self.s().get_vertex(handle)
354    }
355
356    /// An iterator visiting all faces.
357    ///
358    /// The first returned face is the outer face, all other faces will be inner faces.
359    /// The iterator type is [FaceHandle<PossiblyOuterTag, ...>](FaceHandle).
360    ///
361    /// *See also [inner_faces()](Triangulation::inner_faces())*
362    fn all_faces(
363        &self,
364    ) -> FaceIterator<'_, Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face> {
365        self.s().faces()
366    }
367
368    /// An iterator visiting all inner faces.
369    //
370    /// The iterator type is [FaceHandle<InnerTag, ...>](FaceHandle).
371    fn inner_faces(
372        &self,
373    ) -> InnerFaceIterator<'_, Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face>
374    {
375        self.s().inner_faces()
376    }
377
378    /// An iterator visiting all faces of the Voronoi diagram.
379    ///
380    /// The iterator type is [VoronoiFace]
381    fn voronoi_faces(
382        &self,
383    ) -> VoronoiFaceIterator<'_, Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face>
384    {
385        VoronoiFaceIterator::new(self.s())
386    }
387
388    /// An iterator visiting all directed voronoi edges.
389    ///
390    /// The iterator type is [DirectedVoronoiEdge]
391    fn directed_voronoi_edges(
392        &self,
393    ) -> DirectedVoronoiEdgeIterator<
394        '_,
395        Self::Vertex,
396        Self::DirectedEdge,
397        Self::UndirectedEdge,
398        Self::Face,
399    > {
400        DirectedVoronoiEdgeIterator::new(self.s())
401    }
402
403    /// An iterator visiting all undirected voronoi edges.
404    ///
405    /// The iterator type is [UndirectedVoronoiEdge]
406    fn undirected_voronoi_edges(
407        &self,
408    ) -> UndirectedVoronoiEdgeIterator<
409        '_,
410        Self::Vertex,
411        Self::DirectedEdge,
412        Self::UndirectedEdge,
413        Self::Face,
414    > {
415        UndirectedVoronoiEdgeIterator::new(self.s())
416    }
417
418    /// Returns information about the location of a point in a triangulation.
419    ///
420    /// # Panics
421    ///
422    /// Panics if the target point has any `NAN` coordinate.
423    fn locate(
424        &self,
425        point: Point2<<Self::Vertex as HasPosition>::Scalar>,
426    ) -> PositionInTriangulation {
427        let hint = self.hint_generator().get_hint(point);
428        self.locate_with_hint_option_core(point, Some(hint))
429    }
430
431    /// Locates a vertex at a given position.
432    ///
433    /// Returns `None` if the point could not be found.
434    ///
435    /// # Panics
436    ///
437    /// Panics if the target point has any `NAN` coordinate.
438    #[allow(clippy::type_complexity)]
439    fn locate_vertex(
440        &self,
441        point: Point2<<Self::Vertex as HasPosition>::Scalar>,
442    ) -> Option<VertexHandle<'_, Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face>>
443    {
444        match self.locate(point) {
445            PositionInTriangulation::OnVertex(vertex) => Some(self.vertex(vertex)),
446            _ => None,
447        }
448    }
449
450    /// Returns an edge between two vertices.
451    ///
452    /// If the edge does not exist, `None` is returned.
453    /// This operation runs in `O(n)` time, where `n` is
454    /// the degree of `from`.
455    #[allow(clippy::type_complexity)]
456    fn get_edge_from_neighbors(
457        &self,
458        from: FixedVertexHandle,
459        to: FixedVertexHandle,
460    ) -> Option<
461        DirectedEdgeHandle<'_, Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face>,
462    > {
463        self.s().get_edge_from_neighbors(from, to)
464    }
465
466    /// Returns information about the location of a point in a triangulation.
467    ///
468    /// Additionally, a hint can be given to speed up computation.
469    /// The hint should be a vertex close to the position that
470    /// is being looked up.
471    ///
472    /// # Panics
473    ///
474    /// Panics if the target vertex has any `NAN` coordinate.
475    ///
476    /// *See also [locate](Triangulation::locate), [locate_vertex](Triangulation::locate_vertex)*
477    fn locate_with_hint(
478        &self,
479        point: Point2<<Self::Vertex as HasPosition>::Scalar>,
480        hint: FixedVertexHandle,
481    ) -> PositionInTriangulation {
482        self.locate_with_hint_option_core(point, Some(hint))
483    }
484
485    /// Inserts a new vertex into the triangulation.
486    ///
487    /// A hint can be given to speed up the process.
488    /// The hint should be a handle of a vertex close to the new vertex.
489    /// in this case the insertion time can be reduced to O(1) on average
490    /// if the hint is close. If the hint is randomized, running time will
491    /// be O(sqrt(n)) on average with an O(n) worst case.
492    ///
493    /// *See also [insert](Triangulation::insert)*
494    fn insert_with_hint(
495        &mut self,
496        t: Self::Vertex,
497        hint: FixedVertexHandle,
498    ) -> Result<FixedVertexHandle, InsertionError> {
499        self.insert_with_hint_option(t, Some(hint))
500    }
501
502    /// Attempts to remove a vertex from the triangulation.
503    ///
504    /// Returns the removed vertex data if it could be found.
505    ///
506    /// # Handle invalidation
507    /// This method will invalidate all vertex, edge and face handles
508    /// upon successful removal.
509    ///
510    /// # Panics
511    ///
512    /// Panics if the target position has any `NAN` coordinate.
513    ///
514    /// *See also [remove](Triangulation::remove)*
515    fn locate_and_remove(
516        &mut self,
517        point: Point2<<Self::Vertex as HasPosition>::Scalar>,
518    ) -> Option<Self::Vertex> {
519        match self.locate_with_hint_option_core(point, None) {
520            PositionInTriangulation::OnVertex(handle) => Some(self.remove(handle)),
521            _ => None,
522        }
523    }
524
525    /// Removes a vertex from the triangulation.
526    ///
527    /// This operation runs in O(d²), where d is the degree of the
528    /// removed vertex (the number of its outgoing edges).
529    ///
530    /// # Handle invalidation
531    /// This method will invalidate all vertex, edge and face handles.
532    fn remove(&mut self, vertex: FixedVertexHandle) -> Self::Vertex {
533        self.remove_and_notify(vertex)
534    }
535
536    /// Inserts a new vertex into the triangulation.
537    ///
538    /// This operation runs in O(log(n)) on average when using a tree
539    /// lookup to back up the triangulation, or in O(sqrt(n)) when using
540    /// a walk lookup. n denotes the number of vertices, the given
541    /// running times assume that input data is given uniformly randomly
542    /// distributed. If the point has already been contained in the
543    /// triangulation, the old vertex is overwritten.
544    ///
545    /// Returns either a handle to the new vertex or an error if the vertex could not be inserted.
546    /// The triangulation will remain unchanged if an error ocurred.
547    ///
548    /// Use [vertex](Triangulation::vertex) to retrieve more information about the inserted vertex.
549    ///
550    /// # Example
551    /// ```
552    /// # fn main() -> Result<(), spade::InsertionError> {
553    /// use spade::{DelaunayTriangulation, InsertionError, Triangulation, Point2};
554    ///
555    /// let mut triangulation = DelaunayTriangulation::<_>::default();
556    ///
557    /// let vertices = vec![Point2::new(0.0, 1.0), Point2::new(4.0, 2.0), Point2::new(3.0, 4.0)];
558    /// for vertex in vertices {
559    ///   // While not required in this example, it might be a good idea in general to prevent underflow errors like this:
560    ///   let corrected_position = spade::mitigate_underflow(vertex);
561    ///   triangulation.insert(corrected_position)?;
562    /// }
563    ///
564    /// // Done!
565    /// assert_eq!(triangulation.num_inner_faces(), 1);
566    /// assert_eq!(triangulation.num_vertices(), 3);
567    /// # Ok(()) }
568    /// ```
569    ///
570    /// *See also [insert_with_hint](Triangulation::insert_with_hint), [validate_vertex](crate::validate_vertex),
571    ///  [mitigate_underflow](crate::mitigate_underflow), [bulk_load](Triangulation::bulk_load)*
572    fn insert(&mut self, vertex: Self::Vertex) -> Result<FixedVertexHandle, InsertionError> {
573        self.insert_with_hint_option(vertex, None)
574    }
575
576    /// An iterator visiting all undirected edges.
577    ///
578    /// The iterator type is [FixedUndirectedEdgeHandle].
579    fn fixed_undirected_edges(&self) -> FixedUndirectedEdgeIterator {
580        FixedUndirectedEdgeIterator::new(self.num_undirected_edges())
581    }
582
583    /// An iterator visiting all directed edges.
584    ///
585    /// The iterator type is [FixedDirectedEdgeHandle].
586    fn fixed_directed_edges(&self) -> FixedDirectedEdgeIterator {
587        FixedDirectedEdgeIterator::new(self.num_directed_edges())
588    }
589
590    /// An iterator visiting all faces.
591    ///
592    /// The first returned element is the outer face. All other
593    /// faces are inner faces.
594    ///
595    /// The iterator type is [FixedFaceHandle<PossiblyOuterTag, ...>](FixedFaceHandle).
596    fn fixed_all_faces(&self) -> FixedFaceIterator {
597        FixedFaceIterator::new(self.num_all_faces())
598    }
599
600    /// An iterator visiting all inner faces of the triangulation.
601    ///
602    /// The iterator type is [FixedFaceHandle<InnerTag, ...>](FixedFaceHandle).
603    fn fixed_inner_faces(&self) -> FixedInnerFaceIterator {
604        let mut result = FixedInnerFaceIterator::new(self.num_all_faces());
605        result.next();
606        result
607    }
608
609    /// Returns `true` if all vertices lie on a single line.
610    ///
611    /// This is always the case for triangulations with 0, 1 or two vertices.
612    fn all_vertices_on_line(&self) -> bool {
613        self.num_all_faces() == 1
614    }
615
616    /// Returns an iterator over all convex hull edges.
617    ///
618    /// The edges are returned in clockwise order as seen from any point in the triangulation.
619    ///
620    #[doc = include_str!("../images/convex_hull.svg")]
621    ///
622    /// *A triangulation with its convex hull being highlighted. `e0` .. `e5` denote the returned
623    /// edges in clockwise order.*
624    ///
625    /// *See also [convex_hull_size](Triangulation::convex_hull_size)*
626    fn convex_hull(
627        &self,
628    ) -> HullIterator<'_, Self::Vertex, Self::DirectedEdge, Self::UndirectedEdge, Self::Face> {
629        {
630            HullIterator::new(self.s())
631        }
632    }
633
634    /// Returns a mutable reference to the associated data of a face.
635    fn face_data_mut<InnerOuter: InnerOuterMarker>(
636        &mut self,
637        handle: FixedFaceHandle<InnerOuter>,
638    ) -> &mut Self::Face {
639        self.s_mut().face_data_mut(handle)
640    }
641
642    /// Returns a mutable reference to the associated data of a directed edge.
643    fn directed_edge_data_mut(
644        &mut self,
645        handle: FixedDirectedEdgeHandle,
646    ) -> &mut Self::DirectedEdge {
647        self.s_mut().directed_edge_data_mut(handle)
648    }
649}
650
651/// Implements general functions for triangulations over floating point data types.
652///
653/// This trait is implemented for any triangulation (constrained and regular Delaunay triangulations)
654/// over `f32` and `f64`.
655pub trait FloatTriangulation: Triangulation
656where
657    <Self::Vertex as HasPosition>::Scalar: Float,
658{
659    /// Returns all edges contained in a rectangle.
660    ///
661    /// An edge is considered to be contained in the rectangle if at least one point exists
662    /// that is both on the edge and inside the rectangle (including its boundary).
663    ///
664    /// The rectangle is specified by its lower and upper corners. Yields an empty iterator
665    /// if `lower.x > upper.x` or `lower.y > upper.y`.
666    ///
667    #[doc = include_str!("../images/shape_iterator_rectangle_edges.svg")]
668    ///
669    /// *Example: Shows all edges (red) that are returned when iterating over a rectangle (teal)*
670    ///
671    /// # Memory consumption
672    ///
673    /// Memory usage is, on average, in O(|convex_hull(E)|) where "E" refers to all edges that
674    /// have been returned so far.
675    fn get_edges_in_rectangle(
676        &self,
677        lower: Point2<<Self::Vertex as HasPosition>::Scalar>,
678        upper: Point2<<Self::Vertex as HasPosition>::Scalar>,
679    ) -> EdgesInShapeIterator<'_, Self, RectangleMetric<<Self::Vertex as HasPosition>::Scalar>>
680    {
681        let distance_metric = RectangleMetric::new(lower, upper);
682        let center = lower.add(upper).mul(0.5f32.into());
683        EdgesInShapeIterator {
684            inner_iter: FloodFillIterator::new(self, distance_metric, center),
685        }
686    }
687
688    /// Returns all edges contained in a circle.
689    ///
690    /// An edge is considered to be contained in a circle if at least one point exists that is both
691    /// on the edge and within the circle (including its boundary).
692    ///
693    /// `radius_2` refers to the **squared radius** of the circle.
694    ///
695    #[doc = include_str!("../images/shape_iterator_circle_edges.svg")]
696    ///
697    /// *Example: Shows all edges (red) that are returned when iterating over a circle (teal)*
698    ///
699    /// # Panics
700    ///
701    /// Panics if `radius_2 < 0.0`
702    ///
703    /// # Memory consumption
704    ///
705    /// Memory usage is, on average, in O(|convex_hull(E)|) where "E" refers to all edges that
706    /// have been returned so far.
707    fn get_edges_in_circle(
708        &self,
709        center: Point2<<Self::Vertex as HasPosition>::Scalar>,
710        radius_2: <Self::Vertex as HasPosition>::Scalar,
711    ) -> EdgesInShapeIterator<'_, Self, CircleMetric<<Self::Vertex as HasPosition>::Scalar>> {
712        let metric = CircleMetric::new(center, radius_2);
713        EdgesInShapeIterator {
714            inner_iter: FloodFillIterator::new(self, metric, center),
715        }
716    }
717
718    /// Returns all vertices in a rectangle.
719    ///
720    /// Any vertex on the rectangle's boundary or corners is also returned.
721    ///
722    /// The rectangle is specified by its lower and upper corners. Yields an empty iterator
723    /// if `lower.x > upper.x || lower.y > upper.y`.
724    ///
725    #[doc = include_str!("../images/shape_iterator_rectangle_vertices.svg")]
726    ///
727    /// *Example: Shows all vertices (red) that are returned when iterating over a rectangle (teal)*
728    ///
729    /// # Memory consumption
730    ///
731    /// Consumed memory is in `O(|convex_hull(V)|)` where `V` refers to all vertices that have been
732    /// returned so far.
733    fn get_vertices_in_rectangle(
734        &self,
735        lower: Point2<<Self::Vertex as HasPosition>::Scalar>,
736        upper: Point2<<Self::Vertex as HasPosition>::Scalar>,
737    ) -> VerticesInShapeIterator<'_, Self, RectangleMetric<<Self::Vertex as HasPosition>::Scalar>>
738    {
739        let distance_metric = RectangleMetric::new(lower, upper);
740        let center = lower.add(upper).mul(0.5f32.into());
741
742        VerticesInShapeIterator::new(FloodFillIterator::new(self, distance_metric, center))
743    }
744
745    /// Returns all vertices in a circle.
746    ///
747    /// Any vertex on the circle's boundary is also returned.
748    ///
749    /// `radius_2` refers to the **squared radius** of the circle.
750    ///
751    #[doc = include_str!("../images/shape_iterator_circle_vertices.svg")]
752    ///
753    /// *Example: Shows all vertices (red) that are returned when iterating over a circle (teal)*
754    ///
755    /// # Panics
756    ///
757    /// Panics if `radius_2 < 0.0`
758    ///
759    /// # Memory consumption
760    ///
761    /// Consumed memory is in `O(|convex_hull(V)|)` where `V` refers to all vertices that have been
762    /// returned so far.
763    fn get_vertices_in_circle(
764        &self,
765        center: Point2<<Self::Vertex as HasPosition>::Scalar>,
766        radius_2: <Self::Vertex as HasPosition>::Scalar,
767    ) -> VerticesInShapeIterator<'_, Self, CircleMetric<<Self::Vertex as HasPosition>::Scalar>>
768    {
769        let distance_metric = CircleMetric::new(center, radius_2);
770
771        VerticesInShapeIterator::new(FloodFillIterator::new(self, distance_metric, center))
772    }
773
774    /// Used for barycentric interpolation on this triangulation. Refer to the documentation of
775    /// [Barycentric] and [crate::NaturalNeighbor] for more information.
776    ///
777    /// *Note:* In contrast to the other interpolation algorithms, barycentric interpolation also works
778    /// for [crate::ConstrainedDelaunayTriangulation]s.
779    fn barycentric(&self) -> Barycentric<'_, Self> {
780        Barycentric::new(self)
781    }
782}
783
784impl<T> FloatTriangulation for T
785where
786    T: Triangulation,
787    <T::Vertex as HasPosition>::Scalar: Float,
788{
789}