Special case: 2-Dimensional space

Graham's Scan

  • First choose a trivial point
    p0
    that it must be in convex hull (leftmost and lowest).
  • sort all the other points in polar angle order, getting
    {p1,,pn}
    .
  • let
    s={p0,p1}={s2,s1}
    (reversed order).
  • let
    i=2
    .
  • while
    i<n
    do the following:
    If
    |s|<2
    or
    pis1s2
    is convex, then let
    s=s{pi}
    , and
    i=i+1
    .
    If not,
    s=s{s1}
    .
  • then
    s
    is a convex hull

Implementation Issue:

Polar angle sort may cause dividing by

0, or two points with the same tangent.

Optimizing: Monotone Chain

Divide the question into upper convex hull and lower convex hull,
and there are points at infinitely low and infinitely high respectively.
Then we don't really need to do polar angle sort, what we need is just sort by coordinate.

Implementation

vector<point> ConvexHull(vector<point>& pts) { int n = pts.size(); // lower monotone chain sort(pts.begin(), pts.end(), [](const point& a, const point& b){ return a.x == b.x ? a.y < b.y : a.x < b.x; }); vector<point> chain(1, pts[0]); for (int i = 1; i < n;) { int bk = chain.size() - 1; if (bk == 0 || (chain[bk] - chain[bk - 1]) ^ (pts[i] - chain[bk]) > 0) chain.push_back(pts[i++]); else chain.pop_back(); } // upper monotone chain vector<point> chain2(1, pts.back()); for (int i = n - 2; i >= 0;) { int bk = chain2.size() - 1; if (bk == 0 || (chain2[bk] - chain2[bk - 1]) ^ (pts[i] - chain2[bk]) > 0) chain2.push_back(pts[i--]); else chain2.pop_back(); } // remove duplicate points chain.pop_back(); chain2.pop_back(); // combine lower chain and upper chain to convex hull chain.insert(chain.end(), chain2.begin(), chain2.end()); return chain; }