Akatsuki13

Geo

Oct 28th, 2016
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.87 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. double INF = 1e100;
  6. double eps = 1e-12;
  7.  
  8. struct PT
  9. {
  10.     double x, y;
  11.     PT() {}
  12.     PT(double x, double y) : x(x), y(y) {}
  13.     PT(const PT &p) : x(p.x), y(p.y)    {}
  14.     PT operator + (const PT &p)  const
  15.     {
  16.         return PT(x+p.x, y+p.y);
  17.     }
  18.     PT operator - (const PT &p)  const
  19.     {
  20.         return PT(x-p.x, y-p.y);
  21.     }
  22.     PT operator * (double c)     const
  23.     {
  24.         return PT(x*c,   y*c  );
  25.     }
  26.     PT operator / (double c)     const
  27.     {
  28.         return PT(x/c,   y/c  );
  29.     }
  30.     bool operator<(const PT &rhs) const
  31.     {
  32.         return make_pair(y,x) < make_pair(rhs.y,rhs.x);
  33.     }
  34.     bool operator==(const PT &rhs) const
  35.     {
  36.         return make_pair(y,x) == make_pair(rhs.y,rhs.x);
  37.     }
  38. };
  39.  
  40. double dot(PT p, PT q)
  41. {
  42.     return p.x*q.x+p.y*q.y;
  43. }
  44. double len (PT p)
  45. {
  46.     return sqrt(p.x*p.x+p.y*p.y);
  47. }
  48. double dist2(PT p, PT q)
  49. {
  50.     return dot(p-q,p-q);
  51. }
  52. double cross(PT p, PT q)
  53. {
  54.     return p.x*q.y-p.y*q.x;
  55. }
  56. ostream &operator<<(ostream &os, const PT &p)
  57. {
  58.     os << "(" << p.x << "," << p.y << ")";
  59. }
  60.  
  61. // rotate a point CCW or CW around the origin
  62. PT RotateCCW90(PT p)
  63. {
  64.     return PT(-p.y,p.x);
  65. }
  66. PT RotateCW90(PT p)
  67. {
  68.     return PT(p.y,-p.x);
  69. }
  70. PT RotateCCW(PT p, double t)
  71. {
  72.     return PT(p.x*cos(t)-p.y*sin(t), p.x*sin(t)+p.y*cos(t));
  73. }
  74.  
  75. // project point c onto line through a and b
  76. // assuming a != b
  77. PT ProjectPointLine(PT a, PT b, PT c)
  78. {
  79.     return a + (b-a)*dot(c-a, b-a)/dot(b-a, b-a);
  80. }
  81.  
  82. // project point c onto line segment through a and b
  83. PT ProjectPointSegment(PT a, PT b, PT c)
  84. {
  85.     double r = dot(b-a,b-a);
  86.     if (fabs(r) < eps) return a;
  87.     r = dot(c-a, b-a)/r;
  88.     if (r < 0) return a;
  89.     if (r > 1) return b;
  90.     return a + (b-a)*r;
  91. }
  92.  
  93. // compute distance from c to segment between a and b
  94. double DistancePointSegment(PT a, PT b, PT c)
  95. {
  96.     return sqrt(dist2(c, ProjectPointSegment(a, b, c)));
  97. }
  98.  
  99. // compute distance between point (x,y,z) and plane ax+by+cz=d
  100. double DistancePointPlane(double x, double y, double z,
  101.                           double a, double b, double c, double d)
  102. {
  103.     return fabs(a*x+b*y+c*z-d)/sqrt(a*a+b*b+c*c);
  104. }
  105.  
  106. // determine if lines from a to b and c to d are parallel or collinear
  107. bool LinesParallel(PT a, PT b, PT c, PT d)
  108. {
  109.     return fabs(cross(b-a, c-d)) < eps;
  110. }
  111.  
  112. bool LinesCollinear(PT a, PT b, PT c, PT d)
  113. {
  114.     return LinesParallel(a, b, c, d)
  115.            && fabs(cross(a-b, a-c)) < eps
  116.            && fabs(cross(c-d, c-a)) < eps;
  117. }
  118.  
  119. // determine if line segment from a to b intersects with
  120. // line segment from c to d
  121. bool SegmentsIntersect(PT a, PT b, PT c, PT d)
  122. {
  123.     if (LinesCollinear(a, b, c, d))
  124.     {
  125.         if (dist2(a, c) < eps || dist2(a, d) < eps ||
  126.                 dist2(b, c) < eps || dist2(b, d) < eps) return true;
  127.         if (dot(c-a, c-b) > 0 && dot(d-a, d-b) > 0 && dot(c-b, d-b) > 0)
  128.             return false;
  129.         return true;
  130.     }
  131.     if (cross(d-a, b-a) * cross(c-a, b-a) > 0) return false;
  132.     if (cross(a-c, d-c) * cross(b-c, d-c) > 0) return false;
  133.     return true;
  134. }
  135.  
  136. // compute intersection of line passing through a and b
  137. // with line passing through c and d, assuming that unique
  138. // intersection exists; for segment intersection, check if
  139. // segments intersect first
  140. PT ComputeLineIntersection(PT a, PT b, PT c, PT d)
  141. {
  142.     b=b-a;
  143.     d=c-d;
  144.     c=c-a;
  145.     assert(dot(b, b) > eps && dot(d, d) > eps);
  146.     return a + b*cross(c, d)/cross(b, d);
  147. }
  148.  
  149. // compute center of circle given three points
  150. PT ComputeCircleCenter(PT a, PT b, PT c)
  151. {
  152.     b=(a+b)/2;
  153.     c=(a+c)/2;
  154.     return ComputeLineIntersection(b, b+RotateCW90(a-b), c, c+RotateCW90(a-c));
  155. }
  156.  
  157. // determine if point is in a possibly non-convex polygon (by William
  158. // Randolph Franklin); returns 1 for strictly interior points, 0 for
  159. // strictly exterior points, and 0 or 1 for the remaining points.
  160. // Note that it is possible to convert this into an *exact* test using
  161. // integer arithmetic by taking care of the division appropriately
  162. // (making sure to deal with signs properly) and then by writing exact
  163. // tests for checking point on polygon boundary
  164. bool PointInPolygon(const vector<PT> &p, PT q)
  165. {
  166.     bool c = 0;
  167.     for (int i = 0; i < p.size(); i++)
  168.     {
  169.         int j = (i+1)%p.size();
  170.         if ((p[i].y <= q.y && q.y < p[j].y ||
  171.                 p[j].y <= q.y && q.y < p[i].y) &&
  172.                 q.x < p[i].x + (p[j].x - p[i].x) * (q.y - p[i].y) / (p[j].y - p[i].y))
  173.             c = !c;
  174.     }
  175.     return c;
  176. }
  177.  
  178. // determine if point is on the boundary of a polygon
  179. bool PointOnPolygon(const vector<PT> &p, PT q)
  180. {
  181.     for (int i = 0; i < p.size(); i++)
  182.         if (dist2(ProjectPointSegment(p[i], p[(i+1)%p.size()], q), q) < eps)
  183.             return true;
  184.     return false;
  185. }
  186.  
  187. // compute intersection of line through points a and b with
  188. // circle centered at c with radius r > 0
  189. vector<PT> CircleLineIntersection(PT a, PT b, PT c, double r)
  190. {
  191.     vector<PT> ret;
  192.     b = b-a;
  193.     a = a-c;
  194.     double A = dot(b, b);
  195.     double B = dot(a, b);
  196.     double C = dot(a, a) - r*r;
  197.     double D = B*B - A*C;
  198.     if (D < -eps) return ret;
  199.     ret.push_back(c+a+b*(-B+sqrt(D+eps))/A);
  200.     if (D > eps)
  201.         ret.push_back(c+a+b*(-B-sqrt(D))/A);
  202.     return ret;
  203. }
  204.  
  205. // compute intersection of circle centered at a with radius r
  206. // with circle centered at b with radius R
  207. vector<PT> CircleCircleIntersection(PT a, PT b, double r, double R)
  208. {
  209.     vector<PT> ret;
  210.     double d = sqrt(dist2(a, b));
  211.     if (d > r+R || d+min(r, R) < max(r, R)) return ret;
  212.     double x = (d*d-R*R+r*r)/(2*d);
  213.     double y = sqrt(r*r-x*x);
  214.     PT v = (b-a)/d;
  215.     ret.push_back(a+v*x + RotateCCW90(v)*y);
  216.     if (y > 0)
  217.         ret.push_back(a+v*x - RotateCCW90(v)*y);
  218.     return ret;
  219. }
  220.  
  221. // This code computes the area or centroid of a (possibly nonconvex)
  222. // polygon, assuming that the coordinates are listed in a clockwise or
  223. // counterclockwise fashion.  Note that the centroid is often known as
  224. // the "center of gravity" or "center of mass".
  225. double ComputeSignedArea(const vector<PT> &p)
  226. {
  227.     double area = 0;
  228.     for(int i = 0; i < p.size(); i++)
  229.     {
  230.         int j = (i+1) % p.size();
  231.         area += p[i].x*p[j].y - p[j].x*p[i].y;
  232.     }
  233.     return area / 2.0;
  234. }
  235.  
  236. double ComputeArea(const vector<PT> &p)
  237. {
  238.     return fabs(ComputeSignedArea(p));
  239. }
  240.  
  241. PT ComputeCentroid(const vector<PT> &p)
  242. {
  243.     PT c(0,0);
  244.     double scale = 6.0 * ComputeSignedArea(p);
  245.     for (int i = 0; i < p.size(); i++)
  246.     {
  247.         int j = (i+1) % p.size();
  248.         c = c + (p[i]+p[j])*(p[i].x*p[j].y - p[j].x*p[i].y);
  249.     }
  250.     return c / scale;
  251. }
  252.  
  253. // tests whether or not a given polygon (in CW or CCW order) is simple
  254. bool IsSimple(const vector<PT> &p)
  255. {
  256.     for (int i = 0; i < p.size(); i++)
  257.     {
  258.         for (int k = i+1; k < p.size(); k++)
  259.         {
  260.             int j = (i+1) % p.size();
  261.             int l = (k+1) % p.size();
  262.             if (i == l || j == k) continue;
  263.             if (SegmentsIntersect(p[i], p[j], p[k], p[l]))
  264.                 return false;
  265.         }
  266.     }
  267.     return true;
  268. }
  269.  
  270. double angle (PT p, PT q)
  271. {
  272.     return acos(dot(p, q)/(len(p)*len(q)));
  273. }
  274.  
  275. double angle2 (PT a, PT b, PT c) //returns angle ABC
  276. {
  277.     return angle (a-b, c-b);
  278. }
  279.  
  280. PT incentre (PT a, PT b, PT c)
  281. {
  282.     double angb = angle (a-b, c-b);
  283.     double anga = angle (b-a, c-a);
  284.     double angc = angle (a-c, b-c);
  285.  
  286.     PT p1 = RotateCCW(c-b, angb/2.0)+b;
  287.     PT p2 = RotateCCW(b-c, -angc/2.0)+c;
  288.  
  289.     PT d = ComputeLineIntersection(b, p1, c, p2);
  290.  
  291.     return d;
  292. }
  293.  
  294. #define REMOVE_REDUNDANT
  295.  
  296. double area2(PT a, PT b, PT c)
  297. {
  298.     return cross(a,b) + cross(b,c) + cross(c,a);
  299. }
  300.  
  301. #ifdef REMOVE_REDUNDANT
  302. bool between(const PT &a, const PT &b, const PT &c)
  303. {
  304.     return (fabs(area2(a,b,c)) < eps && (a.x-b.x)*(c.x-b.x) <= 0 && (a.y-b.y)*(c.y-b.y) <= 0);
  305. }
  306. #endif
  307.  
  308. void ConvexHull(vector<PT> &pts)
  309. {
  310.     sort(pts.begin(), pts.end());
  311.     pts.erase(unique(pts.begin(), pts.end()), pts.end());
  312.     vector<PT> up, dn;
  313.     for (int i = 0; i < pts.size(); i++)
  314.     {
  315.         while (up.size() > 1 && area2(up[up.size()-2], up.back(), pts[i]) >= 0) up.pop_back();
  316.         while (dn.size() > 1 && area2(dn[dn.size()-2], dn.back(), pts[i]) <= 0) dn.pop_back();
  317.         up.push_back(pts[i]);
  318.         dn.push_back(pts[i]);
  319.     }
  320.     pts = dn;
  321.     for (int i = (int) up.size() - 2; i >= 1; i--) pts.push_back(up[i]);
  322.  
  323. #ifdef REMOVE_REDUNDANT
  324.     if (pts.size() <= 2) return;
  325.     dn.clear();
  326.     dn.push_back(pts[0]);
  327.     dn.push_back(pts[1]);
  328.     for (int i = 2; i < pts.size(); i++)
  329.     {
  330.         if (between(dn[dn.size()-2], dn[dn.size()-1], pts[i])) dn.pop_back();
  331.         dn.push_back(pts[i]);
  332.     }
  333.     if (dn.size() >= 3 && between(dn.back(), dn[0], dn[1]))
  334.     {
  335.         dn[0] = dn.back();
  336.         dn.pop_back();
  337.     }
  338.     pts = dn;
  339. #endif
  340. }
  341.  
  342. int main ()
  343. {
  344.  
  345. }
Add Comment
Please, Sign In to add comment