Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*** Convex Hull - Graham's Scan ***/
- /*
- ConvexHull : Graham's Scan O(n lg n), integer implementation
- P[]: holds all the points, C[]: holds points on the hull
- np: number of points in P[], nc: number of points in C[]
- to handle duplicate, call makeUnique() before calling convexHull()
- call convexHull() if you have np >= 3
- to remove co-linear points on hull, call compress() after convexHull()
- */
- point P[MAX], C[MAX], P0;
- inline int triArea2(const point &a, const point &b, const point &c) {
- return (a.x*(b.y-c.y) + b.x*(c.y-a.y) + c.x*(a.y-b.y));
- }
- inline int sqDist(const point &a, const point &b) {
- return ((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
- }
- inline bool comp(const point &a, const point &b) {
- int d = triArea2(P0, a, b);
- if(d < 0) return false;
- if(!d && sqDist(P0, a) > sqDist(P0, b)) return false;
- return true;
- }
- inline bool normal(const point &a, const point &b) {
- return ((a.x==b.x) ? a.y < b.y : a.x < b.x);
- }
- inline bool issame(const point &a, const point &b) {
- return (a.x == b.x && a.y == b.y);
- }
- inline void makeUnique(int &np) {
- sort(&P[0], &P[np], normal);
- np = unique(&P[0], &P[np], issame) - P;
- }
- void convexHull(int &np, int &nc) {
- int i, j, pos = 0;
- for(i = 1; i < np; i++)
- if(P[i].y<P[pos].y || (P[i].y==P[pos].y && P[i].x<P[pos].x))
- pos = i;
- swap(P[0], P[pos]);
- P0 = P[0];
- sort(&P[1], &P[np], comp);
- for(i = 0; i < 3; i++) C[i] = P[i];
- for(i = j = 3; i < np; i++) {
- while(triArea2(C[j-2], C[j-1], P[i]) < 0) j--;
- C[j++] = P[i];
- }
- nc = j;
- }
- void compress(int &nc) {
- int i, j, d;
- C[nc] = C[0];
- for(i=j=1; i < nc; i++) {
- d = triArea2(C[j-1], C[i], C[i+1]);
- if(d || (!d && issame(C[j-1], C[i+1]))) C[j++] = C[i];
- }
- nc = j;
- }
- /*** Point in convex Polygon ***/
- /*
- C[] array of points of convex polygon in ccw order,
- nc number of points in C, p target points.
- returns true if p is inside C (including edge) or false otherwise.
- complexity O(lg n)
- */
- inline bool inConvexPoly(point *C, int nc, const point &p) {
- int st = 1, en = nc - 1, mid;
- while(en - st > 1) {
- mid = (st + en)>>1;
- if(triArea2(C[0], C[mid], p) < 0) en = mid;
- else st = mid;
- }
- if(triArea2(C[0], C[st], p) < 0) return false;
- if(triArea2(C[st], C[en], p) < 0) return false;
- if(triArea2(C[en], C[0], p) < 0) return false;
- return true;
- }
- /*** Polygon Area (2D) ***/
- /*
- P[] holds the points, must be either in cw or ccw
- function returns double of the area.
- */
- inline int dArea(int np) {
- int area = 0;
- for(int i = 0; i < np; i++) {
- area += p[i].x*p[i+1].y - p[i].y*p[i+1].x;
- }
- return abs(area);
- }
- /*** Closest Pair ***/
- /*
- closestPair(Point *X, Point *Y, int n);
- X contains the points sorted by x co-ordinate,
- Y contains the points sorted by y co-ordinate,
- One additional item in Point structure is needed, the original index.
- */
- typedef long long i64;
- typedef struct { int x, y, i; } Point;
- int flag[MAX];
- inline i64 sq(const i64 &x) {
- return x*x;
- }
- inline i64 sqdist(const Point &a, const Point &b) {
- return sq(a.x-b.x) + sq(a.y-b.y);
- }
- inline i64 closestPair(Point *X, Point *Y, int n) {
- if(n == 1) return INF;
- if(n == 2) return sqdist(X[0], X[1]);
- int i, j, k, n1, n2, ns, m = n >> 1;
- Point Xm = X[m-1], *XL, *XR, *YL, *YR, *YS;
- i64 lt, rt, dd, tmp;
- XL = new Point[m], YL = new Point[m];
- XR = new Point[m+1], YR = new Point[m+1];
- YS = new Point[n];
- for(i = 0; i < m; i++) XL[i] = X[i], flag[X[i].i] = 0;
- for(; i < n; i++) XR[i - m] = X[i], flag[X[i].i] = 1;
- for(i = n2 = n1 = 0; i < n; i++) {
- if(!flag[Y[i].i]) YL[n1++] = Y[i];
- else YR[n2++] = Y[i];
- }
- lt = closestPair(XL, YL, n1);
- rt = closestPair(XR, YR, n2);
- dd = min(lt, rt);
- for(i = ns = 0; i < n; i++)
- if(sq(Y[i].x - Xm.x) < dd)
- YS[ns++] = Y[i];
- for(j = 0; j < ns; j++)
- for(k = j + 1; k < ns && sq(YS[k].y - YS[j].y) < dd; k++)
- dd = min(dd, sqdist(YS[j], YS[k]));
- delete[] XL; delete[] XR;
- delete[] YL; delete[] YR;
- delete[] YS;
- return dd;
- }
- /*** Circle Intersection Area ***/
- /*
- This code assumes the circle center and radius to be integer.
- Change this when necessary.
- */
- inline double commonArea(const Circle &a, const Circle &b) {
- int dsq = sqDist(a.c, b.c);
- double d = sqrt((double)dsq);
- if(sq(a.r + b.r) <= dsq) return 0;
- if(a.r >= b.r && sq(a.r-b.r) >= dsq) return pi * b.r * b.r;
- if(a.r <= b.r && sq(b.r-a.r) >= dsq) return pi * a.r * a.r;
- double angleA = 2.0 * acos((a.r * a.r + dsq - b.r * b.r) / (2.0 * a.r * d));
- double angleB = 2.0 * acos((b.r * b.r + dsq - a.r * a.r) / (2.0 * b.r * d));
- return 0.5 * (a.r * a.r * (angleA - sin(angleA)) + b.r * b.r * (angleB - sin(angleB)));
- }
- /*** Segment Intersection (2D) ***/
- /*
- Segment intersection in 2D integer space.
- P1, p2 makes first segment, p3, p4 makes the second segment
- */
- inline bool intersect(const Point &p1, const Point &p2, const Point &p3, const Point &p4) {
- i64 d1, d2, d3, d4;
- d1 = direction(p3, p4, p1);
- d2 = direction(p3, p4, p2);
- d3 = direction(p1, p2, p3);
- d4 = direction(p1, p2, p4);
- if(((d1 < 0 && d2 > 0) || (d1 > 0 && d2 < 0)) && ((d3 < 0 && d4 > 0) || (d3 > 0 && d4 < 0))) return true;
- if(!d3 && onsegment(p1, p2, p3)) return true;
- if(!d4 && onsegment(p1, p2, p4)) return true;
- if(!d1 && onsegment(p3, p4, p1)) return true;
- if(!d2 && onsegment(p3, p4, p2)) return true;
- return false;
- }
- /*** Segment Intersection (GeeksforGeeks) ***/
- // A C++ program to check if two given line segments intersect
- #include <iostream>
- using namespace std;
- struct Point
- {
- int x;
- int y;
- };
- // Given three colinear points p, q, r, the function checks if
- // point q lies on line segment 'pr'
- bool onSegment(Point p, Point q, Point r)
- {
- if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) &&
- q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y))
- return true;
- return false;
- }
- // To find orientation of ordered triplet (p, q, r).
- // The function returns following values
- // 0 --> p, q and r are colinear
- // 1 --> Clockwise
- // 2 --> Counterclockwise
- int orientation(Point p, Point q, Point r)
- {
- // See https://www.geeksforgeeks.org/orientation-3-ordered-points/
- // for details of below formula.
- int val = (q.y - p.y) * (r.x - q.x) -
- (q.x - p.x) * (r.y - q.y);
- if (val == 0) return 0; // colinear
- return (val > 0)? 1: 2; // clock or counterclock wise
- }
- // The main function that returns true if line segment 'p1q1'
- // and 'p2q2' intersect.
- bool doIntersect(Point p1, Point q1, Point p2, Point q2)
- {
- // Find the four orientations needed for general and
- // special cases
- int o1 = orientation(p1, q1, p2);
- int o2 = orientation(p1, q1, q2);
- int o3 = orientation(p2, q2, p1);
- int o4 = orientation(p2, q2, q1);
- // General case
- if (o1 != o2 && o3 != o4)
- return true;
- // Special Cases
- // p1, q1 and p2 are colinear and p2 lies on segment p1q1
- if (o1 == 0 && onSegment(p1, p2, q1)) return true;
- // p1, q1 and q2 are colinear and q2 lies on segment p1q1
- if (o2 == 0 && onSegment(p1, q2, q1)) return true;
- // p2, q2 and p1 are colinear and p1 lies on segment p2q2
- if (o3 == 0 && onSegment(p2, p1, q2)) return true;
- // p2, q2 and q1 are colinear and q1 lies on segment p2q2
- if (o4 == 0 && onSegment(p2, q1, q2)) return true;
- return false; // Doesn't fall in any of the above cases
- }
- // Driver program to test above functions
- int main()
- {
- struct Point p1 = {1, 1}, q1 = {10, 1};
- struct Point p2 = {1, 2}, q2 = {10, 2};
- doIntersect(p1, q1, p2, q2)? cout << "Yes\n": cout << "No\n";
- p1 = {10, 0}, q1 = {0, 10};
- p2 = {0, 0}, q2 = {10, 10};
- doIntersect(p1, q1, p2, q2)? cout << "Yes\n": cout << "No\n";
- p1 = {-5, -5}, q1 = {0, 0};
- p2 = {1, 1}, q2 = {10, 10};
- doIntersect(p1, q1, p2, q2)? cout << "Yes\n": cout << "No\n";
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment