diff --git a/contents/graham_scan/code/c++/graham_scan.cpp b/contents/graham_scan/code/c++/graham_scan.cpp index 1e24b1bfe..c3da584fa 100644 --- a/contents/graham_scan/code/c++/graham_scan.cpp +++ b/contents/graham_scan/code/c++/graham_scan.cpp @@ -1,44 +1,59 @@ +#include +#include #include #include -#include -struct point{ +struct point { double x; double y; }; -bool ccw(point a, point b, point c){ - return ((b.x - a.x)*(c.y - a.y) > (b.y - a.y)*(c.x - a.x)); +std::ostream& operator<<(std::ostream& os, const std::vector& points) { + for (auto p : points) { + os << "(" << p.x << ", " << p.y << ")\n"; + } + return os; +} + +double ccw(const point& a, const point& b, const point& c) { + return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); } -std::vector grahamScan(std::vector points){ - //selecting lowest point as pivot - int lowIndex = 0; - for(size_t i = 1; i < points.size(); i++) { - if(points[i].y < points[lowIndex].y){ - lowIndex = i; +double polar_angle(const point& origin, const point& p) { + return std::atan2(p.y - origin.y, p.x - origin.x); +} + +std::vector graham_scan(std::vector& points) { + // selecting lowest point as pivot + size_t low_index = 0; + for (size_t i = 1; i < points.size(); i++) { + if (points[i].y < points[low_index].y) { + low_index = i; } } - std::swap(points[0], points[lowIndex]); + std::swap(points[0], points[low_index]); point pivot = points[0]; - //sorting points by polar angle - std::sort(points.begin()+1, points.end(), [pivot](point a, point b){ - return ccw(pivot, a, b); - }); + // sorting points by polar angle + std::sort( + points.begin() + 1, + points.end(), + [&pivot](const point& pa, const point& pb) { + return polar_angle(pivot, pa) < polar_angle(pivot, pb); + }); - //creating convex hull + // creating convex hull size_t m = 1; - for(size_t i = 2; i < points.size(); i++) { - while(ccw(points[m - 1], points[m], points[i]) <= 0){ - if(m > 1) { - m--; - continue; - } else if(i == points.size()) { - break; - } else { - i++; - } + for (size_t i = 2; i < points.size(); i++) { + while (ccw(points[m - 1], points[m], points[i]) <= 0) { + if (m > 1) { + m--; + continue; + } else if (i == points.size()) { + break; + } else { + i++; + } } m++; std::swap(points[i], points[m]); @@ -46,20 +61,24 @@ std::vector grahamScan(std::vector points){ return std::vector(points.begin(), points.begin() + m + 1); } -void print(std::vector points){ - for ( auto p : points){ - std::cout <<"(" << p.x << ", " << p.y <<")\n"; - } -} - -int main(){ - std::vector points = {{-5, 2}, {5, 7}, {-6, -12}, {-14, -14}, {9, 9}, - {-1, -1}, {-10, 11}, {-6, 15}, {-6, -8}, {15, -9}, - {7, -7}, {-2, -9}, {6, -5}, {0, 14}, {2, 8}}; - std::cout << "original points are as follows:\n"; - print(points); - std::vector hull = grahamScan(points); - std::cout << "points in hull are as follows:\n"; - print(hull); +int main() { + std::vector points = {{-5, 2}, + {5, 7}, + {-6, -12}, + {-14, -14}, + {9, 9}, + {-1, -1}, + {-10, 11}, + {-6, 15}, + {-6, -8}, + {15, -9}, + {7, -7}, + {-2, -9}, + {6, -5}, + {0, 14}, + {2, 8}}; + std::cout << "original points are as follows:\n" << points; + const std::vector hull = graham_scan(points); + std::cout << "points in hull are as follows:\n" << hull; return 0; } diff --git a/contents/graham_scan/graham_scan.md b/contents/graham_scan/graham_scan.md index 9cdb0fb1a..7c38afe8d 100644 --- a/contents/graham_scan/graham_scan.md +++ b/contents/graham_scan/graham_scan.md @@ -27,7 +27,7 @@ We can find whether a rotation is counter-clockwise with trigonometric functions {% sample lang="java" %} [import:27-29, lang:"java"](code/java/GrahamScan.java) {% sample lang="cpp" %} -[import:10-12, lang="cpp"](code/c++/graham_scan.cpp) +[import:18-20, lang="cpp"](code/c++/graham_scan.cpp) {% endmethod %} If the output of this function is 0, the points are collinear. @@ -57,7 +57,7 @@ In the end, the code should look something like this: {% sample lang="java" %} [import:35-70, lang:"java"](code/java/GrahamScan.java) {% sample lang="cpp" %} -[import:14-47, lang="cpp"](code/c++/graham_scan.cpp) +[import:26-62, lang="cpp"](code/c++/graham_scan.cpp) {% endmethod %} ### Bibliography