Advertisement
peltorator

!Double Geometry

Nov 30th, 2017
548
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 18.64 KB | None | 0 0
  1. //
  2. //
  3. //
  4. //            IF INPUT IS DOUBLE, CHANGE IT IN READ METHODS
  5. //            SET PRECISION IN YOUR PROGRAM TO OUTPUT POINTS
  6. //
  7. //
  8.  
  9. const ld eps = 1e-8;
  10. const ld PI = atan2(0, -1);
  11. const ld INF = 1e15;
  12.  
  13.  
  14. ld sqr(ld a)
  15. {
  16.     return a * a;
  17. }
  18.  
  19. ld my_abs(ld a)
  20. {
  21.     if (a < 0)
  22.         return -a;
  23.     return a;
  24. }
  25.  
  26. bool eq(ld a, ld b)
  27. {
  28.     return my_abs(a - b) < eps;
  29. }
  30.  
  31. bool neq(ld a, ld b)
  32. {
  33.     return my_abs(a - b) > eps;
  34. }
  35.  
  36. bool leq(ld a, ld b)
  37. {
  38.     return a < b || eq(a, b);
  39. }
  40.  
  41. bool le(ld a, ld b)
  42. {
  43.     return a < b && !eq(a, b);
  44. }
  45.  
  46.  
  47. bool geq(ld a, ld b)
  48. {
  49.     return a > b || eq(a, b);
  50. }
  51.  
  52.  
  53. bool ge(ld a, ld b)
  54. {
  55.     return a > b && !eq(a, b);
  56. }
  57.  
  58. ld my_sqrt(ld a)
  59. {
  60.     if(le(a, (ld)0))
  61.     {
  62. #ifdef ONPC
  63.         assert("my_sqrt OF NEGATIVE NUMBER");
  64. #endif
  65.         return 0;
  66.     }
  67.     if(a < 0)
  68.         return 0;
  69.     return sqrtl(a);
  70. }
  71.  
  72. /*----------------------------------------Point------------------------------*/
  73.  
  74. struct Point
  75. {
  76.     ld x, y;
  77.  
  78.     Point():
  79.         x(0),
  80.         y(0) {}
  81.     Point(ld x, ld y):
  82.         x(x),
  83.         y(y) {}
  84.  
  85.     Point operator-() const
  86.     {
  87.         return Point(-x, -y);
  88.     }
  89.  
  90.     Point operator+(const Point &a) const
  91.     {
  92.         return Point(a.x + x, a.y + y);
  93.     }
  94.  
  95.     void operator+=(const Point &a)
  96.     {
  97.         x += a.x;
  98.         y += a.y;
  99.     }
  100.  
  101.     Point operator-(const Point &a) const
  102.     {
  103.         return Point(x - a.x, y - a.y);
  104.     }
  105.  
  106.     void operator-=(const Point &a)
  107.     {
  108.         x -= a.x;
  109.         y -= a.y;
  110.     }
  111.  
  112.     ld operator^(const Point &a) const
  113.     {
  114.         return x * a.y - y * a.x;
  115.     }
  116.  
  117.     ld operator*(const Point &a) const
  118.     {
  119.         return x * a.x + y * a.y;
  120.     }
  121.  
  122.     Point operator*(const ld &a) const
  123.     {
  124.         return Point(x * a, y * a);
  125.     }
  126.  
  127.     friend Point operator*(const ld &a, const Point &p);
  128.  
  129.     void operator*=(const ld &a)
  130.     {
  131.         x *= a;
  132.         y *= a;
  133.     }
  134.  
  135.     Point operator/(const ld &a) const
  136.     {
  137.         return Point(x / a, y / a);
  138.     }
  139.  
  140.     void operator/=(const ld &a)
  141.     {
  142.         x /= a;
  143.         y /= a;
  144.     }
  145.  
  146.     ld len() const
  147.     {
  148.         return my_sqrt(x * x + y * y);
  149.     }
  150.  
  151.     ld dist(const Point &a) const
  152.     {
  153.         return (*this - a).len();
  154.     }
  155.  
  156.     bool operator<(const Point &a) const
  157.     {
  158.         return le(y, a.y) || (eq(y, a.y) && le(x, a.x));
  159.     }
  160.  
  161.     bool operator>(const Point &a) const
  162.     {
  163.         return ge(y, a.y) || (eq(y, a.y) && ge(x, a.x));
  164.     }
  165.  
  166.     bool operator==(const Point &a) const
  167.     {
  168.         return eq(a.x, x) && eq(a.y, y);
  169.     }
  170.  
  171.     bool operator!=(const Point &a) const
  172.     {
  173.         return neq(a.x, x) || neq(a.y, y);
  174.     }
  175.  
  176.     void read()
  177.     {
  178.         ll a, b;
  179.         cin >> a >> b;
  180.         x = a;
  181.         y = b;
  182.     }
  183.  
  184.     void write() const
  185.     {
  186.         cout << x << ' ' << y << '\n';
  187.     }
  188.  
  189.     void debwrite() const
  190.     {
  191.         cerr << fixed << setprecision(2) << "Point: x: " << x << ", y: " << y << endl;
  192.     }
  193.  
  194.     Point get_norm(const ld &k = 1) const
  195.     {
  196.         ld len = my_sqrt(x * x + y * y);
  197.         if (eq(len, 0))
  198.         {
  199. #ifdef ONPC
  200.             assert("NORMALIZING ZERO VECTOR");
  201. #endif
  202.             return *this;
  203.         }
  204.         return Point(x / len * k, y / len * k);
  205.     }
  206.  
  207.     void normalize(const ld &k = 1)
  208.     {
  209.         Point p = Point(x, y).get_norm(k);
  210.         x = p.x;
  211.         y = p.y;
  212.     }
  213.  
  214.     Point rotate() const
  215.     {
  216.         return Point(-y, x);
  217.     }
  218.  
  219.     Point rotate(const ld &cosa, const ld &sina) const
  220.     {
  221.         Point v = Point(x, y);
  222.         Point u = v.rotate();
  223.         return v * cosa + u * sina;
  224.     }
  225.  
  226.     Point rotate(const ld &al) const
  227.     {
  228.         return rotate(cos(al), sin(al));
  229.     }
  230.  
  231.     bool is_zero() const
  232.     {
  233.         return eq(x, 0) && eq(y, 0);
  234.     }
  235.  
  236.     ld angle() const
  237.     {
  238.         return atan2(y, x);
  239.     }
  240. };
  241.  
  242. Point operator*(const ld &a, const Point &p)
  243. {
  244.     return Point(a * p.x, a * p.y);
  245. }
  246.  
  247. /*-----------------------------------------Line------------------------------*/
  248.  
  249.  
  250. struct Line
  251. {
  252.     ld a, b, c;
  253.  
  254.     Line():
  255.         a(1),
  256.         b(1),
  257.         c(0) {}
  258.  
  259.     Line(ld a, ld b, ld c):
  260.         a(a),
  261.         b(b),
  262.         c(c) {}
  263.  
  264.     Line(Point a, Point b):
  265.         a(a.y - b.y),
  266.         b(b.x - a.x),
  267.         c((b.y - a.y) * a.x + (a.x - b.x) * a.y) {}
  268.  
  269.     ld len() const
  270.     {
  271.         return my_sqrt(a * a + b * b);
  272.     }
  273.  
  274.     ld operator()(const Point &p) const
  275.     {
  276.         return a * p.x + b * p.y + c;
  277.     }
  278.  
  279.     void normalize()
  280.     {
  281.         ld z = my_sqrt(a * a + b * b);
  282.         if (neq(z, 0))
  283.         {
  284.             a /= z;
  285.             b /= z;
  286.             c /= z;
  287.         }
  288.         else
  289.         {
  290. #ifdef ONPC
  291.             assert("normalizing (0, 0, 0) line");
  292. #endif
  293.         }
  294.     }
  295.  
  296.     Point cross(const Line &l) const
  297.     {
  298.         return Point(-(b * l.c - l.b * c) / (b * l.a - l.b * a), -(a * l.c - l.a * c) / (a * l.b - l.a * b));
  299.     }
  300.  
  301.     Point intersect(const Line &l) const
  302.     {
  303.         return Point(-(b * l.c - l.b * c) / (b * l.a - l.b * a), -(a * l.c - l.a * c) / (a * l.b - l.a * b));
  304.     }
  305.  
  306.     bool parallel(const Line &l) const
  307.     {
  308.         return eq(0, l.a * b - l.b * a);
  309.     }
  310.  
  311.     ld dist(const Point &p) const
  312.     {
  313.         return my_abs(p.x * a + p.y * b + c) / my_sqrt(a * a + b * b);
  314.     }
  315.  
  316.     int dir(const Point &p) const
  317.     {
  318.         ld t = p.x * a + p.y * b + c ;
  319.         if (eq(t, 0))
  320.             return 0;
  321.         if (ge(t, 0))
  322.             return 1;
  323.         return -1;
  324.     }
  325.  
  326.     bool lies(const Point &p) const
  327.     {
  328.         return my_abs(a * p.x + b * p.y + c) < eps;
  329.     }
  330.  
  331.     Line perpendicular() const
  332.     {
  333.         return Line(-b, a, 0);
  334.     }
  335.  
  336.     Line perpendicular(const Point &p) const
  337.     {
  338.         return Line(-b, a, p.x * b - p.y * a);
  339.     }
  340.  
  341.     void read()
  342.     {
  343.         ll x, y, z;
  344.         cin >> x >> y >> z;
  345.         a = x;
  346.         b = y;
  347.         c = z;
  348.     }
  349.  
  350.     void write()
  351.     {
  352.         cout << a << ' ' << b << ' ' << c << '\n';
  353.     }
  354.  
  355.     void debwrite()
  356.     {
  357. #ifdef ONPC
  358.         cerr << fixed << setprecision(2) << "Line: a = " << a << ", b = " << b << ", c = " << c << endl;
  359. #endif
  360.     }
  361. };
  362.  
  363.  
  364. /*-----------------------------------------Circle------------------------------------------*/
  365.  
  366.  
  367. struct Circle
  368. {
  369.     Point c;
  370.     ld r;
  371.  
  372.     Circle():
  373.         c(Point(0, 0)),
  374.         r(1) {}
  375.  
  376.     Circle(Point c, ld r):
  377.         c(c),
  378.         r(r) {}
  379.  
  380.     Circle(ld x, ld y, ld r):
  381.         c(Point(x, y)),
  382.         r(r) {}
  383.  
  384.     Circle(Point c, Point a):
  385.         c(c),
  386.         r((c - a).len()) {}
  387.  
  388.     ld len() const
  389.     {
  390.         return (ld)2 * PI * r;
  391.     }
  392.  
  393.     ld square() const
  394.     {
  395.         return PI * r * r;
  396.     }
  397.  
  398.     void read()
  399.     {
  400.         ll a, b, d;
  401.         cin >> a >> b >> d;
  402.         c.x = a;
  403.         c.y = b;
  404.         r = d;
  405.     }
  406.  
  407.     void write() const
  408.     {
  409.         cout << c.x << ' ' << c.y << ' ' << r << '\n';
  410.     }
  411.  
  412.     void debwrite() const
  413.     {
  414. #ifdef ONPC
  415.         cerr << fixed << setprecision(2) << "Circle: ceneter = (" << c.x << ", " << c.y << "); radius = " << r << endl;
  416. #endif
  417.     }
  418. };
  419.  
  420. ld dist(const Point &a, const Point &b)
  421. {
  422.     return (a - b).len();
  423. }
  424.  
  425. Point lines_cross(Line l, Line k)
  426. {
  427.     l.normalize();
  428.     k.normalize();
  429.     return l.cross(k);
  430. }
  431.  
  432. Point lines_intersect(Line l, Line k)
  433. {
  434.     l.normalize();
  435.     k.normalize();
  436.     return l.cross(k);
  437. }
  438.  
  439.  
  440. bool parallel(Line l, Line k)
  441. {
  442.     l.normalize();
  443.     k.normalize();
  444.     return l.parallel(k);
  445. }
  446.  
  447. bool point_on_line(Point p, Line l)
  448. {
  449.     l.normalize();
  450.     return l.lies(p);
  451. }
  452.  
  453. bool point_on_line(Line l, Point p)
  454. {
  455.     l.normalize();
  456.     return l.lies(p);
  457. }
  458.  
  459. bool three_points_on_line(Point a, Point b, Point c)
  460. {
  461.     a -= b;
  462.     b -= c;
  463.     return my_abs(a ^ b) / a.len() / b.len() < eps;
  464. }
  465.  
  466. bool collinear(Point a, Point b, const Point &c)
  467. {
  468.     a -= c;
  469.     b -= c;
  470.     return my_abs(a ^ b) / a.len() / b.len() < eps;
  471. }
  472.  
  473. Line perp(const Point &p, Line l)
  474. {
  475.     l.normalize();
  476.     return l.perpendicular(p);
  477. }
  478.  
  479. Line perp(Line l, Point p)
  480. {
  481.     l.normalize();
  482.     return l.perpendicular(p);
  483. }
  484.  
  485. ld dist_to_line(const Point &p, Line l)
  486. {
  487.     l.normalize();
  488.     return l.dist(p);
  489. }
  490.  
  491. ld dist_to_line(Line l, const Point &p)
  492. {
  493.     l.normalize();
  494.     return l.dist(p);
  495. }
  496.  
  497. ld dist_to_ray(const Point &p, const Point &a, const Point &b)
  498. {
  499.     if ((b - a) * (p - a) / (b - a).len() / (p - a).len() > eps)
  500.         return dist_to_line(p, Line(a, b));
  501.     return p.dist(a);
  502. }
  503.  
  504. bool point_on_ray(const Point &p, const Point &a, const Point &b)
  505. {
  506.     return eq(0, dist_to_ray(p, a, b));
  507. }
  508.  
  509. ld dist_to_segment(const Point &p, const Point &a, const Point &b)
  510. {
  511.     return max(dist_to_ray(p, a, b), dist_to_ray(p, b, a));
  512. }
  513.  
  514. bool point_on_segment(const Point &p, const Point &a, const Point &b)
  515. {
  516.     return eq(0, dist_to_segment(p, a, b));
  517. }
  518.  
  519. ld angle(Point A, const Point &O, Point B)
  520. {
  521.     A -= O;
  522.     B -= O;
  523.     return acos((A * B) / A.len() / B.len());
  524. }
  525.  
  526. ld angle(const Point &A, const Point &B)
  527. {
  528.     return acos((A * B) / A.len() / B.len());
  529. }
  530.  
  531. bool point_in_angle(Point P, Point A, const Point &O, Point B)
  532. {
  533.     P -= O;
  534.     A -= O;
  535.     B -= O;
  536.     if (le((B ^ A) / A.len() / B.len(), 0))
  537.         swap(A, B);
  538.     return geq((A ^ P) / A.len() / P.len(), 0) && geq((P ^ B) / P.len() / B.len(), 0);
  539. }
  540.  
  541. vector<Point> segments_cross(Point A, Point B, Point C, Point D)
  542. {
  543.     if (three_points_on_line(A, B, C) && three_points_on_line(A, B, D))
  544.     {
  545.         if (A > B)
  546.             swap(A, B);
  547.         if (C > D)
  548.             swap(C, D);
  549.         if (C > B)
  550.             return {};
  551.         if (C == B)
  552.             return {C};
  553.         return {B, C};
  554.     }
  555.     Line l1 = Line(A, B), l2 = Line(C, D);
  556.     if (parallel(l1, l2))
  557.         return {};
  558.     Point X = lines_cross(l1, l2);
  559.     if (point_on_segment(X, A, B) && point_on_segment(X, C, D))
  560.         return {X};
  561.     return {};
  562. }
  563.  
  564. bool check_rays_cross(const Point &A, const Point &B, const Point &C, const Point &D)
  565. {
  566.     Line l1 = Line(A, B), l2 = Line(C, D);
  567.     if (parallel(l1, l2))
  568.         return 0;
  569.     Point X = lines_cross(l1, l2);
  570.     return point_on_ray(X, A, B) && point_on_ray(X, C, D);
  571. }
  572.  
  573. Point in_center(const Point &A, const Point &B, const Point &C)
  574. {
  575.     ld a = (C - B).len();
  576.     ld b = (A - C).len();
  577.     ld c = (A - B).len();
  578.     ld s = a + b + c;
  579.     return Point((a * A.x + b * B.x + c * C.x) / s, (a * A.y + b * B.y + c * C.y) / s);
  580. }
  581.  
  582. Line bissectrice(const Point &A, const Point &B, const Point &C)
  583. {
  584.     return Line(A, in_center(A, B, C));
  585. }
  586.  
  587. Circle in_circle(const Point &A, const Point &B, const Point &C)
  588. {
  589.     Point I = in_center(A, B, C);
  590.     return Circle(I, dist_to_line(I, Line(A, B)));
  591. }
  592.  
  593.  
  594. Point middle(const Point &A, const Point &B)
  595. {
  596.     return (A + B) / (ld)2;
  597. }
  598.  
  599. Line median(const Point &A, const Point &B, const Point &C)
  600. {
  601.     Point M = middle(A, C);
  602.     return Line(B, M);
  603. }
  604.  
  605. Point medians_center(const Point &A, const Point &B, const Point &C)
  606. {
  607.     return (A + B + C) / (ld)3;
  608. }
  609.  
  610. Point masses_center(const vector<Point> &p)
  611. {
  612.     Point ans = p[0];
  613.     for (int i = 1; i < p.size(); i++)
  614.         ans += p[i];
  615.     return ans / (ld)p.size();
  616. }
  617.  
  618. Point heights_center(const Point &A, const Point &B, const Point &C)
  619. {
  620.     Line AB = Line(A, B), BC = Line(B, C);
  621.     Line l = perp(A, BC), k = perp(C, AB);
  622.     return lines_cross(l, k);
  623. }
  624.  
  625. Point circum_center(const Point &A, const Point &B, const Point &C)
  626. {
  627.     Point Ma = middle(B, C), Mb = middle(A, C);
  628.     Line BC = Line(B, C), AC = Line(A, C);
  629.     Line l = perp(Ma, BC), k = perp(Mb, AC);
  630.     return lines_cross(l, k);
  631. }
  632.  
  633. Circle circum_circle(const Point &A, const Point &B, const Point &C)
  634. {
  635.     Point P = circum_center(A, B, C);
  636.     return Circle(P, (P - A).len());
  637. }
  638.  
  639. ld square(const vector<Point> &p)
  640. {
  641.     ld s = 0;
  642.     int n = p.size();
  643.     for (int i = 0; i < n; i++)
  644.     {
  645.         int j = (i + 1) % n;
  646.         s += (p[i].x - p[j].x) * (p[i].y + p[j].y);
  647.     }
  648.     return s / (ld)2;
  649. }
  650.  
  651. bool point_on_circle(const Point &P, const Circle &w)
  652. {
  653.     return eq(dist(P, w.c), w.r);
  654. }
  655.  
  656. bool point_in_circle(const Point &P, const Circle &w)
  657. {
  658.     return leq(dist(P, w.c), w.r);
  659. }
  660.  
  661. ld dist_to_circle(Point p, Circle w)
  662. {
  663.     return my_abs(w.r - (w.c - p).len());
  664. }
  665.  
  666. bool point_in_convex_polygon(const Point &A, const vector<Point> &p)
  667. {
  668.     int n = p.size();
  669.     for (int i = 0; i < n; i++)
  670.     {
  671.         int j = (i + 1) % n, k = (i + 2) % n;
  672.         Line l = Line(p[i], p[j]);
  673.         l.normalize();
  674.         if (l(A) * l(p[k]) < -eps)
  675.             return 0;
  676.     }
  677.     return 1;
  678. }
  679.  
  680. ld arc_length(const Circle &c, const Point &A, const Point &B)
  681. {
  682.     ld alpha = angle(A, c.c, B);
  683.     return alpha * c.r;
  684. }
  685.  
  686. vector<Point> line_circle_cross(Line l, const Circle &w)
  687. {
  688.     l.normalize();
  689.     vector<Point> v;
  690.     ld d = dist_to_line(w.c, l);
  691.     if (ge(d, w.r))
  692.         return v;
  693.     Point h = w.c - Point(l.a, l.b) * d;
  694.     Point h1 = w.c + Point(l.a, l.b) * d;
  695.     if (my_abs(dist_to_line(h1, l)) < my_abs(dist_to_line(h, l)))
  696.         h = h1;
  697.     if (eq(d, w.r))
  698.     {
  699.         v.push_back(h);
  700.         return v;
  701.     }
  702.     Point vect = Point(-l.b, l.a);
  703.     ld go = my_sqrt(w.r * w.r - d * d);
  704.     Point q = vect * go;
  705.     v.push_back(h + q);
  706.     v.push_back(h - q);
  707.     return v;
  708. }
  709.  
  710. vector<Point> circles_cross(const Circle &w, const Circle &u)
  711. {
  712.     Point v = (u.c - w.c);
  713.     ld d = v.len();
  714.     v = v / d;
  715.     ld a = (w.r * w.r - u.r * u.r + d * d) / ((ld)2 * d);
  716.     v = w.c + v * a;
  717.     Line l(w.c, u.c);
  718.     Line k = perp(l, v);
  719.     return line_circle_cross(k, w);
  720. }
  721.  
  722.  
  723. vector<Line> tangent(const Point &P, const Circle &c)
  724. {
  725.     vector<Line> t;
  726.     if (point_on_circle(P, c))
  727.     {
  728.         Line l = Line(P, c.c);
  729.         Line k = perp(P, l);
  730.         t.push_back(k);
  731.         return t;
  732.     }
  733.     if (point_in_circle(P, c))
  734.         return t;
  735.     Circle w(P, my_sqrt((c.c - P).len() * (c.c - P).len() - c.r * c.r));
  736.     vector<Point> a = circles_cross(w, c);
  737.     return {tangent(a[0], c)[0], tangent(a[1], c)[0]};
  738. }
  739.  
  740. bool where(Point v)
  741. {
  742.     if (v.y != 0)
  743.         return v.y > 0;
  744.     return v.x > 0;
  745. }
  746.  
  747. bool convex_hull_cmp(Point v, Point u)
  748. {
  749.     bool x = where(v), y = where(u);
  750.     if (x != y)
  751.         return x;
  752.     ld t = (v ^ u) / v.len() / u.len();
  753.     if (my_abs(t) > eps)
  754.         return t > eps;
  755.     return v.len() < u.len();
  756. }
  757.  
  758. vector<Point> graham_convex_hull(vector<Point> a)
  759. {
  760.     int n = a.size();
  761.     Point down = a[0];
  762.     for (int i = 1; i < n; i++)
  763.         if (a[i] < down)
  764.             down = a[i];
  765.     for (int i = 0; i < n; i++)
  766.         a[i] -= down;
  767.     sort(a.begin(), a.end(), convex_hull_cmp);
  768.     vector<Point> v;
  769.     for (int i = 0; i < n; i++)
  770.     {
  771.         while (v.size() > 1 && geq(((a[i] - v.back()) ^ (v.back() - v[v.size() - 2])), 0))
  772.             v.pop_back();
  773.         v.push_back(a[i]);
  774.     }
  775.     for (int i = 0; i < v.size(); i++)
  776.         v[i] += down;
  777.     return v;
  778. }
  779.  
  780. vector<Point> jarvis_convex_hull(vector<Point> a)
  781. {
  782.     int n = a.size();
  783.     if (n < 3)
  784.     {
  785.         if (n == 1)
  786.             return a;
  787.         if (n == 2)
  788.         {
  789.             if (a[0] == a[1])
  790.                 return {a[0]};
  791.             return a;
  792.         }
  793.     }
  794.     Point down = a[0];
  795.     int k = 0;
  796.     for (int i = 0; i < n; i++)
  797.         if (a[i] < down)
  798.             k = i, down = a[i];
  799.     vector<Point> v;
  800.     v.push_back(down);
  801.     int cur = k;
  802.     while (true)
  803.     {
  804.         int next = -1;
  805.         for (int i = 0; i < n; i++)
  806.             if (i != cur && (next == -1 || ge(((a[i] - a[cur]) ^ (a[next] - a[cur])), 0) ||
  807.             (eq(((a[i] - a[cur]) ^ (a[next] - a[cur])), 0) && (a[i] - a[cur]).len() > (a[next] - a[cur]).len())))
  808.                 next = i;
  809.         if (next == k)
  810.             break;
  811.         v.push_back(a[next]);
  812.         cur = next;
  813.     }
  814.     return v;
  815. }
  816.  
  817.  
  818.  
  819. vector<Point> sum(const vector<Point> &a, const vector<Point> &b)
  820. {
  821.     vector<Point> v, vect;
  822.     v.clear();
  823.     vect.clear();
  824.     int n = a.size();
  825.     int m = b.size();
  826.     Point besta(5e18, 5e18);
  827.     for (int i = 0; i < n; i++)
  828.         if (a[i] < besta)
  829.             besta = a[i];
  830.     Point bestb(5e18, 5e18);
  831.     for (int i = 0; i < m; i++)
  832.         if (b[i] < bestb)
  833.             bestb = b[i];
  834.     Point start = besta + bestb;
  835.     for (int i = 0; i < n; i++)
  836.         vect.push_back(a[(i + 1) % n] - a[i]);
  837.     for (int i = 0; i < m; i++)
  838.         vect.push_back(b[(i + 1) % m] - b[i]);
  839.     sort(vect.begin(), vect.end(), convex_hull_cmp);
  840.     for (int i = 0; i < vect.size(); i++)
  841.     {
  842.         start += vect[i];
  843.         v.push_back(start);
  844.     }
  845.     return v;
  846. }
  847.  
  848. bool planes_intersect(vector<Line> q)
  849. {
  850.     int n = q.size();
  851.     random_shuffle(q.begin(), q.end());
  852.     Point p;
  853.     if (eq(q[0].a, 0))
  854.     {
  855.         p.x = 0;
  856.         p.y = -q[0].c / q[0].b;
  857.     }
  858.     else
  859.     {
  860.         p.y = 0;
  861.         p.x = -q[0].c / q[0].a;
  862.     }
  863.     for (int i = 1; i < q.size(); i++)
  864.     {
  865.         if (geq(q[i](p), 0))
  866.             continue;
  867.         if (eq(q[i].b, 0))
  868.         {
  869.             ld l = -INF, r = INF;
  870.             for (int j = 0; j < i; j++)
  871.             {
  872.                 if (parallel(q[j], q[i]))
  873.                 {
  874.                     if (le(q[j](Point(-q[i].c / q[i].a, 0)), 0))
  875.                         return 0;
  876.                     continue;
  877.                 }
  878.                 Point p = lines_cross(q[i], q[j]);
  879.                 Point qq = Point(p.x, p.y + (ld)100);
  880.                 if (q[j](qq) > (ld)0)
  881.                     l = max(l, p.y);
  882.                 else
  883.                     r = min(r, p.y);
  884.             }
  885.             if (ge(l, r))
  886.                 return 0;
  887.             p.x = -q[i].c / q[i].a;
  888.             p.y = l;
  889.         }
  890.         else
  891.         {
  892.             ld l = -INF, r = INF;
  893.             for (int j = 0; j < i; j++)
  894.             {
  895.                 if (parallel(q[j], q[i]))
  896.                 {
  897.                     if (le(q[j](Point(0, -q[i].c / q[i].b)), 0))
  898.                         return 0;
  899.                     continue;
  900.                 }
  901.                 Point p = lines_cross(q[i], q[j]);
  902.                 Point qq = Point(p.x + (ld)100, -(q[i].c + (p.x + (ld)100) * q[i].a) / q[i].b);
  903.                 if (q[j](qq) > (ld)0)
  904.                     l = max(l, p.x);
  905.                 else
  906.                     r = min(r, p.x);
  907.             }
  908.             if (ge(l, r))
  909.                 return 0;
  910.             p.x = l;
  911.             p.y = -(q[i].c + q[i].a * l) / q[i].b;
  912.         }
  913.     }
  914.     return 1;
  915. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement