diff --git a/src/Triangle.Examples/Examples/Example4.cs b/src/Triangle.Examples/Examples/Example4.cs
index c7ab07a..449eb4b 100644
--- a/src/Triangle.Examples/Examples/Example4.cs
+++ b/src/Triangle.Examples/Examples/Example4.cs
@@ -8,7 +8,7 @@ namespace TriangleNet.Examples
using TriangleNet.Smoothing;
///
- /// Refine only a part of a polygon mesh be using region pointers and an area constraint.
+ /// Refine only a part of a polygon mesh by using region pointers and an area constraint.
///
public class Example4
{
diff --git a/src/Triangle.Examples/Examples/Example7.cs b/src/Triangle.Examples/Examples/Example7.cs
index f08de35..5c18841 100644
--- a/src/Triangle.Examples/Examples/Example7.cs
+++ b/src/Triangle.Examples/Examples/Example7.cs
@@ -1,8 +1,10 @@
namespace TriangleNet.Examples
{
+ using System;
using TriangleNet.Geometry;
using TriangleNet.Meshing;
+ using TriangleNet.Meshing.Iterators;
using TriangleNet.Rendering.Text;
///
@@ -26,7 +28,18 @@ namespace TriangleNet.Examples
};
// Generate mesh using the polygons Triangulate extension method.
- var mesh = poly.Triangulate(quality);
+ var mesh = (Mesh)poly.Triangulate(quality);
+
+ // Validate.
+ foreach (var e in EdgeIterator.EnumerateEdges(mesh))
+ {
+ double length = Math.Sqrt(DistSqr(e.GetVertex(0), e.GetVertex(1)));
+
+ if (length > MAX_EDGE_LENGTH)
+ {
+ Console.WriteLine("Something's wrong in here ...");
+ }
+ }
if (print) SvgImage.Save(mesh, "example-7.svg", 500);
}
diff --git a/src/Triangle.Examples/Examples/Example9.cs b/src/Triangle.Examples/Examples/Example9.cs
index 72d264f..93d4a53 100644
--- a/src/Triangle.Examples/Examples/Example9.cs
+++ b/src/Triangle.Examples/Examples/Example9.cs
@@ -11,7 +11,7 @@ namespace TriangleNet.Examples
///
public class Example9
{
- public static void Run()
+ public static void Run(bool print = false)
{
var pts = new List
{
@@ -39,7 +39,7 @@ namespace TriangleNet.Examples
var list = MeshValidator.GetDegenerateBoundaryTriangles(mesh);
- if (list.Any())
+ if (print && list.Any())
{
Console.WriteLine("Iteration {0}: found {1} degenerate triangle(s) of {2}.",
i, list.Count(), mesh.Triangles.Count);
diff --git a/src/Triangle/Geometry/Contour.cs b/src/Triangle/Geometry/Contour.cs
index 08932a9..68ab9af 100644
--- a/src/Triangle/Geometry/Contour.cs
+++ b/src/Triangle/Geometry/Contour.cs
@@ -142,7 +142,7 @@ namespace TriangleNet.Geometry
double dx, dy;
double h;
- var predicates = new RobustPredicates();
+ var predicates = RobustPredicates.Default;
a = contour[0];
b = contour[1];
diff --git a/src/Triangle/Tools/PolygonValidator.cs b/src/Triangle/Tools/PolygonValidator.cs
index 4609519..64c82cc 100644
--- a/src/Triangle/Tools/PolygonValidator.cs
+++ b/src/Triangle/Tools/PolygonValidator.cs
@@ -37,17 +37,17 @@ namespace TriangleNet.Tools
if (p == null)
{
horrors++;
- logger.Warning(String.Format("Point {0} is null.", i), "PolygonValidator.IsConsistent()");
+ logger.Warning(string.Format("Point {0} is null.", i), "PolygonValidator.IsConsistent()");
}
else if (double.IsNaN(p.x) || double.IsNaN(p.y))
{
horrors++;
- logger.Warning(String.Format("Point {0} has invalid coordinates.", i), "PolygonValidator.IsConsistent()");
+ logger.Warning(string.Format("Point {0} has invalid coordinates.", i), "PolygonValidator.IsConsistent()");
}
else if (double.IsInfinity(p.x) || double.IsInfinity(p.y))
{
horrors++;
- logger.Warning(String.Format("Point {0} has invalid coordinates.", i), "PolygonValidator.IsConsistent()");
+ logger.Warning(string.Format("Point {0} has invalid coordinates.", i), "PolygonValidator.IsConsistent()");
}
i++;
@@ -60,7 +60,7 @@ namespace TriangleNet.Tools
if (seg == null)
{
horrors++;
- logger.Warning(String.Format("Segment {0} is null.", i), "PolygonValidator.IsConsistent()");
+ logger.Warning(string.Format("Segment {0} is null.", i), "PolygonValidator.IsConsistent()");
// Always abort if a NULL-segment is found.
return false;
@@ -72,7 +72,7 @@ namespace TriangleNet.Tools
if ((p.x == q.x) && (p.y == q.y))
{
horrors++;
- logger.Warning(String.Format("Endpoints of segment {0} are coincident (IDs {1} / {2}).", i, p.id, q.id),
+ logger.Warning(string.Format("Endpoints of segment {0} are coincident (IDs {1} / {2}).", i, p.id, q.id),
"PolygonValidator.IsConsistent()");
}
@@ -109,7 +109,7 @@ namespace TriangleNet.Tools
if (points[i - 1] == points[i])
{
horrors++;
- logger.Warning(string.Format("Found duplicate point {0}.", points[i]),
+ logger.Warning(string.Format("Found duplicate point ({0}, {1}).", points[i].x, points[i].y),
"PolygonValidator.HasDuplicateVertices()");
}
}
@@ -117,6 +117,53 @@ namespace TriangleNet.Tools
return horrors > 0;
}
+ ///
+ /// Get the ratio of the largest and smallest segment length.
+ ///
+ /// The polygon.
+ /// The ratio threshold.
+ ///
+ /// This method will also report zero-length segments.
+ ///
+ public static double GetSegmentRatio(IPolygon poly, double threshold = 2e12)
+ {
+ var logger = Log.Instance;
+
+ double min = double.MaxValue;
+ double max = 0.0;
+
+ foreach (var seg in poly.Segments)
+ {
+ var p = seg.GetVertex(0);
+ var q = seg.GetVertex(1);
+
+ var dx = p.X - q.X;
+ var dy = p.Y - q.Y;
+
+ var length = Math.Sqrt(dx * dx + dy * dy);
+
+ if (length == 0.0)
+ {
+ logger.Warning(string.Format("Found zero-length segment (vertex IDs {0} / {1}).", p.id, q.id),
+ "PolygonValidator.GetSegmentRatio()");
+ continue;
+ }
+
+ min = Math.Min(min, length);
+ max = Math.Max(max, length);
+ }
+
+ double ratio = max / min;
+
+ if (ratio > threshold)
+ {
+ logger.Warning(string.Format("Polygon has large segment ratio {0:G2}.", ratio),
+ "PolygonValidator.GetSegmentRatio()");
+ }
+
+ return ratio;
+ }
+
///
/// Test the polygon for 360 degree angles.
///
diff --git a/src/Triangle/TrianglePool.cs b/src/Triangle/TrianglePool.cs
index 30d866c..aa67836 100644
--- a/src/Triangle/TrianglePool.cs
+++ b/src/Triangle/TrianglePool.cs
@@ -27,6 +27,11 @@ namespace TriangleNet
// A stack of free triangles.
Stack stack;
+ ///
+ /// Gets the total number of currently allocated triangles.
+ ///
+ public int Capacity => size;
+
public TrianglePool()
{
size = 0;