Convex Hull
The convex hull is the smallest convex polygon enclosing a point set — the rubber band snapped around the nails. We build it with Andrew's monotone chain, sorting by and sweeping a lower and upper hull while popping any non-left turn via the orientation primitive, in .
╌╌╌╌
The previous lesson gave us one operation: the orientation of an ordered triple of points , read off the sign of the cross product
A positive value means turns counterclockwise (a left turn), a negative value means clockwise (a right turn), and zero means the three points are collinear. That one branch-free, multiplication-only test, with no divisions, no square roots, and no angles, is the only geometric primitive this lesson needs. We now use it to solve the foundational problem of computational geometry: given points in the plane, find their convex hull.
The problem
The mental picture is exact and worth keeping: hammer a nail into the plane at each point, stretch a rubber band wide enough to enclose them all, and let go. The band snaps taut around the outermost points and traces the hull; the points it touches are the hull vertices, and everything else lands strictly inside.
A hull algorithm must report the vertices in boundary order (say counterclockwise). The naive approaches are slow: testing each ordered pair to see whether all other points lie on one side of the line through it identifies hull edges in ; gift-wrapping (Jarvis march) pivots from one hull vertex to the next in time, where is the number of hull vertices, good when the hull is tiny but when every point is a vertex. We can do better, and provably best, in .
Gift-wrapping is worth a concrete step, because it is the most literal statement
of what on the hull
means. Start at the guaranteed hull vertex the lowest
point, and pick the next vertex as the one that makes every other point fall
to the left of the ray — equivalently, is the most clockwise point
seen from . Take and candidates , , . To
choose between and , test :
is a right turn from , i.e. more clockwise, so beats . Testing
against gives ,
so is a left turn and still wins. After one full pass is the most
clockwise, so is the next hull vertex, and we wrap again from . Each vertex
costs a full pass, which is why the total is — cheap when the hull
is small, quadratic when every point is a corner.
Andrew's monotone chain
The cleanest algorithm sorts the points once and sweeps them with a stack, building the boundary in two passes.
The pop condition is pure orientation. Suppose the stack ends in and we are
about to add . If is a left turn (cross product ), is
a genuine corner of the hull-so-far and we keep it. If it is a right turn or
collinear (cross product ), then is inside
the corner that opens
up (the rubber band would not touch ), so we pop and re-test with the new
top. This is the rejection drawn below.
Here bends to the right, so the chain dips below the convex boundary at . The algorithm pops and the corrected edge runs straight from to , restoring the all-left-turns invariant.
Inside the left-to-right sweep this plays out as a stack that grows and occasionally collapses. Below, the stack holds when arrives; the turn at is a right turn, so pops, and now the turn at is still a right turn, so pops too, leaving the taut chain .
- 1sort ascending by , removing duplicates
- 2lower hull
- 3for each point in (left to right) do
- 4while and do
- 5pop
- 6push onto
- 7upper hull
- 8for each point in (right to left) do
- 9while and do
- 10pop
- 11push onto
- 12drop the last element of and ofshared endpoints
- 13return concatenated withcounterclockwise
Here denote the top two stack elements and is the orientation value above. The last point of each chain is the first point of the other (the global min and max under the sort order), so we drop one copy of each to avoid duplicating the two extreme vertices.
A worked lower-hull sweep. Take the six points
, , , , , , already sorted by .
The left-to-right sweep builds the lower chain as a stack; each row is the
stack after processing one point, with the cross test that fired.
| point | test at the top two | action | stack |
|---|---|---|---|
| — | push | ||
| — | push | ||
| pop , push | |||
| push | |||
| , then | pop , pop , push | ||
| push |
The lower hull is : the sweep discarded (a right turn at ), kept tentatively, then evicted both when arrived and the chain straightened. The upper-hull pass runs the mirror sweep right to left and closes the polygon.
Complexity. The sort costs . Each sweep is linear despite the
inner while: a point is pushed once and popped at most once, so the total number
of pop operations across a sweep is at most . The work after sorting is
therefore , and the sort dominates: overall.
Graham scan: the classic alternative
The original hull algorithm, Graham's scan, has the same skeleton but a different ordering. Pick the point with the lowest -coordinate (ties broken by ) as a pivot ; it is certainly a hull vertex. Sort the remaining points by polar angle around , then scan them in that angular order, maintaining a stack and popping whenever the last three points fail to turn left, the identical orientation test. Because the points are visited in angular order, one pass suffices to trace the whole boundary, again in .1
Monotone chain is usually preferred in practice precisely because it avoids the polar-angle sort: comparing lexicographically uses only the coordinates, whereas sorting by angle requires either (floating point, slow, imprecise) or cross-product comparisons with careful handling of the pivot, which means more code and more numerical fragility for the same asymptotics.
Degeneracies
Real inputs are not in general position,
and the hull is where edge cases bite.
- Duplicate points must be removed first (the sort makes this a linear scan); a repeated point can otherwise wedge a zero-length edge into the chain and break the turn test.
- Collinear points on a hull edge are a deliberate policy choice, and it lives entirely in the comparison operator. Using in the pop condition (as above) discards collinear points, keeping only true corners — the minimal vertex set. Using keeps collinear points on the boundary, so a flat edge with interior points reports all of them. Problems like Erect the Fence, which ask for every point lying on the fence, want the variant; most geometry that follows (diameter, area) wants the lean hull. Decide which one your caller needs and pick the inequality accordingly.
For example, suppose the bottom edge of the hull runs
through , , — three points on one horizontal line, with
strictly between the corners. When the sweep has on the stack and
arrives, . Under the
rule the zero triggers a pop, so is dropped and the edge is the single
segment — the lean hull with corners only. Under the strict
rule the zero does not pop, so stays and the boundary lists — every
point on the fence. The entire difference between corners
and on the boundary
is that one comparison.
A lower bound:
The running time is not an artifact of these particular algorithms. No comparison-based hull algorithm can beat it, by the same lower-bound argument that pins comparison sorting.
So monotone chain and Graham scan are asymptotically optimal: the sort they pay for is, in a precise sense, the same sort the problem itself requires.
What the hull is good for
The hull is rarely the final answer. It is a preprocessing step that collapses
messy points down to an ordered convex polygon of vertices, after
which many extremal
questions become easy. The key technique is rotating
calipers: walk two pointers around the hull in tandem, exploiting the fact that
as one supporting line rotates, the farthest or nearest vertex advances
monotonically.2 This computes the polygon diameter (the
farthest pair of points in the whole set, which must be two hull vertices) in
time after the hull, rather than the of checking all pairs.
The same caliper sweep yields the smallest enclosing rectangle (its optimal orientation always has a side flush with a hull edge), the width of the point set, and the convex layers (peel the hull, recurse on the interior). Whenever a problem cares only about the outermost shape of a point cloud (collision bounds, fitting, nearest-feature queries), computing the hull first is the standard first step.3
Output-sensitive and higher-dimensional hulls
The standard references give for the hull, and the parabola lower bound says that is optimal when the hull is reported in sorted order. But that lower bound applies only because the output is a sorted sequence of points. When the hull has just vertices, a lower cost should be possible. Two lines of work address exactly that.
Chan's algorithm (1996) resolves this: it computes the hull in , output-sensitive in the true hull size , which matches the lower bound for every and beats whenever the hull is small.4 The trick combines the two algorithms already in this lesson. Guess a bound on ; partition the points into groups of each and build each group's hull with Graham scan in , for total. Then run a gift-wrap over the group hulls, using binary search on each group hull to find its tangent in , so each wrap step costs and steps cost . Choosing makes both parts . Since is unknown, Chan runs the whole thing with (squaring the guess) and stops the first time the wrap completes within steps; the doubling search adds only a constant factor.
QuickHull is the practical divide-and-conquer analogue of quicksort. Take the two extreme- points; they split the set into points above and below the line between them. For the upper part, find the point farthest from that line — it is a hull vertex — and recurse on the two sub-lines it forms, discarding every point inside the triangle. Average performance is and it is very fast on typical inputs, but like quicksort it degrades to on adversarial sets where each split peels off only one point.5 QuickHull is what the widely used Qhull library implements, and it generalizes cleanly to three and higher dimensions, where the hull is a polytope with faces and the plane-sweep intuition of this module no longer applies.
Takeaways
- The convex hull is the smallest convex polygon enclosing a point set (the rubber band around the nails), and reporting it in boundary order is the foundational problem of planar computational geometry.
- Andrew's monotone chain sorts by , then sweeps a lower and upper hull, popping any vertex where the last three points fail to turn counterclockwise (cross product ). It is , dominated by the sort.
- The pop condition is the orientation primitive from the previous lesson: keep left turns, reject right turns and (by policy) collinear points.
- Graham scan achieves the same bound by sorting on polar angle; monotone chain avoids angle computation and is more numerically stable.
- Degeneracies, namely duplicates and collinear hull-edge points, are handled by deduplicating and by choosing (keep collinear) versus (drop them).
- Any hull algorithm is by reduction from sorting (lift points onto a parabola), so these algorithms are optimal.
- The hull is a preprocessing step: rotating calipers give the diameter, smallest enclosing rectangle, and width in once the hull is built.
Footnotes
- CLRS, Ch. 33 — Computational Geometry (§33.3): Graham's scan sorts by polar angle around the lowest point and maintains a stack of left turns, in . ↩
- Skiena, § — Convex Hull: the hull as the most basic geometric structure, with rotating calipers for farthest-pair and enclosing-shape queries. ↩
- CLRS, Ch. 33 — Computational Geometry (§33.3): the convex hull as a preprocessing primitive reducing points to an ordered convex polygon. ↩
- Timothy M. Chan,
Optimal output-sensitive convex hull algorithms in two and three dimensions,
Discrete & Computational Geometry 16(4), 1996 — the hull combining group Graham scans with a gift-wrap over group hulls and a doubling search on . ↩ - C. Bradford Barber, David P. Dobkin, and Hannu Huhdanpaa,
The Quickhull Algorithm for Convex Hulls,
ACM Transactions on Mathematical Software 22(4), 1996 — the divide-and-conquer QuickHull implemented in the Qhull library, extending to higher dimensions. ↩
╌╌ END ╌╌