Graham's Scan
Algorithm
Graham’s scan computes the convex hull in time. It works by sorting points radially from a reference point and then building the hull incrementally using a stack.
Steps
-
Find anchor point : Choose the point with the lowest -coordinate (break ties by choosing the leftmost, i.e. smallest ). This point is guaranteed to be on the hull.
-
Sort remaining points: Sort the remaining points by polar angle around , measured from the positive -axis (horizontal line to the right). If two points have the same angle, keep only the one furthest from (the closer one is interior to the hull edge).
-
Build the hull: Use a stack.
- Push , then , then (the first three points in sorted order).
- For each remaining point in sorted order:
- While the last two points on the stack (let’s call them
topandnext-to-top) and make a non-left turn (i.e. a right turn or collinear), pop the stack. - Push .
- While the last two points on the stack (let’s call them
- After processing all points, the stack contains the hull vertices in CCW order.
Non-Left Turn Detection
Use the cross product. For points (next-to-top), (top), (new point):
If the cross product is (right turn or collinear), pop .
Why No Trigonometry?
Sorting by polar angle does not require computing angles. Since all points (except ) are in the half-plane above or to the right of , the polar angle satisfies . Use the cross product as comparator:
For points and (both ), comes before in polar angle order iff:
If the cross product is , they are collinear; keep the further point.
Worked Example
Points: , , , , , .
Step 1: Anchor (lowest , leftmost for ).
Step 2: Sort by polar angle from :
- : angle
- : angle
- : angle
- : angle
- : angle
Sorted order (by cross product): , , , , .
Step 3: Stack trace.
| Iteration | Point | Stack before | Pop? | Stack after |
|---|---|---|---|---|
| Init | — | [] | — | [P0] |
| 1 | (4,0) | [P0] | — | [P0, (4,0)] |
| 2 | (2,1) | [P0, (4,0)] | — | [P0, (4,0), (2,1)] |
| 3 | (4,3) | [P0, (4,0), (2,1)] | Check (4,0)→(2,1)→(4,3) |
Compute for iteration 3: ? No — use the correct direction.
Let’s check turn from stack: , , .
Right turn → pop B = (2,1). Stack becomes [P0, (4,0)].
Now check: , , .
Left turn → push (4,3). Stack: [P0, (4,0), (4,3)].
| 4 | (1,4) | [P0, (4,0), (4,3)] | : cross → left turn, push.
| 5 | (0,3) | [P0, (4,0), (4,3), (1,4)] | : cross → left turn, push.
Hull: back to .
Complexity Analysis
- Finding :
- Sorting by polar angle: (dominates)
- Stack operations: each point pushed at most once, popped at most once →
Total: , dominated by sorting.
Handling Collinear Points
If multiple points are collinear on a hull edge, only the furthest points are kept (the intermediate points are not vertices of the convex polygon). The sorting step handles this by removing closer collinear points, and the stack’s non-strict-left-turn check () removes intermediate collinear points found during processing.
Summary
| Step | Operation | Time |
|---|---|---|
| 1. Find anchor | Scan for min | |
| 2. Sort by polar angle | Cross product comparator | |
| 3. Build hull | Stack with turn check | |
| Total | — | |
| No trig? | Yes, cross products only | — |
| Hull output | CCW vertex list on stack | — |