AlgoPlus v0.1.0
Loading...
Searching...
No Matches
convex_hull.h
1#ifndef CONVEX_HULL_H
2#define CONVEX_HULL_H
3
4#include <cmath>
5#ifdef __cplusplus
6#include <algorithm>
7#include <iostream>
8#include <stack>
9#include <vector>
10#endif
11
12namespace helpers {
22int orientation(const std::pair<int, int> a, const std::pair<int, int> b,
23 const std::pair<int, int> c) {
24 double v = a.first * (b.second - c.second) + b.first * (c.second - a.second) +
25 c.first * (a.second - b.second);
26 if (v < 0) {
27 return -1;
28 }
29 if (v > 0) {
30 return 1;
31 }
32 return 0;
33}
34}; // namespace helpers
35
36std::vector<std::pair<int, int>> graham_scan(std::vector<std::pair<int, int>> points,
37 bool include_first_twice = true) {
38 // find the leftmost and downmost point
39 std::pair<int, int> p0 = *min_element(
40 points.begin(), points.end(), [](std::pair<int, int> a, std::pair<int, int> b) {
41 return std::make_pair(a.second, a.first) < std::make_pair(b.second, b.first);
42 });
43
44 // sort the points by their polar angle(anti-clockwise)
45 std::sort(points.begin(), points.end(),
46 [&](const std::pair<int, int> a, const std::pair<int, int> b) {
47 int ori = helpers::orientation(p0, a, b);
48 if (ori == 0) {
49 return (p0.first - a.first) * (p0.first - a.first) +
50 (p0.second - a.second) * (p0.second - a.second) <
51 (p0.first - b.first) * (p0.first - b.first) +
52 (p0.second - b.second) * (p0.second - b.second);
53 }
54 return ori > 0;
55 });
56
57 std::vector<std::pair<int, int>> s;
58 for (const auto& point : points) {
59 while (s.size() > 1 && helpers::orientation(s[s.size() - 2], s.back(), point) <= 0) {
60 s.pop_back();
61 }
62 s.push_back(point);
63 }
64
65 if (include_first_twice) {
66 s.push_back(p0); // push back the starting point again
67 }
68 return s;
69}
70
71#endif