Purpose: Build a Delaunay triangulation incrementally, in expected time with randomized insertion order ( worst case).
Delaunay triangulation
A triangulation in which no point lies inside the circumcircle of any triangle. Equivalently, it maximises the minimum angle over all triangulations β it avoids skinny triangles. Its dual is the Voronoi diagram.
Algorithm
- Start with a super-triangle large enough to contain every input point.
- Insert points one at a time (in random order). For each new point :
- find all triangles whose circumcircle contains β these are the βbadβ triangles;
- their union is a star-shaped cavity; collect its boundary edges (edges belonging to exactly one bad triangle);
- delete the bad triangles, and create one new triangle from to each boundary edge.
- At the end, delete every triangle touching a super-triangle vertex.
Code sketch
for (Point p : points) {
vector<int> bad;
for (int i = 0; i < (int)tri.size(); i++)
if (inCircumcircle(p, tri[i])) bad.push_back(i);
vector<Edge> boundary;
for (int i : bad)
for (Edge e : edgesOf(tri[i]))
if (countIn(bad, e) == 1) boundary.push_back(e); // not shared
removeAll(tri, bad);
for (Edge e : boundary) tri.push_back(Triangle{e.a, e.b, p});
}The key predicate
Everything rests on the in-circle test: is inside the circumcircle of (given counter-clockwise orientation)?
With integer coordinates up to this determinant reaches β well beyond long long and beyond doubleβs 53-bit mantissa. Use __int128 with reduced coordinate ranges, exact rational arithmetic, or adaptive-precision predicates (Shewchuk). Getting this predicate wrong is the single most common cause of a broken Delaunay implementation.
Complexity
- Expected: with randomized insertion and a point-location structure
- Naive (scan all triangles per insertion):
- Worst case with adversarial order:
- Space: β a planar triangulation has at most triangles
Delaunay construction methods
| Method | Time | Notes |
|---|---|---|
| Bowyer-Watson | expected | easiest to understand |
| Divide and conquer (Guibas-Stolfi) | worst case | quad-edge structure |
| Sweep line (Fortune) | see Fortuneβs algorithm | |
| Lift to 3D + convex hull | lift ; the lower hull is the Delaunay triangulation | |
| Flip algorithm | start from any triangulation, flip illegal edges |
The lifting method is the most elegant: Delaunay in 2D is exactly the lower convex hull of the points lifted onto a paraboloid in 3D. If you already have a 3D hull routine, you get Delaunay for free.
What Delaunay gives you
- Voronoi diagram β the dual graph, for free
- Euclidean MST β a subgraph of the Delaunay triangulation, so run Kruskal on edges instead of
- Nearest neighbour graph β also a subgraph
- Closest pair β the shortest Delaunay edge
- Largest empty circle, mesh generation, terrain interpolation
Variants / Use Cases
- Delaunay Triangulation β the topic page
- Fortuneβs algorithm β the sweep-line construction of the Voronoi dual
- Constrained Delaunay β force certain edges to appear (for polygon meshing)
- 3D Delaunay / tetrahedralisation β the same algorithm with circumspheres, worst case