|
| 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