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

  1. Start with a super-triangle large enough to contain every input point.
  2. 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.
  3. 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

MethodTimeNotes
Bowyer-Watson expectedeasiest to understand
Divide and conquer (Guibas-Stolfi) worst casequad-edge structure
Sweep line (Fortune)see Fortune’s algorithm
Lift to 3D + convex hulllift ; the lower hull is the Delaunay triangulation
Flip algorithmstart 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