Problem: Compute a conforming Delaunay triangulation of a set of boundaries and constraints
A 2d conforming Delaunay triangulation (CDT) is a true Delaunay triangulation in which each boundary or constraint may have been subdivided into several edges by the insertion of additional points. This allows the edges to exist in the triangulation while maintaining the Delaunay property.
A CDT must contain at least one of the following items:
- An arbitrary number of triangulation points, which will be vertices of the triangles in the CDT.
- An arbitrary number of unordered open or closed edges, called constraints, whose start and end points will be vertices of the triangles in the CDT. No edge of a triangle will cross a constraint. This is achieved by inserting additional triangulation points.
- An arbitrary number of unordered edges defining closed regions, called boundaries, whose start and end points will be vertices of the triangles in the CDT. No edge will cross a boundary. Boundaries allow for defining holes or islands in a triangulation by removing triangles with a simple ray tracing algorithm.
Restrictions:
- A CDT can not triangulate points, constraints or boundaries with identical X and Y coordinates. This is, vertical or recessing walls or "caves" can not be triangulated.
- Intersecting constraints and/or boundaries will cause unpredictable results at the intersection points.
- The boundary edges must define an arbitrary number of closed regions or the ray tracing algorithm will fail.
The algorithm does not recheck if the boundaries or constraints intersect, nor does it recheck if the boundaries define closed regions.
Click here for more details on the implemented triangulation algorithm, valid input data and restrictions.
The following example is a CDT of the Chiemsee lake in Bavaria. It has the two islands Herrenchiemsee and Frauenchiemsee. You can download the edges forming the lake and the islands here.
Solution using G#
- public static void ConformingDelaunay()
- {
- Global.AbsoluteEpsilon = 1e-6;
- //-----------------------------------------------------------------
- //Triangulate the gound area
- //-----------------------------------------------------------------
- ConformingDelaunayTriangulation2d ground =
- //Four points encompassing all boundaries
- //The four outer boundary edges
- ground.Boundaries.Add(
- new Constraint(
- Constraint.ConstraintType.Boundary));
- ground.Boundaries.Add(
- new Constraint(
- Constraint.ConstraintType.Boundary));
- ground.Boundaries.Add(
- new Constraint(
- Constraint.ConstraintType.Boundary));
- ground.Boundaries.Add(
- new Constraint(
- Constraint.ConstraintType.Boundary));
- //The lake with its islands
- ground.Boundaries.AddRange(
- ConvertToConstraint(
- Chiemsee.Lake(),
- Constraint.ConstraintType.Boundary)); //The lake
- ground.Boundaries.AddRange(
- ConvertToConstraint(
- Chiemsee.HerrenChiemsee(),
- Constraint.ConstraintType.Boundary)); //Herrenchiemsee island
- ground.Boundaries.AddRange(
- ConvertToConstraint(
- Chiemsee.FrauenChiemsee(),
- Constraint.ConstraintType.Boundary)); //Frauenchiemsee island
- ground.Triangulate();
- //-----------------------------------------------------------------
- //Triangulate the water area
- //-----------------------------------------------------------------
- ConformingDelaunayTriangulation2d water =
- //Four points encompassing all boundaries
- //The lake with its islands
- water.Boundaries.AddRange(
- ConvertToConstraint(
- Chiemsee.Lake(),
- Constraint.ConstraintType.Boundary)); //The lake
- water.Boundaries.AddRange(
- ConvertToConstraint(
- Chiemsee.HerrenChiemsee(),
- Constraint.ConstraintType.Boundary)); //Herrenchiemsee island
- water.Boundaries.AddRange(
- ConvertToConstraint(
- Chiemsee.FrauenChiemsee(),
- Constraint.ConstraintType.Boundary)); //Frauenchiemsee island
- water.Triangulate();
- //-----------------------------------------------------------------
- //Visualize ground and water
- //-----------------------------------------------------------------
- sc.Add(ground.GetTriangles(), groundLayer);
- sc.Add(water.GetTriangles(), waterLayer);
- sc.Add(Constraint.GetEdges(ground.Constraints), boundaryLayer);
- sc.Add(Constraint.GetEdges(ground.Boundaries), boundaryLayer);
- sc.WriteDxf(@"e:\conforming_delaunay.dxf");
- Console.WriteLine("Done!");
- Console.ReadLine();
- }
- /// <summary>A helper method to convert edges into constraints.</summary>
- /// <param name="edges">A list of edges</param>
- /// <param name="type">The desired constraint type.</param>
- /// <returns>Returns a list of constraints.</returns>
- public static List<Constraint> ConvertToConstraint(List<Edge> edges, Constraint.ConstraintType type)
- {
- for (int i = 0; i < edges.Count; i++)
- {
- }
- return constraints;
- }




