|
| 1 | +#include <algorithm> |
| 2 | +#include <cmath> |
1 | 3 | #include <iostream> |
2 | 4 | #include <vector> |
3 | | -#include <algorithm> |
4 | 5 |
|
5 | | -struct point{ |
| 6 | +struct point { |
6 | 7 | double x; |
7 | 8 | double y; |
8 | 9 | }; |
9 | 10 |
|
10 | | -bool ccw(point a, point b, point c){ |
11 | | - return ((b.x - a.x)*(c.y - a.y) > (b.y - a.y)*(c.x - a.x)); |
| 11 | +std::ostream& operator<<(std::ostream& os, const std::vector<point>& points) { |
| 12 | + for (auto p : points) { |
| 13 | + os << "(" << p.x << ", " << p.y << ")\n"; |
| 14 | + } |
| 15 | + return os; |
| 16 | +} |
| 17 | + |
| 18 | +double ccw(const point& a, const point& b, const point& c) { |
| 19 | + return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); |
12 | 20 | } |
13 | 21 |
|
14 | | -std::vector<point> grahamScan(std::vector<point> points){ |
15 | | - //selecting lowest point as pivot |
16 | | - int lowIndex = 0; |
17 | | - for(size_t i = 1; i < points.size(); i++) { |
18 | | - if(points[i].y < points[lowIndex].y){ |
19 | | - lowIndex = i; |
| 22 | +double polar_angle(const point& origin, const point& p) { |
| 23 | + return std::atan2(p.y - origin.y, p.x - origin.x); |
| 24 | +} |
| 25 | + |
| 26 | +std::vector<point> graham_scan(std::vector<point>& points) { |
| 27 | + // selecting lowest point as pivot |
| 28 | + size_t low_index = 0; |
| 29 | + for (size_t i = 1; i < points.size(); i++) { |
| 30 | + if (points[i].y < points[low_index].y) { |
| 31 | + low_index = i; |
20 | 32 | } |
21 | 33 | } |
22 | | - std::swap(points[0], points[lowIndex]); |
| 34 | + std::swap(points[0], points[low_index]); |
23 | 35 | point pivot = points[0]; |
24 | 36 |
|
25 | | - //sorting points by polar angle |
26 | | - std::sort(points.begin()+1, points.end(), [pivot](point a, point b){ |
27 | | - return ccw(pivot, a, b); |
28 | | - }); |
| 37 | + // sorting points by polar angle |
| 38 | + std::sort( |
| 39 | + points.begin() + 1, |
| 40 | + points.end(), |
| 41 | + [&pivot](const point& pa, const point& pb) { |
| 42 | + return polar_angle(pivot, pa) < polar_angle(pivot, pb); |
| 43 | + }); |
29 | 44 |
|
30 | | - //creating convex hull |
| 45 | + // creating convex hull |
31 | 46 | size_t m = 1; |
32 | | - for(size_t i = 2; i < points.size(); i++) { |
33 | | - while(ccw(points[m - 1], points[m], points[i]) <= 0){ |
34 | | - if(m > 1) { |
35 | | - m--; |
36 | | - continue; |
37 | | - } else if(i == points.size()) { |
38 | | - break; |
39 | | - } else { |
40 | | - i++; |
41 | | - } |
| 47 | + for (size_t i = 2; i < points.size(); i++) { |
| 48 | + while (ccw(points[m - 1], points[m], points[i]) <= 0) { |
| 49 | + if (m > 1) { |
| 50 | + m--; |
| 51 | + continue; |
| 52 | + } else if (i == points.size()) { |
| 53 | + break; |
| 54 | + } else { |
| 55 | + i++; |
| 56 | + } |
42 | 57 | } |
43 | 58 | m++; |
44 | 59 | std::swap(points[i], points[m]); |
45 | 60 | } |
46 | 61 | return std::vector<point>(points.begin(), points.begin() + m + 1); |
47 | 62 | } |
48 | 63 |
|
49 | | -void print(std::vector<point> points){ |
50 | | - for ( auto p : points){ |
51 | | - std::cout <<"(" << p.x << ", " << p.y <<")\n"; |
52 | | - } |
53 | | -} |
54 | | - |
55 | | -int main(){ |
56 | | - std::vector<point> points = {{-5, 2}, {5, 7}, {-6, -12}, {-14, -14}, {9, 9}, |
57 | | - {-1, -1}, {-10, 11}, {-6, 15}, {-6, -8}, {15, -9}, |
58 | | - {7, -7}, {-2, -9}, {6, -5}, {0, 14}, {2, 8}}; |
59 | | - std::cout << "original points are as follows:\n"; |
60 | | - print(points); |
61 | | - std::vector<point> hull = grahamScan(points); |
62 | | - std::cout << "points in hull are as follows:\n"; |
63 | | - print(hull); |
| 64 | +int main() { |
| 65 | + std::vector<point> points = {{-5, 2}, |
| 66 | + {5, 7}, |
| 67 | + {-6, -12}, |
| 68 | + {-14, -14}, |
| 69 | + {9, 9}, |
| 70 | + {-1, -1}, |
| 71 | + {-10, 11}, |
| 72 | + {-6, 15}, |
| 73 | + {-6, -8}, |
| 74 | + {15, -9}, |
| 75 | + {7, -7}, |
| 76 | + {-2, -9}, |
| 77 | + {6, -5}, |
| 78 | + {0, 14}, |
| 79 | + {2, 8}}; |
| 80 | + std::cout << "original points are as follows:\n" << points; |
| 81 | + const std::vector<point> hull = graham_scan(points); |
| 82 | + std::cout << "points in hull are as follows:\n" << hull; |
64 | 83 | return 0; |
65 | 84 | } |
0 commit comments