diff --git a/geometry/convex_hull.cc b/geometry/convex_hull.cc new file mode 100644 index 0000000..dffc9c8 --- /dev/null +++ b/geometry/convex_hull.cc @@ -0,0 +1,38 @@ +struct convex_hull { + int n, m; + vector on_hull; + // WARN: counter-clockwise + vector hull; + + // WARN: sort the points before initializing + template + convex_hull(const vector>& a) : n(a.size()), on_hull(n) { + for (int i = 0; i < n; ++i) { + int m = hull.size(); + // WARN: keeping the points that are on edges + while (m > 1 and (a[hull[m - 1]] - a[hull[m - 2]]) * (a[i] - a[hull[m - 2]]) < 0) { + on_hull[hull[m - 1]] -= 1; + hull.pop_back(); + m -= 1; + } + on_hull[i] += 1; + hull.emplace_back(i); + } + int low = hull.size(); + + for (int i = n - 2; ~i; --i) { + int m = hull.size(); + while (m > low and (a[hull[m - 1]] - a[hull[m - 2]]) * (a[i] - a[hull[m - 2]]) < 0) { + on_hull[hull[m - 1]] -= 1; + hull.pop_back(); + m -= 1; + } + on_hull[i] += 1; + hull.emplace_back(i); + } + if (n > 1) { + hull.pop_back(); + } + m = hull.size(); + } +};