From 826057a5e0a3d196b279d30bc475574b2d27d089 Mon Sep 17 00:00:00 2001 From: wo80 Date: Tue, 9 Jan 2024 11:57:31 +0100 Subject: [PATCH] Minor cleanup and updates to DCEL entities. * Rename 'Boundary' property of HalfEdge class to 'Label' * Add 'Label' property to Face class and initialize to generator label * Update Voronoi tests. --- .../Voronoi/BoundedVoronoiTest.cs | 16 ++++++++++--- .../Voronoi/StandardVoronoiTest.cs | 16 ++++++++++--- src/Triangle/Topology/DCEL/DcelMesh.cs | 24 +++++-------------- src/Triangle/Topology/DCEL/Face.cs | 17 +++++++++++-- src/Triangle/Topology/DCEL/HalfEdge.cs | 15 +++++++----- src/Triangle/Voronoi/StandardVoronoi.cs | 2 +- 6 files changed, 57 insertions(+), 33 deletions(-) diff --git a/src/Triangle.Tests/Voronoi/BoundedVoronoiTest.cs b/src/Triangle.Tests/Voronoi/BoundedVoronoiTest.cs index 58bb02b..1c46462 100644 --- a/src/Triangle.Tests/Voronoi/BoundedVoronoiTest.cs +++ b/src/Triangle.Tests/Voronoi/BoundedVoronoiTest.cs @@ -11,7 +11,14 @@ public class BoundedVoronoiTest [Test] public void TestBoundedVoronoi() { - var p = Helper.SplitRectangle(-1, 1, 1, -1, 3); + int boundaryLabel = 3; + + var p = Helper.SplitRectangle(-1, 1, 1, -1, boundaryLabel); + + Assert.That(p.Regions.Count, Is.EqualTo(2)); + + int regionLabel1 = p.Regions[0].Label; + int regionLabel2 = p.Regions[1].Label; var mesher = new GenericMesher(); var mesh = (Mesh)mesher.Triangulate(p); @@ -19,8 +26,8 @@ public void TestBoundedVoronoi() var voronoi = new BoundedVoronoi(mesh); // The "split rectangle" polygon has two region pointer set. - Assert.That(voronoi.Vertices.Count(v => v.Label == 1), Is.EqualTo(2)); - Assert.That(voronoi.Vertices.Count(v => v.Label == 2), Is.EqualTo(2)); + Assert.That(voronoi.Vertices.Count(v => v.Label == regionLabel1), Is.EqualTo(2)); + Assert.That(voronoi.Vertices.Count(v => v.Label == regionLabel2), Is.EqualTo(2)); // The polygon has 6 boundary segments, so the Voronoi diagram // should have 6 infinite edges (which are projected onto the @@ -32,6 +39,9 @@ public void TestBoundedVoronoi() // All Voronoi cells should have a generator vertex. Assert.That(voronoi.Faces.All(f => f.Generator is not null)); + // All Voronoi cells should have the same label as the dual vertex. + Assert.That(voronoi.Faces.All(f => f.Label == boundaryLabel)); + // Check DCEL topology (all Voronoi cells should be closed). Assert.That(voronoi.IsConsistent()); } diff --git a/src/Triangle.Tests/Voronoi/StandardVoronoiTest.cs b/src/Triangle.Tests/Voronoi/StandardVoronoiTest.cs index a022aa1..31bc04e 100644 --- a/src/Triangle.Tests/Voronoi/StandardVoronoiTest.cs +++ b/src/Triangle.Tests/Voronoi/StandardVoronoiTest.cs @@ -11,7 +11,14 @@ public class StandardVoronoiTest [Test] public void TestStandardVoronoi() { - var p = Helper.SplitRectangle(-1, 1, 1, -1, 3); + int boundaryLabel = 3; + + var p = Helper.SplitRectangle(-1, 1, 1, -1, boundaryLabel); + + Assert.That(p.Regions.Count, Is.EqualTo(2)); + + int regionLabel1 = p.Regions[0].Label; + int regionLabel2 = p.Regions[1].Label; var mesher = new GenericMesher(); var mesh = (Mesh)mesher.Triangulate(p); @@ -19,8 +26,8 @@ public void TestStandardVoronoi() var voronoi = new StandardVoronoi(mesh); // The "split rectangle" polygon has two region pointer set. - Assert.That(voronoi.Vertices.Count(v => v.Label == 1), Is.EqualTo(2)); - Assert.That(voronoi.Vertices.Count(v => v.Label == 2), Is.EqualTo(2)); + Assert.That(voronoi.Vertices.Count(v => v.Label == regionLabel1), Is.EqualTo(2)); + Assert.That(voronoi.Vertices.Count(v => v.Label == regionLabel2), Is.EqualTo(2)); // The polygon has 6 boundary segments, so the Voronoi diagram // should have 6 infinite edges. @@ -30,6 +37,9 @@ public void TestStandardVoronoi() // All Voronoi cells should have a generator vertex. Assert.That(voronoi.Faces.All(f => f.Generator is not null)); + // All Voronoi cells should have the same label as the dual vertex. + Assert.That(voronoi.Faces.All(f => f.Label == boundaryLabel)); + // Check DCEL topology (account for unbounded Voronoi cells). Assert.That(voronoi.IsConsistent(false)); } diff --git a/src/Triangle/Topology/DCEL/DcelMesh.cs b/src/Triangle/Topology/DCEL/DcelMesh.cs index 4dcfd67..339cd3c 100644 --- a/src/Triangle/Topology/DCEL/DcelMesh.cs +++ b/src/Triangle/Topology/DCEL/DcelMesh.cs @@ -48,34 +48,22 @@ protected DcelMesh(bool initialize) /// /// Gets the vertices of the Voronoi diagram. /// - public List Vertices - { - get { return vertices; } - } + public List Vertices => vertices; /// /// Gets the list of half-edges specify the Voronoi diagram topology. /// - public List HalfEdges - { - get { return edges; } - } + public List HalfEdges => edges; /// /// Gets the faces of the Voronoi diagram. /// - public List Faces - { - get { return faces; } - } + public List Faces => faces; /// /// Gets the collection of edges of the Voronoi diagram. /// - public IEnumerable Edges - { - get { return EnumerateEdges(); } - } + public IEnumerable Edges => EnumerateEdges(); /// /// Check if the DCEL is consistent. @@ -234,7 +222,7 @@ public void ResolveBoundaryEdges() var map = new Dictionary(); // TODO: parallel? - foreach (var edge in this.edges) + foreach (var edge in edges) { if (edge.twin == null) { @@ -252,7 +240,7 @@ public void ResolveBoundaryEdges() edge.id = j++; edge.next = map[edge.twin.origin.id]; - this.edges.Add(edge); + edges.Add(edge); } } diff --git a/src/Triangle/Topology/DCEL/Face.cs b/src/Triangle/Topology/DCEL/Face.cs index db4a10b..2bde7f8 100644 --- a/src/Triangle/Topology/DCEL/Face.cs +++ b/src/Triangle/Topology/DCEL/Face.cs @@ -10,7 +10,7 @@ namespace TriangleNet.Topology.DCEL using TriangleNet.Geometry; /// - /// A face of the DCEL datastructure. + /// A face of the DCEL data structure. /// public class Face { @@ -30,7 +30,7 @@ static Face() #endregion internal int id; - internal int mark; + internal int label; // If the face is a Voronoi cell, this is the point that generates the cell. internal Point generator; @@ -53,6 +53,18 @@ public int ID set { id = value; } } + /// + /// Gets or sets a general-purpose label. + /// + /// + /// For Voronoi diagrams, this will be the same as the label. + /// + public int Label + { + get { return label; } + set { label = value; } + } + /// /// Gets or sets a half-edge connected to the face. /// @@ -95,6 +107,7 @@ public Face(Point generator, HalfEdge edge) if (generator != null) { id = generator.ID; + label = generator.Label; } } diff --git a/src/Triangle/Topology/DCEL/HalfEdge.cs b/src/Triangle/Topology/DCEL/HalfEdge.cs index cbf536d..99afcea 100644 --- a/src/Triangle/Topology/DCEL/HalfEdge.cs +++ b/src/Triangle/Topology/DCEL/HalfEdge.cs @@ -7,12 +7,12 @@ namespace TriangleNet.Topology.DCEL { /// - /// A half-edge of the DCEL datastructure. + /// A half-edge of the DCEL data structure. /// public class HalfEdge { internal int id; - internal int mark; + internal int label; internal Vertex origin; internal Face face; @@ -29,12 +29,15 @@ public int ID } /// - /// Gets or sets a boundary marker. + /// Gets or sets a general-purpose label. /// - public int Boundary + /// + /// Can be used to identify boundary segments. + /// + public int Label { - get { return mark; } - set { mark = value; } + get { return label; } + set { label = value; } } /// diff --git a/src/Triangle/Voronoi/StandardVoronoi.cs b/src/Triangle/Voronoi/StandardVoronoi.cs index 839bcd5..3469ff2 100644 --- a/src/Triangle/Voronoi/StandardVoronoi.cs +++ b/src/Triangle/Voronoi/StandardVoronoi.cs @@ -37,7 +37,7 @@ public StandardVoronoi(Mesh mesh, Rectangle box) /// Initializes a new instance of the class. /// /// The mesh. - /// The bounding box used for clipping (not implemented.) + /// The bounding box used for clipping (not implemented). /// /// public StandardVoronoi(Mesh mesh, Rectangle box, IVoronoiFactory factory, IPredicates predicates)