Add convex hull example.

This commit is contained in:
wo80
2022-04-25 17:46:19 +02:00
parent 5b2d85e299
commit e162e02102
12 changed files with 107 additions and 27 deletions
+1 -5
View File
@@ -2,7 +2,6 @@
namespace TriangleNet.Examples namespace TriangleNet.Examples
{ {
using TriangleNet.Geometry; using TriangleNet.Geometry;
using TriangleNet.Meshing;
using TriangleNet.Meshing.Algorithm; using TriangleNet.Meshing.Algorithm;
using TriangleNet.Rendering.Text; using TriangleNet.Rendering.Text;
@@ -19,11 +18,8 @@ namespace TriangleNet.Examples
// Choose triangulator: Incremental, SweepLine or Dwyer. // Choose triangulator: Incremental, SweepLine or Dwyer.
var triangulator = new Dwyer(); var triangulator = new Dwyer();
// Generate a default mesher.
var mesher = new GenericMesher(triangulator);
// Generate mesh. // Generate mesh.
var mesh = mesher.Triangulate(points); var mesh = triangulator.Triangulate(points, new Configuration());
if (print) SvgImage.Save(mesh, "example-1.svg", 500); if (print) SvgImage.Save(mesh, "example-1.svg", 500);
+1 -1
View File
@@ -9,7 +9,7 @@ namespace TriangleNet.Examples
/// <summary> /// <summary>
/// Troubleshooting: finding degenerate boundary triangles. /// Troubleshooting: finding degenerate boundary triangles.
/// </summary> /// </summary>
public class Example9 public class Example10
{ {
public static bool Run(bool print = false) public static bool Run(bool print = false)
{ {
+4 -4
View File
@@ -12,7 +12,7 @@ namespace TriangleNet.Examples
/// <summary> /// <summary>
/// Scattered data interpolation without USE_Z or USE_ATTRIBS. /// Scattered data interpolation without USE_Z or USE_ATTRIBS.
/// </summary> /// </summary>
internal class Example10 internal class Example11
{ {
// The function we are sampling. // The function we are sampling.
private static readonly Func<Point, double> F = p => Math.Sin(p.X) * Math.Cos(p.Y); private static readonly Func<Point, double> F = p => Math.Sin(p.X) * Math.Cos(p.Y);
@@ -28,7 +28,7 @@ namespace TriangleNet.Examples
var mesh = GetScatteredDataMesh(r, out double[] data); var mesh = GetScatteredDataMesh(r, out double[] data);
//var mesh = GetStructuredDataMesh(r, out double[] data); //var mesh = GetStructuredDataMesh(r, out double[] data);
if (print) SvgImage.Save(mesh, "example-10.svg", 500); if (print) SvgImage.Save(mesh, "example-11.svg", 500);
// The points to interpolate. // The points to interpolate.
var xy = Generate.RandomPoints(50, r); var xy = Generate.RandomPoints(50, r);
@@ -69,8 +69,8 @@ namespace TriangleNet.Examples
double h = domain.Width / SIZE; double h = domain.Width / SIZE;
// Generate a rectangle boundary point set (20 points on each side). // Generate a rectangle boundary point set (SIZE points on each side).
var input = Generate.Rectangle(r, 0.5); var input = Generate.Rectangle(r, h);
// Making sure we add some margin to the boundary. // Making sure we add some margin to the boundary.
h = -h / 2; h = -h / 2;
@@ -0,0 +1,83 @@
namespace TriangleNet.Examples
{
using System.Collections.Generic;
using TriangleNet.Geometry;
using TriangleNet.Meshing;
using TriangleNet.Rendering.Text;
/// <summary>
/// Simple point set triangulation with convex hull.
/// </summary>
public class Example2
{
public static bool Run(bool print = false)
{
const int N = 50;
// Generate point set.
var points = Generate.RandomPoints(N, new Rectangle(0, 0, 100, 100));
// We use a polygon as input to enable segment insertion on the convex hull.
var poly = new Polygon(N);
poly.Points.AddRange(points);
// Set the 'convex' option to enclose the convex hull with segments.
var options = new ConstraintOptions() { Convex = true };
// Generate mesh.
var mesh = poly.Triangulate(options);
if (print) SvgImage.Save(mesh, "example-2.svg", 500);
return CheckConvexHull(mesh.Segments);
}
private static bool CheckConvexHull(IEnumerable<ISegment> segments)
{
int first = -1, prev = -1;
Point a = null, b, c;
var p = RobustPredicates.Default;
foreach (var s in segments)
{
// If first loop ...
if (first < 0)
{
// initialize vertex ids of first segment and ...
first = s.P1;
prev = s.P0;
// initialize first segment endpoint.
a = s.GetVertex(1);
continue;
}
// Check whether segments are returned in consecutive order.
if (prev != s.P1)
{
return false;
}
b = s.GetVertex(1);
c = s.GetVertex(0);
// Check whether the convex hull is traversed in counterclockwise.
if (p.CounterClockwise(a, b, c) < 0)
{
return false;
}
prev = s.P0;
a = b;
}
// Check whether the last segment connects to the first.
return prev == first;
}
}
}
+2 -2
View File
@@ -7,7 +7,7 @@
/// <summary> /// <summary>
/// Triangulate a polygon with hole and set minimum angle constraint. /// Triangulate a polygon with hole and set minimum angle constraint.
/// </summary> /// </summary>
public static class Example2 public static class Example3
{ {
public static bool Run(bool print = false) public static bool Run(bool print = false)
{ {
@@ -20,7 +20,7 @@
// Generate mesh using the polygons Triangulate extension method. // Generate mesh using the polygons Triangulate extension method.
var mesh = poly.Triangulate(quality); var mesh = poly.Triangulate(quality);
if (print) SvgImage.Save(mesh, "example-2.svg", 500); if (print) SvgImage.Save(mesh, "example-3.svg", 500);
return mesh.Triangles.Count > 0; return mesh.Triangles.Count > 0;
} }
+3 -3
View File
@@ -10,14 +10,14 @@ namespace TriangleNet.Examples
/// <summary> /// <summary>
/// Triangulate a polygon with hole with maximum area constraint, followed by mesh smoothing. /// Triangulate a polygon with hole with maximum area constraint, followed by mesh smoothing.
/// </summary> /// </summary>
public class Example3 public class Example4
{ {
public static bool Run(bool print = false) public static bool Run(bool print = false)
{ {
// Generate mesh. // Generate mesh.
var mesh = CreateMesh(); var mesh = CreateMesh();
if (print) SvgImage.Save(mesh, "example-3.svg", 500); if (print) SvgImage.Save(mesh, "example-4.svg", 500);
return mesh.Triangles.Count > 0; return mesh.Triangles.Count > 0;
} }
@@ -25,7 +25,7 @@ namespace TriangleNet.Examples
public static IMesh CreateMesh() public static IMesh CreateMesh()
{ {
// Generate the input geometry. // Generate the input geometry.
var poly = Example2.CreatePolygon(); var poly = Example3.CreatePolygon();
// Since we want to do CVT smoothing, ensure that the mesh // Since we want to do CVT smoothing, ensure that the mesh
// is conforming Delaunay. // is conforming Delaunay.
+2 -2
View File
@@ -10,7 +10,7 @@ namespace TriangleNet.Examples
/// <summary> /// <summary>
/// Refine only a part of a polygon mesh by using region pointers and an area constraint. /// Refine only a part of a polygon mesh by using region pointers and an area constraint.
/// </summary> /// </summary>
public class Example4 public class Example5
{ {
public static bool Run(bool print = false) public static bool Run(bool print = false)
{ {
@@ -41,7 +41,7 @@ namespace TriangleNet.Examples
smoother.Smooth(mesh, 5); smoother.Smooth(mesh, 5);
if (print) SvgImage.Save(mesh, "example-4.svg", 500); if (print) SvgImage.Save(mesh, "example-5.svg", 500);
return mesh.Triangles.Count > 0; return mesh.Triangles.Count > 0;
} }
+4 -4
View File
@@ -11,19 +11,19 @@ namespace TriangleNet.Examples
/// <summary> /// <summary>
/// Two ways finding boundary triangles. /// Two ways finding boundary triangles.
/// </summary> /// </summary>
public static class Example5 public static class Example6
{ {
public static bool Run(bool print = false) public static bool Run(bool print = false)
{ {
var mesh = Example3.CreateMesh(); var mesh = Example4.CreateMesh();
FindBoundary1(mesh); FindBoundary1(mesh);
if (print) SvgImage.Save(mesh, "example-5-1.svg", 500, true, false); if (print) SvgImage.Save(mesh, "example-6-1.svg", 500, true, false);
FindBoundary2(mesh); FindBoundary2(mesh);
if (print) SvgImage.Save(mesh, "example-5-2.svg", 500, true, false); if (print) SvgImage.Save(mesh, "example-6-2.svg", 500, true, false);
return mesh.Triangles.Count > 0; return mesh.Triangles.Count > 0;
} }
+2 -2
View File
@@ -11,7 +11,7 @@
/// <summary> /// <summary>
/// Boolean operations on mesh regions (intersection, difference, xor). /// Boolean operations on mesh regions (intersection, difference, xor).
/// </summary> /// </summary>
public static class Example6 public static class Example7
{ {
public static bool Run(bool print = false) public static bool Run(bool print = false)
{ {
@@ -28,7 +28,7 @@
// Generate mesh. // Generate mesh.
var mesh = (Mesh)polygon.Triangulate(); var mesh = (Mesh)polygon.Triangulate();
if (print) SvgImage.Save(mesh, "example-6.svg", 500); if (print) SvgImage.Save(mesh, "example-7.svg", 500);
// Find a seeding triangle (in this case, the point (2, 2) lies in // Find a seeding triangle (in this case, the point (2, 2) lies in
// both rectangles). // both rectangles).
+2 -2
View File
@@ -10,7 +10,7 @@ namespace TriangleNet.Examples
/// <summary> /// <summary>
/// Using a user test function to define a maximum edge length constraint. /// Using a user test function to define a maximum edge length constraint.
/// </summary> /// </summary>
public static class Example7 public static class Example8
{ {
const double MAX_EDGE_LENGTH = 0.2; const double MAX_EDGE_LENGTH = 0.2;
@@ -41,7 +41,7 @@ namespace TriangleNet.Examples
} }
} }
if (print) SvgImage.Save(mesh, "example-7.svg", 500); if (print) SvgImage.Save(mesh, "example-8.svg", 500);
return true; return true;
} }
+2 -2
View File
@@ -10,11 +10,11 @@ namespace TriangleNet.Examples
/// <summary> /// <summary>
/// Compute the adjacency matrix of the mesh vertices. /// Compute the adjacency matrix of the mesh vertices.
/// </summary> /// </summary>
public class Example8 public class Example9
{ {
public static bool Run() public static bool Run()
{ {
var mesh = (Mesh)Example3.CreateMesh(); var mesh = (Mesh)Example4.CreateMesh();
return FindAdjacencyMatrix(mesh); return FindAdjacencyMatrix(mesh);
} }
+1
View File
@@ -18,6 +18,7 @@ namespace TriangleNet
Check("Example 8", Example8.Run()); Check("Example 8", Example8.Run());
Check("Example 9", Example9.Run()); Check("Example 9", Example9.Run());
Check("Example 10", Example10.Run()); Check("Example 10", Example10.Run());
Check("Example 11", Example10.Run());
} }
static void Check(string item, bool success) static void Check(string item, bool success)