public void TestEquilateralTriangles() { double sqrt3 = Math.Sqrt(3); var vertices = new List <Vertex>() { new Vertex(0.0, 0.0) { ID = 0 }, new Vertex(1.0, sqrt3) { ID = 1 }, new Vertex(2.0, 0.0) { ID = 2 }, new Vertex(3.0, sqrt3) { ID = 3 } }; var mesh = new Dwyer().Triangulate(vertices, new Configuration()); var quality = new QualityMeasure(mesh); Assert.AreEqual(quality.AreaMinimum, quality.AreaMaximum); Assert.AreEqual(1.0, quality.AlphaMinimum); Assert.AreEqual(1.0, quality.AlphaMaximum); Assert.AreEqual(1.0, quality.Q_Minimum); Assert.AreEqual(1.0, quality.Q_Maximum); }
public void TestTriangulateDwyer() { var t = new Dwyer(); var vertices = GetVertices(); var mesh = t.Triangulate(vertices, new Configuration()); Assert.AreEqual(6, vertices.Count); Assert.AreEqual(6, mesh.Vertices.Count); Assert.AreEqual(1, mesh.Vertices .Where(v => v.Type == VertexType.UndeadVertex) .Count()); }
public static bool Run(bool print = false) { // Generate points. var points = Generate.RandomPoints(50, new Rectangle(0, 0, 100, 100)); // Choose triangulator: Incremental, SweepLine or Dwyer. var triangulator = new Dwyer(); // Generate mesh. var mesh = triangulator.Triangulate(points, new Configuration()); if (print) { SvgImage.Save(mesh, "example-1.svg", 500); } return(mesh.Triangles.Count > 0); }
public void TestInterpolatePoint() { var vertices = new List <Vertex>() { new Vertex(0.0, 0.0) { ID = 0 }, new Vertex(2.0, 0.0) { ID = 1 }, new Vertex(0.5, 1.0) { ID = 2 } }; // The z-values. var values = new double[] { 1d, -1d, 2d }; var mesh = new Dwyer().Triangulate(vertices, new Configuration()); var tri = mesh.Triangles.First(); // Check the corners. double actual, expected; for (int i = 0; i < 3; i++) { actual = Interpolation.InterpolatePoint(tri, vertices[i], values); expected = values[i]; Assert.AreEqual(expected, actual); } // Check the edge midpoints. double x, y; for (int i = 0; i < 3; i++) { x = (vertices[i].X + vertices[(i + 1) % 3].X) / 2; y = (vertices[i].Y + vertices[(i + 1) % 3].Y) / 2; var p = new Point(x, y); actual = Interpolation.InterpolatePoint(tri, p, values); expected = (values[i] + values[(i + 1) % 3]) / 2; Assert.AreEqual(expected, actual); } // Check centroid. x = (vertices[0].X + vertices[1].X + vertices[2].X) / 3; y = (vertices[0].Y + vertices[1].Y + vertices[2].Y) / 3; actual = Interpolation.InterpolatePoint(tri, new Point(x, y), values); expected = (values[0] + values[1] + values[2]) / 3; Assert.AreEqual(expected, actual); }
/// <summary> /// Triangulate a given number of random point sets in parallel. /// </summary> public static bool Run(int n = 1000) { // Use thread-safe random source. var random = Random.Shared; // Generate a random set of sizes. var sizes = Enumerable.Range(0, n).Select(_ => random.Next(500, 5000)); var queue = new ConcurrentQueue <int>(sizes); int concurrencyLevel = Environment.ProcessorCount / 2; var tasks = new Task <MeshResult> [concurrencyLevel]; for (int i = 0; i < concurrencyLevel; i++) { tasks[i] = Task.Run(() => { // Each task has it's own triangle pool and predicates instance. var pool = new TrianglePool(); var predicates = new RobustPredicates(); // The factory methods return the above instances. var config = new Configuration() { Predicates = () => predicates, TrianglePool = () => pool.Restart(), RandomSource = () => Random.Shared }; var triangulator = new Dwyer(); var result = new MeshResult(); var bounds = new Rectangle(0d, 0d, 1000d, 1000d); while (queue.Count > 0) { if (queue.TryDequeue(out int size)) { var points = Generate.RandomPoints(size, bounds); var mesh = triangulator.Triangulate(points, config); ProcessMesh(mesh, result); } } pool.Clear(); return(result); }); } Task.WaitAll(tasks); int numberOfTriangles = tasks.Sum(t => t.Result.NumberOfTriangles); int invalid = tasks.Sum(t => t.Result.Invalid); Console.WriteLine("Total number of triangles processed: {0}", numberOfTriangles); if (invalid > 0) { Console.WriteLine(" Number of invalid triangulations: {0}", invalid); } return(invalid == 0); }