Skip to main content

Incremental Delaunay Triangulation

The incremental algorithm builds the Delaunay triangulation of a point set PP by adding the points one at a time. After each insertion of a new point pp, every triangle whose circumcircle contains pp is illegal and must be removed; the cavity left behind is re-triangulated by connecting pp to each edge on the cavity boundary. When pp lies outside the current hull, the convex hull grows and new "phantom" triangles are added between pp and the visible hull edges.

A textbook clean-room trick to avoid special cases at the boundary is to start with one huge super-triangle that contains every input point, insert the real points into it, and at the end discard every triangle that still references a super-triangle vertex. The code below follows that recipe and keeps the implementation small by scanning the triangle list linearly on each insertion — the more sophisticated conflict graph of de Berg et al. brings the expected running time down to O(nlogn)O(n \log n).

Codes

def solve(xs):
points = xs[0]
n = len(points)
if n < 3:
return []

M = 0
for x, y in points:
M = max(M, abs(x), abs(y))
big = 10 * (M + 1)
p_super = [(-big, -big), (3 * big, -big), (-big, 3 * big)]
all_pts = list(points) + p_super
s0, s1, s2 = n, n + 1, n + 2
triangles = [(s0, s1, s2)]

def in_circle(a, b, c, d):
ax, ay = a[0]-d[0], a[1]-d[1]
bx, by = b[0]-d[0], b[1]-d[1]
cx, cy = c[0]-d[0], c[1]-d[1]
det = (ax*(by*(cx*cx+cy*cy) - cy*(bx*bx+by*by))
- ay*(bx*(cx*cx+cy*cy) - cx*(bx*bx+by*by))
+ (ax*ax+ay*ay)*(bx*cy - by*cx))
return det > 0

def orient(a, b, c):
return ((b[0]-a[0])*(c[1]-a[1]) - (b[1]-a[1])*(c[0]-a[0]))

def ccw(i, j, k):
if orient(all_pts[i], all_pts[j], all_pts[k]) >= 0:
return (i, j, k)
return (i, k, j)

for idx in range(n):
p = all_pts[idx]
bad = []
keep = []
for t in triangles:
a, b, c = all_pts[t[0]], all_pts[t[1]], all_pts[t[2]]
if orient(a, b, c) < 0:
a, b, c = all_pts[t[0]], all_pts[t[2]], all_pts[t[1]]
if in_circle(a, b, c, p):
bad.append(t)
else:
keep.append(t)

edges = {}
for t in bad:
for e in ((t[0], t[1]), (t[1], t[2]), (t[2], t[0])):
key = tuple(sorted(e))
edges[key] = edges.get(key, 0) + 1

triangles = keep
for (u, v), count in edges.items():
if count == 1:
triangles.append(ccw(u, v, idx))

result = []
for t in triangles:
if t[0] < n and t[1] < n and t[2] < n:
result.append(sorted(t))
result.sort()
return result

Example

Loading Python runner...

Description

Run time analysis

O(n2)O(n^2) in the worst case for this naive variant: each of the nn insertions scans the current triangle list, which has O(n)O(n) triangles. The randomized-insertion variant of de Berg et al. with a conflict graph improves the expected running time to O(nlogn)O(n \log n).

Space analysis

O(n)O(n). The triangulation of nn points in the plane has O(n)O(n) triangles, and the super-triangle adds three phantom vertices.

Proof of correctness

The super-triangle is chosen large enough that every real input point lies strictly inside it, so the initial triangulation is a valid Delaunay triangulation of the three super-triangle vertices. The insertion step preserves the empty-circle property by Lawson's theorem: removing all triangles whose circumcircles contain the new point pp produces a star-shaped cavity, and reconnecting pp to each boundary edge of the cavity yields a triangulation whose new triangles are all Delaunay with respect to the current set. Finally, discarding the triangles that touch super-triangle vertices leaves exactly the Delaunay triangulation of the real points. See de Berg et al., Chapter 9, for the full argument.

Extensions

Applications

References

  • de Berg, Cheong, van Kreveld, Overmars. Computational Geometry: Algorithms and Applications, 3rd ed., Chapter 9 (Delaunay Triangulations).
  • Guibas, Knuth, Sharir. "Randomized incremental construction of Delaunay and Voronoi diagrams." Algorithmica, 1992.
  • Bowyer, A. "Computing Dirichlet tessellations." The Computer Journal, 1981.
  • Watson, D. F. "Computing the nn-dimensional Delaunay tessellation with application to Voronoi polytopes." The Computer Journal, 1981.
  • cp-algorithms — Delaunay triangulation