Advertisement
kartikkukreja

Graham Scan - Convex Hull

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