BotByte

GeoCollection.cpp

Mar 23rd, 2018
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.21 KB | None | 0 0
  1. /*** Convex Hull - Graham's Scan ***/
  2.  
  3. /*
  4. ConvexHull : Graham's Scan O(n lg n), integer implementation
  5. P[]: holds all the points, C[]: holds points on the hull
  6. np: number of points in P[], nc: number of points in C[]
  7. to handle duplicate, call makeUnique() before calling convexHull()
  8. call convexHull() if you have np >= 3
  9. to remove co-linear points on hull, call compress() after convexHull()
  10. */
  11.  
  12. point P[MAX], C[MAX], P0;
  13.  
  14. inline int triArea2(const point &a, const point &b, const point &c) {
  15.     return (a.x*(b.y-c.y) + b.x*(c.y-a.y) + c.x*(a.y-b.y));
  16. }
  17.  
  18. inline int sqDist(const point &a, const point &b) {
  19.     return ((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
  20. }
  21.  
  22. inline bool comp(const point &a, const point &b) {
  23.     int d = triArea2(P0, a, b);
  24.     if(d < 0) return false;
  25.     if(!d && sqDist(P0, a) > sqDist(P0, b)) return false;
  26.     return true;
  27. }
  28.  
  29. inline bool normal(const point &a, const point &b) {
  30.     return ((a.x==b.x) ? a.y < b.y : a.x < b.x);
  31. }
  32.  
  33. inline bool issame(const point &a, const point &b) {
  34.     return (a.x == b.x && a.y == b.y);
  35. }
  36.  
  37. inline void makeUnique(int &np) {
  38.     sort(&P[0], &P[np], normal);
  39.     np = unique(&P[0], &P[np], issame) - P;
  40. }
  41.  
  42. void convexHull(int &np, int &nc) {
  43.     int i, j, pos = 0;
  44.     for(i = 1; i < np; i++)
  45.         if(P[i].y<P[pos].y || (P[i].y==P[pos].y && P[i].x<P[pos].x))
  46.             pos = i;
  47.     swap(P[0], P[pos]);
  48.     P0 = P[0];
  49.     sort(&P[1], &P[np], comp);
  50.     for(i = 0; i < 3; i++) C[i] = P[i];
  51.     for(i = j = 3; i < np; i++) {
  52.         while(triArea2(C[j-2], C[j-1], P[i]) < 0) j--;
  53.         C[j++] = P[i];
  54.     }
  55.     nc = j;
  56. }
  57.  
  58. void compress(int &nc) {
  59.     int i, j, d;
  60.     C[nc] = C[0];
  61.     for(i=j=1; i < nc; i++) {
  62.         d = triArea2(C[j-1], C[i], C[i+1]);
  63.         if(d || (!d && issame(C[j-1], C[i+1]))) C[j++] = C[i];
  64.     }
  65.     nc = j;
  66. }
  67.  
  68.  
  69.  
  70. /*** Point in convex Polygon ***/
  71.  
  72. /*
  73. C[] array of points of convex polygon in ccw order,
  74. nc number of points in C, p target points.
  75. returns true if p is inside C (including edge) or false otherwise.
  76. complexity O(lg n)
  77. */
  78.  
  79. inline bool inConvexPoly(point *C, int nc, const point &p) {
  80.     int st = 1, en = nc - 1, mid;
  81.     while(en - st > 1) {
  82.         mid = (st + en)>>1;
  83.         if(triArea2(C[0], C[mid], p) < 0) en = mid;
  84.         else st = mid;
  85.     }
  86.     if(triArea2(C[0], C[st], p) < 0) return false;
  87.     if(triArea2(C[st], C[en], p) < 0) return false;
  88.     if(triArea2(C[en], C[0], p) < 0) return false;
  89.     return true;
  90. }
  91.  
  92.  
  93.  
  94. /*** Polygon Area (2D) ***/
  95.  
  96. /*
  97. P[] holds the points, must be either in cw or ccw
  98. function returns double of the area.
  99. */
  100.  
  101. inline int dArea(int np) {
  102.     int area = 0;
  103.     for(int i = 0; i < np; i++) {
  104.         area += p[i].x*p[i+1].y - p[i].y*p[i+1].x;
  105.     }
  106.     return abs(area);
  107. }
  108.  
  109.  
  110.  
  111. /*** Closest Pair ***/
  112.  
  113. /*
  114. closestPair(Point *X, Point *Y, int n);
  115. X contains the points sorted by x co-ordinate,
  116. Y contains the points sorted by y co-ordinate,
  117. One additional item in Point structure is needed, the original index.
  118. */
  119.  
  120. typedef long long i64;
  121. typedef struct { int x, y, i; } Point;
  122.  
  123. int flag[MAX];
  124.  
  125. inline i64 sq(const i64 &x) {
  126.     return x*x;
  127. }
  128.  
  129. inline i64 sqdist(const Point &a, const Point &b) {
  130.     return sq(a.x-b.x) + sq(a.y-b.y);
  131. }
  132.  
  133. inline i64 closestPair(Point *X, Point *Y, int n) {
  134.     if(n == 1) return INF;
  135.     if(n == 2) return sqdist(X[0], X[1]);
  136.  
  137.     int i, j, k, n1, n2, ns, m = n >> 1;
  138.     Point Xm = X[m-1], *XL, *XR, *YL, *YR, *YS;
  139.     i64 lt, rt, dd, tmp;
  140.  
  141.     XL = new Point[m], YL = new Point[m];
  142.     XR = new Point[m+1], YR = new Point[m+1];
  143.     YS = new Point[n];
  144.  
  145.     for(i = 0; i < m; i++) XL[i] = X[i], flag[X[i].i] = 0;
  146.     for(; i < n; i++) XR[i - m] = X[i], flag[X[i].i] = 1;
  147.     for(i = n2 = n1 = 0; i < n; i++) {
  148.         if(!flag[Y[i].i]) YL[n1++] = Y[i];
  149.         else YR[n2++] = Y[i];
  150.     }
  151.  
  152.     lt = closestPair(XL, YL, n1);
  153.     rt = closestPair(XR, YR, n2);
  154.     dd = min(lt, rt);
  155.  
  156.     for(i = ns = 0; i < n; i++)
  157.         if(sq(Y[i].x - Xm.x) < dd)
  158.             YS[ns++] = Y[i];
  159.     for(j = 0; j < ns; j++)
  160.         for(k = j + 1; k < ns && sq(YS[k].y - YS[j].y) < dd; k++)
  161.             dd = min(dd, sqdist(YS[j], YS[k]));
  162.  
  163.     delete[] XL; delete[] XR;
  164.     delete[] YL; delete[] YR;
  165.     delete[] YS;
  166.  
  167.     return dd;
  168. }
  169.  
  170.  
  171.  
  172. /*** Circle Intersection Area ***/
  173.  
  174. /*
  175. This code assumes the circle center and radius to be integer.
  176. Change this when necessary.
  177. */
  178.  
  179. inline double commonArea(const Circle &a, const Circle &b) {
  180.     int dsq = sqDist(a.c, b.c);
  181.     double d = sqrt((double)dsq);
  182.     if(sq(a.r + b.r) <= dsq) return 0;
  183.     if(a.r >= b.r && sq(a.r-b.r) >= dsq) return pi * b.r * b.r;
  184.     if(a.r <= b.r && sq(b.r-a.r) >= dsq) return pi * a.r * a.r;
  185.     double angleA = 2.0 * acos((a.r * a.r + dsq - b.r * b.r) / (2.0 * a.r * d));
  186.     double angleB = 2.0 * acos((b.r * b.r + dsq - a.r * a.r) / (2.0 * b.r * d));
  187.     return 0.5 * (a.r * a.r * (angleA - sin(angleA)) + b.r * b.r * (angleB - sin(angleB)));
  188. }
  189.  
  190.  
  191.  
  192. /*** Segment Intersection (2D) ***/
  193.  
  194. /*
  195. Segment intersection in 2D integer space.
  196. P1, p2 makes first segment, p3, p4 makes the second segment
  197. */
  198.  
  199. inline bool intersect(const Point &p1, const Point &p2, const Point &p3, const Point &p4) {
  200.     i64 d1, d2, d3, d4;
  201.     d1 = direction(p3, p4, p1);
  202.     d2 = direction(p3, p4, p2);
  203.     d3 = direction(p1, p2, p3);
  204.     d4 = direction(p1, p2, p4);
  205.     if(((d1 < 0 && d2 > 0) || (d1 > 0 && d2 < 0)) && ((d3 < 0 && d4 > 0) || (d3 > 0 && d4 < 0))) return true;
  206.     if(!d3 && onsegment(p1, p2, p3)) return true;
  207.     if(!d4 && onsegment(p1, p2, p4)) return true;
  208.     if(!d1 && onsegment(p3, p4, p1)) return true;
  209.     if(!d2 && onsegment(p3, p4, p2)) return true;
  210.     return false;
  211. }
  212.  
  213.  
  214.  
  215. /*** Segment Intersection (GeeksforGeeks) ***/
  216.  
  217. // A C++ program to check if two given line segments intersect
  218. #include <iostream>
  219. using namespace std;
  220.  
  221. struct Point
  222. {
  223.     int x;
  224.     int y;
  225. };
  226.  
  227. // Given three colinear points p, q, r, the function checks if
  228. // point q lies on line segment 'pr'
  229. bool onSegment(Point p, Point q, Point r)
  230. {
  231.     if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) &&
  232.         q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y))
  233.        return true;
  234.  
  235.     return false;
  236. }
  237.  
  238. // To find orientation of ordered triplet (p, q, r).
  239. // The function returns following values
  240. // 0 --> p, q and r are colinear
  241. // 1 --> Clockwise
  242. // 2 --> Counterclockwise
  243. int orientation(Point p, Point q, Point r)
  244. {
  245.     // See https://www.geeksforgeeks.org/orientation-3-ordered-points/
  246.     // for details of below formula.
  247.     int val = (q.y - p.y) * (r.x - q.x) -
  248.               (q.x - p.x) * (r.y - q.y);
  249.  
  250.     if (val == 0) return 0;  // colinear
  251.  
  252.     return (val > 0)? 1: 2; // clock or counterclock wise
  253. }
  254.  
  255. // The main function that returns true if line segment 'p1q1'
  256. // and 'p2q2' intersect.
  257. bool doIntersect(Point p1, Point q1, Point p2, Point q2)
  258. {
  259.     // Find the four orientations needed for general and
  260.     // special cases
  261.     int o1 = orientation(p1, q1, p2);
  262.     int o2 = orientation(p1, q1, q2);
  263.     int o3 = orientation(p2, q2, p1);
  264.     int o4 = orientation(p2, q2, q1);
  265.  
  266.     // General case
  267.     if (o1 != o2 && o3 != o4)
  268.         return true;
  269.  
  270.     // Special Cases
  271.     // p1, q1 and p2 are colinear and p2 lies on segment p1q1
  272.     if (o1 == 0 && onSegment(p1, p2, q1)) return true;
  273.  
  274.     // p1, q1 and q2 are colinear and q2 lies on segment p1q1
  275.     if (o2 == 0 && onSegment(p1, q2, q1)) return true;
  276.  
  277.     // p2, q2 and p1 are colinear and p1 lies on segment p2q2
  278.     if (o3 == 0 && onSegment(p2, p1, q2)) return true;
  279.  
  280.      // p2, q2 and q1 are colinear and q1 lies on segment p2q2
  281.     if (o4 == 0 && onSegment(p2, q1, q2)) return true;
  282.  
  283.     return false; // Doesn't fall in any of the above cases
  284. }
  285.  
  286. // Driver program to test above functions
  287. int main()
  288. {
  289.     struct Point p1 = {1, 1}, q1 = {10, 1};
  290.     struct Point p2 = {1, 2}, q2 = {10, 2};
  291.  
  292.     doIntersect(p1, q1, p2, q2)? cout << "Yes\n": cout << "No\n";
  293.  
  294.     p1 = {10, 0}, q1 = {0, 10};
  295.     p2 = {0, 0}, q2 = {10, 10};
  296.     doIntersect(p1, q1, p2, q2)? cout << "Yes\n": cout << "No\n";
  297.  
  298.     p1 = {-5, -5}, q1 = {0, 0};
  299.     p2 = {1, 1}, q2 = {10, 10};
  300.     doIntersect(p1, q1, p2, q2)? cout << "Yes\n": cout << "No\n";
  301.  
  302.     return 0;
  303. }
Advertisement
Add Comment
Please, Sign In to add comment