Convex Hulls
Definition and Properties
The convex hull of a point set is the smallest convex set containing , equivalently the intersection of all convex sets containing , or the set of all convex combinations with .
For finite point sets in , the convex hull is a convex polygon whose vertices are a subset of (the extreme points). Points on the hull boundary but not at vertices are non-extreme hull points.
Lower bound: computing the convex hull of points in requires in the algebraic decision tree model (via reduction from sorting). However, if = number of hull vertices, output-sensitive algorithms can achieve .
Graham Scan
Algorithm (Graham, 1972):
- Find the lowest point (leftmost if tie)
- Sort remaining points by polar angle around
- Process points in order, maintaining a stack representing the current hull:
- For each point : while the last two stack points and make a non-left turn, pop the stack
- Push
Correctness: the stack invariant ensures that the sequence of points on the stack always forms the vertices of a convex polygon in counterclockwise order.
Complexity: for sorting; the scan itself is (each point is pushed and popped at most once, amortized).
Degeneracy handling: collinear points during the angle sort must be handled carefully. Points at the same angle should be sorted by distance from ; the farthest collinear point on the last angular group should be processed last.
Andrew's Monotone Chain
Algorithm (Andrew, 1979):
- Sort points lexicographically (by , breaking ties by )
- Build upper hull: scan left to right, maintaining convexity (clockwise turns)
- Build lower hull: scan left to right, maintaining convexity (counterclockwise turns)
- Concatenate upper and lower hulls
Advantages over Graham scan:
- No trigonometric functions (uses only cross products)
- Numerically more stable
- Handles collinear points more naturally
- Simple implementation; the preferred algorithm in competitive programming
upper = []
for p in sorted_points:
while len(upper) >= 2 and cross(upper[-2], upper[-1], p) >= 0:
upper.pop()
upper.append(p)
lower = []
for p in sorted_points:
while len(lower) >= 2 and cross(lower[-2], lower[-1], p) <= 0:
lower.pop()
lower.append(p)
hull = upper + lower[1:-1]
Jarvis March (Gift Wrapping)
Algorithm (Jarvis, 1973): where = hull size
- Start from the lowest point (guaranteed on hull)
- At each hull vertex, find the point making the smallest counterclockwise angle with the current edge direction
- Continue until returning to the start
Each step requires to find the next hull vertex (linear scan of all points, selecting the one that is most clockwise). Total steps.
Output-sensitive: . Optimal when or but poor when . Can be viewed as the selection-based analog where Graham scan is the sorting-based analog.
Quickhull
Algorithm (Barber, Dobkin, Huhdanpaa, 1996): divide-and-conquer, expected
- Find leftmost and rightmost points; they divide the set into "above" and "below" subsets
- For each subset, find the point farthest from the dividing line (this point must be on the hull)
- The farthest point divides the subset into two smaller subsets; recurse
Analysis: worst case (similar to quicksort); expected for many distributions. In practice, often the fastest algorithm due to excellent cache behavior and early elimination of interior points.
Qhull library: the standard implementation, handles arbitrary dimensions. Uses Quickhull with automatic convexity verification and facet merging for numerical robustness.
Chan's Algorithm
Algorithm (Chan, 1996): --- optimal output-sensitive
Combines Jarvis march with a grouping trick:
- Guess for (doubling strategy)
- Partition points into groups of size
- Compute convex hull of each group using Graham scan: per group, total
- Run Jarvis march, but at each step, find the tangent to each group's hull in via binary search. Total: per Jarvis step, steps max
- If Jarvis completes within steps, done. Otherwise, double and restart
Total cost: . The doubling strategy ensures we don't overshoot by more than a constant factor. The geometric growth ensures total work across all rounds is .
3D Convex Hull
Output: a convex polytope with vertices, edges, and faces. By Euler's formula, if vertices then edges and faces.
Algorithms:
- Incremental: add points one by one, maintaining the hull. For each new point, find visible facets (orientation test in 3D), remove them, and create new facets. Expected for random order; worst case
- Divide and conquer: . Split by median, recursively compute hulls, merge. Merge step finds the "bridge" edges and wraps around
- Randomized incremental: expected. Conflict lists maintain which uninserted points can "see" each facet. Clarkson-Shor framework
- Chan's algorithm extends: in 3D as well
The beneath-beyond algorithm: for each new point, test visibility of each facet. A facet is visible from if (assuming outward-facing normals). Delete visible facets and fill the horizon with new triangles.
CGAL, Qhull: standard implementations handle degeneracies via exact arithmetic or symbolic perturbation.
Higher-Dimensional Convex Hulls
In , the complexity of the convex hull of points can be (upper bound theorem). Algorithms:
- Beneath-beyond: , optimal in even dimensions
- Gift wrapping: generalizes but is where is number of facets
- Reverse search (Avis-Fukuda): polynomial delay per facet, low memory
For , the connection to Delaunay triangulation breaks (Delaunay in = convex hull in of lifted points).
Dynamic Convex Hull
Maintain the convex hull under insertions and/or deletions of points.
Semi-online (insertions only):
- amortized per insertion using balanced BST of hull edges (Preparata, 1979)
- Store upper and lower hulls in separate trees, supporting tangent queries
Fully dynamic (insertions and deletions):
- per operation (Overmars-van Leeuwen, 1981): maintain the hull in two balanced trees (upper and lower). Deletion requires finding the replacement edges
- amortized per operation (Chan, 2001) via a more sophisticated approach
Kinetic convex hull: points move along known trajectories. Maintain a kinetic data structure (KDS) with certificates that detect when the hull topology changes. Processing events maintains the hull over time.
Applications
- Collision detection: two convex objects don't collide iff their Minkowski difference's convex hull doesn't contain the origin (GJK algorithm)
- Linear programming in 2D: the feasible region is a convex polygon; optimize via hull computation or Seidel's randomized
- Smallest enclosing circle/rectangle: related to convex hull; optimal solutions touch hull vertices
- Diameter and width: the diameter (farthest pair) can be computed in from the hull using rotating calipers (Shamos, 1978). Similarly for width (minimum distance between parallel supporting lines)
- Shape analysis: convexity defects (deviations from hull) characterize shape features
Rotating Calipers
A powerful technique on convex hulls. Maintain two parallel supporting lines (the "calipers") and rotate them around the hull:
- Diameter: --- farthest pair is always antipodal
- Width: --- minimum over all directions
- Minimum enclosing rectangle: --- one side flush with a hull edge
- Maximum distance between two convex polygons:
- Minkowski sum of two convex polygons:
- Onion peeling: repeatedly compute and remove the hull. Total ; depth is for random point sets
Lower Bound and Reductions
Sorting reduces to convex hull: given numbers , map to points on a parabola. The hull in order gives the sorted sequence. Hence in the algebraic decision tree model.
Convex hull reduces to sorting (in 2D): the algorithms essentially sort by angle or coordinate. This tight connection means the hull problem is in the comparison model, but output-sensitive algorithms bypass this by exploiting that may be much smaller than .
For integer coordinates bounded by , the sorting step can use integer sorting, achieving or even with advanced integer sorting.