Advertisement
istinishat

Graham Scan (Convex hull)

Nov 24th, 2017
206
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define si(n) scanf("%d",&n)
  5. #define MAX 100005
  6.  
  7. struct Point{
  8.     int x,y;
  9.     Point(){x=0,y=0;}
  10.     Point(int a,int b){x=a,y=b;}
  11.     bool operator < (const Point& b){
  12.         if(b.y!=y)return y<b.y;
  13.         else return x<b.x;
  14.     }
  15. };
  16. // Point having the least y coordinate, used for sorting other points
  17. // according to polar angle about this point
  18. Point pivot;
  19. // returns -1 if a -> b -> c forms a counter-clockwise turn,
  20. // +1 for a clockwise turn, 0 if they are collinear
  21. int ccw(Point a, Point b, Point c) {
  22.     int area = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
  23.     if (area > 0)
  24.         return -1;
  25.     else if (area < 0)
  26.         return 1;
  27.     return 0;
  28. }
  29. // returns square of Euclidean distance between two points
  30. int sqrDist(Point a, Point b)  {
  31.     int dx = a.x - b.x, dy = a.y - b.y;
  32.     return dx * dx + dy * dy;
  33. }
  34. // used for sorting points according to polar order w.r.t the pivot
  35. bool POLAR_ORDER(Point a, Point b)  {
  36.     int order = ccw(pivot, a, b);
  37.     if (order == 0)
  38.         return sqrDist(pivot, a) < sqrDist(pivot, b);
  39.     return (order == -1);
  40. }
  41.  
  42. stack<Point> grahamScan(vector<Point>points)    {
  43.     stack<Point> hull;
  44.     if (points.size() < 3)
  45.         return hull;
  46.  
  47.     // find the point having the least y coordinate (pivot),
  48.     // ties are broken in favor of lower x coordinate
  49.     int leastY = 0;
  50.     for (int i = 1; i < points.size(); i++)
  51.         if (points[i] < points[leastY])
  52.             leastY = i;
  53.  
  54.     // swap the pivot with the first point
  55.     Point temp = points[0];
  56.     points[0] = points[leastY];
  57.     points[leastY] = temp;
  58.  
  59.     // sort the remaining point according to polar order about the pivot
  60.     pivot = points[0];
  61.     sort(points.begin()+1,points.end(),POLAR_ORDER);
  62.  
  63.     hull.push(points[0]);
  64.     hull.push(points[1]);
  65.     hull.push(points[2]);
  66.  
  67.     for (int i=3;i<points.size();i++) {
  68.         Point top = hull.top();
  69.         hull.pop();
  70.         while (ccw(hull.top(), top, points[i]) != -1)   {
  71.             top = hull.top();
  72.             hull.pop();
  73.         }
  74.         hull.push(top);
  75.         hull.push(points[i]);
  76.     }
  77.     return hull;
  78. }
  79.  
  80. int main()  {
  81.     vector<Point>v;
  82.     v.push_back(Point(0,0));
  83.     v.push_back(Point(1,1));
  84.     v.push_back(Point(2,2));
  85.     v.push_back(Point(3,-1));
  86.  
  87.     stack<Point> hull = grahamScan(v);
  88.     while (!hull.empty())   {
  89.         Point p = hull.top();
  90.         hull.pop();
  91.  
  92.         printf("(%d, %d)\n", p.x, p.y);
  93.     }
  94.  
  95.     return 0;
  96. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement