From 367c0bef37a7b46168829197c19e9d3cb2ea8be7 Mon Sep 17 00:00:00 2001 From: subcrip Date: Sat, 9 Nov 2024 18:58:46 +0800 Subject: [PATCH] Add geometry/convex_hull.cc Signed-off-by: subcrip --- geometry/convex_hull.cc | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 geometry/convex_hull.cc 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(); + } +};