Advertisement
Mlxa

Halfplanes

Jan 17th, 2019
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.01 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. typedef long double ld;
  5. #define all(x) begin(x), end(x)
  6. #define long ll
  7. #define double ld
  8.  
  9. const double EPS = 1e-9;
  10. bool double_less(double a, double b) {
  11.     return a < b - EPS;
  12. }
  13. bool double_less_eq(double a, double b) {
  14.     return a < b + EPS;
  15. }
  16. bool double_greater(double a, double b) {
  17.     return a > b + EPS;
  18. }
  19. bool double_greater_eq(double a, double b) {
  20.     return a > b - EPS;
  21. }
  22. bool double_equal(double a, double b) {
  23.     return fabs(a - b) < EPS;
  24. }
  25. bool double_not_equal(double a, double b) {
  26.     return fabs(a - b) > EPS;
  27. }
  28.  
  29. struct Vector {
  30.     double x, y;
  31.     Vector(double a, double b) :
  32.         x(a),
  33.         y(b) {}
  34.     Vector() :
  35.         x(0),
  36.         y(0) {}
  37. };
  38.  
  39. istream &operator>>(istream &in, Vector &v) {
  40.     return in >> v.x >> v.y;
  41. }
  42. ostream &operator<<(ostream &out, Vector v) {
  43.     return out << v.x << ' ' << v.y;
  44. }
  45.  
  46. Vector operator-(Vector a) {
  47.     return { -a.x, - a.y };
  48. }
  49. Vector operator+(Vector a, Vector b) {
  50.     return { a.x + b.x, a.y + b.y };
  51. }
  52. Vector operator-(Vector a, Vector b) {
  53.     return { a.x - b.x, a.y - b.y };
  54. }
  55. Vector operator*(Vector a, double k) {
  56.     return { a.x * k, a.y * k };
  57. }
  58. Vector operator/(Vector a, double k) {
  59.     return { a.x / k, a.y / k };
  60. }
  61. double cross_prod(Vector a, Vector b) {
  62.     return a.x * b.y - a.y * b.x;
  63. }
  64. double dot_prod(Vector a, Vector b) {
  65.     return a.x * b.x + a.y * b.y;
  66. }
  67. bool operator==(Vector a, Vector b) {
  68.     return double_equal(a.x, b.x) && double_equal(a.y, b.y);
  69. }
  70. Vector vec(Vector a, Vector b) {
  71.     return { b.x - a.x, b.y - a.y };
  72. }
  73. double len(Vector a) {
  74.     return hypot(a.x, a.y);
  75. }
  76.  
  77. bool right_triple(Vector a, Vector b, Vector c) {
  78.     return double_less(cross_prod(vec(a, b), vec(b, c)), 0);
  79. }
  80. bool left_triple(Vector a, Vector b, Vector c) {
  81.     return double_greater(cross_prod(vec(a, b), vec(b, c)), 0);
  82. }
  83. bool xy_cmp(Vector a, Vector b) {
  84.     if (double_not_equal(a.x, b.x)) {
  85.         return a.x < b.x;
  86.     }
  87.     return a.y < b.y;
  88. }
  89.  
  90. typedef vector<Vector> Polygon;
  91. Polygon convex_hull(Polygon p) {
  92.     sort(all(p), xy_cmp);
  93.     p.erase(unique(all(p)), p.end());
  94.     if (p.size() < 3) {
  95.         return p;
  96.     }
  97.     int n = (int)p.size();
  98.     Polygon up(1, p[0]), down(1, p[0]);
  99.     for (int i = 1; i < n; ++i) {
  100.         if (i == n - 1 || right_triple(p.front(), p[i], p.back())) {
  101.             while (up.size() >= 2 && !right_triple(up[up.size() - 2], up.back(), p[i])) {
  102.                 up.pop_back();
  103.             }
  104.             up.push_back(p[i]);
  105.         }
  106.         if (i == n - 1 || left_triple(p.front(), p[i], p.back())) {
  107.             while (down.size() >= 2 && !left_triple(down[down.size() - 2], down.back(), p[i])) {
  108.                 down.pop_back();
  109.             }
  110.             down.push_back(p[i]);
  111.         }
  112.     }
  113.     down.insert(down.end(), up.rbegin() + 1, up.rend() - 1);
  114.     return down;
  115. }
  116.  
  117. struct Halfplane {
  118.     Vector a, b;
  119.     Halfplane() {}
  120.     Halfplane(Vector f, Vector s) :
  121.         a(f),
  122.         b(s) {}
  123. };
  124.  
  125. const double S = 1e9;
  126. const double DOUBLE_INF = 1e9;
  127.  
  128. bool contain(Halfplane a, Vector v) {
  129.     return double_greater_eq(cross_prod(vec(a.a, a.b), vec(a.a, v)), 0);
  130. }
  131.  
  132. bool collinear(Vector a, Vector b, Vector c, Vector d) {
  133.     double A = vec(a, b).x, B = vec(a, b).y;
  134.     double C = vec(c, d).x, D = vec(c, d).y;
  135.     /// A / C = B / D
  136.     return double_equal(A * D, B * C);
  137. }
  138.  
  139. Vector intersect_lines(Vector a, Vector b, Vector c, Vector d) {
  140.     double S_acd = cross_prod(vec(a, c), vec(a, d)) / 2;
  141.     double S_bdc = cross_prod(vec(b, d), vec(b, c)) / 2;
  142.     double S_sum = S_acd + S_bdc;
  143.     if (double_equal(S_sum, 0)) {
  144.             assert(false);
  145.             return { 0, 0 };
  146.     }
  147.     Vector u = vec(a, b);
  148.     u = u * S_acd / S_sum;
  149.     return a + u;
  150. }
  151.  
  152. Vector best;
  153.  
  154. bool intersect_halfplanes(vector<Halfplane> h) {
  155.     mt19937 randint;
  156.     h.emplace_back(Vector(-S, 0), Vector(-S, -S));
  157.     h.emplace_back(Vector(0, S), Vector(-S, S));
  158.     h.emplace_back(Vector(S, 0), Vector(S, S));
  159.     h.emplace_back(Vector(0, -S), Vector(S, -S));
  160.     shuffle(h.begin(), h.end(), randint);
  161.     best  = { DOUBLE_INF, 0 };
  162.     for (int i = 0; i < (int)h.size(); ++i) {
  163.         auto &plane = h[i];
  164.         if (contain(plane, best)) {
  165.             continue;
  166.         }
  167.        
  168.         double l = -DOUBLE_INF, r = +DOUBLE_INF;
  169.         for (int j = 0; j < i; ++j) {
  170.             if (collinear(h[j].a, h[j].b, plane.a, plane.b)) {
  171.                 if (contain(h[j], plane.a)) {
  172.                     continue;
  173.                 } else {
  174.                     return false;
  175.                 }
  176.             }
  177.             assert(!collinear(h[j].a, h[j].b, plane.a, plane.b));
  178.             Vector inter = intersect_lines(h[j].a, h[j].b, plane.a, plane.b);
  179.             double val  = len(vec(plane.a, inter)) / len(vec(plane.a, plane.b));
  180.             if (double_less(dot_prod(vec(plane.a, inter), vec(plane.a, plane.b)), 0)) {
  181.                 val *= -1;
  182.             }
  183.             if (contain(h[j], inter + vec(plane.a, plane.b))) {
  184.                 l = max(l, val);
  185.             } else {
  186.                 r = min(r, val);
  187.             }
  188.         }
  189.         if (double_greater(l, r)) {
  190.             return false;
  191.         }
  192.         Vector A = plane.a + vec(plane.a, plane.b) * l;
  193.         Vector B = plane.a + vec(plane.a, plane.b) * r;
  194.         if (A.x > B.x) {
  195.             best = A;
  196.         } else {
  197.             best = B;
  198.         }
  199.     }
  200.     //cerr << "Best point:\t" << best << endl;
  201.     return true;
  202. }
  203.  
  204. const int N = 1e5 + 5;
  205. Vector a[N], b[N];
  206. int n;
  207.  
  208.  
  209. bool check(double w) {
  210.     vector<Halfplane> h;
  211.     Vector x, y, dir, nor;
  212.     for (int i = 0; i < n; ++i) {
  213.         dir = vec(a[i], b[i]);
  214.         dir = dir * w / len(dir);
  215.         nor = { -dir.y, dir.x };
  216.         x = a[i] + nor, y = b[i] + nor;
  217.         if (!contain(Halfplane(x, y), a[i])) {
  218.             swap(x, y);
  219.         }
  220.         assert(contain(Halfplane(x, y), a[i]));
  221.         h.emplace_back(x, y);
  222.         x = a[i] - nor, y = b[i] - nor;
  223.         if (!contain(Halfplane(x, y), a[i])) {
  224.             swap(x, y);
  225.         }
  226.         assert(contain(Halfplane(x, y), a[i]));
  227.         h.emplace_back(x, y);
  228.     }
  229.     /*cerr << "HP:" << endl;
  230.     for (auto e : h) {
  231.         cerr << e.a << '\t' << e.b << endl;
  232.     }*/
  233.     return intersect_halfplanes(h);
  234. }
  235.  
  236. int main() {
  237. #ifdef LC
  238.     assert(freopen("input.txt", "r", stdin));
  239. #endif
  240.     ios::sync_with_stdio(false);
  241.     cin.tie(nullptr);
  242.    
  243.     cin >> n;
  244.     for (int i = 0; i < n; ++i) {
  245.         cin >> a[i] >> b[i];
  246.     }
  247.    
  248.     double l = 1e-9, r = 1e5;
  249.     for (int i = 0; i < 100; ++i) {
  250.         double m = (l + r) / 2;
  251.         if (check(m)) {
  252.             r = m;
  253.         } else {
  254.             l = m;
  255.         }
  256.     }
  257.     assert(check(r));
  258.     cout << fixed << setprecision(8) << best << '\n';
  259.     return 0;
  260. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement