Advertisement
Mlxa

Геометрия в double

Mar 1st, 2019
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.09 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using double_type = long double;
  4. #define ulong uint64_t
  5. #define long int64_t
  6. #define double double_type
  7. #define all(x) begin(x), end(x)
  8.  
  9. const double EPS = 1e-9;
  10.  
  11. bool double_equal(double a, double b) {
  12.     return fabs(a - b) <= EPS;
  13. }
  14.  
  15. bool double_less(double a, double b) {
  16.     return a < b - EPS;
  17. }
  18.  
  19. bool double_greater(double a, double b) {
  20.     return a > b + EPS;
  21. }
  22.  
  23. struct Vector {
  24.     double x, y;
  25.    
  26.     Vector(double a, double b) :
  27.         x(a),
  28.         y(b) {}
  29.    
  30.     Vector() :
  31.         Vector(0, 0) {}
  32.    
  33.     friend bool operator==(Vector a, Vector b) {
  34.         return double_equal(a.x, b.x) && double_equal(a.y, b.y);
  35.     }
  36.  
  37.     friend bool operator!=(Vector a, Vector b) {
  38.         return !(a == b);
  39.     }
  40.  
  41.     friend Vector vec(Vector a, Vector b) {
  42.         return {b.x - a.x, b.y - a.y};
  43.     }
  44.  
  45.     friend Vector operator+(Vector a, Vector b) {
  46.         return {a.x + b.x, a.y + b.y};
  47.     }
  48.  
  49.     friend Vector operator-(Vector a, Vector b) {
  50.         return {a.x - b.x, a.y - b.y};
  51.     }
  52.  
  53.     friend Vector operator-(Vector a) {
  54.         return {-a.x, -a.y};
  55.     }
  56.  
  57.     friend Vector operator*(Vector a, double k) {
  58.         return {a.x * k, a.y * k};
  59.     }
  60.  
  61.     friend Vector operator/(Vector a, double k) {
  62.         return {a.x / k, a.y / k};
  63.     }
  64.  
  65.     void operator+=(Vector b) {
  66.         x += b.x;
  67.         y += b.y;
  68.     }
  69.  
  70.     void operator-=(Vector b) {
  71.         x -= b.x;
  72.         y -= b.y;
  73.     }
  74.  
  75.     void operator*=(double k) {
  76.         x *= k;
  77.         y *= k;
  78.     }
  79.  
  80.     void operator/=(double k) {
  81.         x /= k;
  82.         y /= k;
  83.     }
  84.  
  85.     friend double cross_prod(Vector a, Vector b) {
  86.         return a.x * b.y - a.y * b.x;
  87.     }
  88.  
  89.     friend double dot_prod(Vector a, Vector b) {
  90.         return a.x * b.x + a.y * b.y;
  91.     }
  92.  
  93.     double len2() {
  94.         return x * x + y * y;
  95.     }
  96.  
  97.     double len() {
  98.         return sqrt(len2());
  99.     }
  100.  
  101.     friend double dist2(Vector a, Vector b) {
  102.         return vec(a, b).len2();
  103.     }
  104.  
  105.     friend double dist(Vector a, Vector b) {
  106.         return vec(a, b).len();
  107.     }
  108. };
  109.  
  110. const Vector NONE(rand(), rand());
  111. const Vector MANY(rand(), rand());
  112.  
  113. istream &operator>>(istream &in, Vector &v) {
  114.     return in >> v.x >> v.y;
  115. }
  116.  
  117. ostream &operator<<(ostream &out, Vector v) {
  118.     if (v == NONE) {
  119.         return out << "NONE";
  120.     } else if (v == MANY) {
  121.         return out << "MANY";
  122.     } else {
  123.         return out << v.x << ' ' << v.y;
  124.     }
  125. }
  126.  
  127. struct Line {
  128.     Vector first, second;
  129.  
  130.     Line(Vector a, Vector b) :
  131.         first(a),
  132.         second(b) {
  133.         assert(first != second);
  134.     }
  135.  
  136.     Line() :
  137.         Line({0, 0}, {1, 0}) {}
  138.  
  139.     bool have(Vector p) {
  140.         return double_equal(cross_prod(vec(first, p), vec(first, second)), 0);
  141.     }
  142. };
  143.  
  144. ostream &operator<<(ostream &out, Line l) {
  145.     return out << "line " << l.first << ", " << l.second;
  146. }
  147.  
  148. struct Ray {
  149.     Vector first, second;
  150.  
  151.     Ray(Vector a, Vector b) :
  152.         first(a),
  153.         second(b) {
  154.         assert(first != second);
  155.     }
  156.  
  157.     Ray() :
  158.         Ray({0, 0}, {1, 0}) {}
  159.  
  160.     bool have(Vector p) {
  161.         return double_equal(cross_prod(vec(first, p), vec(first, second)), 0)
  162.             && !double_less(dot_prod(vec(first, p), vec(first, second)), 0);
  163.     }
  164. };
  165.  
  166. ostream &operator<<(ostream &out, Ray r) {
  167.     return out << "ray " << r.first << ", " << r.second;
  168. }
  169.  
  170. struct Segment {
  171.     Vector first, second;
  172.    
  173.     Segment(Vector a, Vector b) :
  174.         first(a),
  175.         second(b) {
  176.     }
  177.  
  178.     Segment() :
  179.         Segment({0, 0}, {0, 0}) {}
  180.  
  181.     bool have(Vector p) {
  182.         return double_equal(cross_prod(vec(first, p), vec(first, second)), 0)
  183.             && !double_greater(dot_prod(vec(p, first), vec(p, second)), 0);
  184.     }
  185. };
  186.  
  187. ostream &operator<<(ostream &out, Segment s) {
  188.     return out << "segment " << s.first << ", " << s.second;
  189. }
  190.  
  191. Vector intersect(Line ab, Line cd) {
  192.     double acd = cross_prod(vec(ab.first, cd.first), vec(ab.first, cd.second));
  193.     double bdc = cross_prod(vec(ab.second, cd.second), vec(ab.second, cd.first));
  194.     if (double_equal(acd + bdc, 0)) {
  195.         return double_equal(acd, 0) ? MANY : NONE;
  196.     } else {
  197.         return ab.first + vec(ab.first, ab.second) * (acd / (acd + bdc));
  198.     }
  199. }
  200.  
  201. template<class A, class B>
  202. Vector intersect_template(A a, B b) {
  203.     Line x(a.first, a.second);
  204.     Line y(b.first, b.second);
  205.     Vector p = intersect(x, y);
  206.     assert(p != MANY);
  207.     return (a.have(p) && b.have(p)) ? p : NONE;
  208. }
  209.  
  210. struct Polygon {
  211.     vector<Vector> points;
  212.    
  213.     Polygon() {}
  214.    
  215.     Polygon(int n) :
  216.         points(n) {}
  217.        
  218.     Vector operator[](int i) const {
  219.         assert(0 <= i);
  220.         return points[i % points.size()];
  221.     }
  222.    
  223.     Vector &operator[](int i) {
  224.         assert(0 <= i);
  225.         return points[i % points.size()];
  226.     }
  227.    
  228.     bool have(Vector v) {
  229.         for (int i = 0; i + 1 < (int)points.size(); ++i) {
  230.             if (Segment(points[i], points[i + 1]).have(v)) {
  231.                 return true;
  232.             }
  233.         }
  234.         if (Segment(points.back(), points.front()).have(v)) {
  235.             return true;
  236.         }
  237.         const double OVER = 1.5e9;
  238.         Ray r(v, v + Vector(OVER, 1));
  239.         int cnt = 0;
  240.         for (int i = 0; i + 1 < (int)points.size(); ++i) {
  241.             cnt += intersect_template(Segment(points[i], points[i + 1]), r) != NONE;
  242.         }
  243.         cnt += intersect_template(Segment(points.back(), points.front()), r) != NONE;
  244.         return cnt % 2;
  245.     }
  246.    
  247.     friend ostream &operator<<(ostream &out, const Polygon &p) {
  248.         for (Vector v : p.points) {
  249.             out << v << '\n';
  250.         }
  251.         return out;
  252.     }
  253.    
  254.     friend istream &operator>>(istream &in, Polygon &p) {
  255.         int n;
  256.         in >> n;
  257.         p.points.resize(n);
  258.         for (int i = 0; i < n; ++i) {
  259.             in >> p.points[i];
  260.         }
  261.         return in;
  262.     }
  263. };
  264.  
  265.  
  266.  
  267. double sign_of_turn(Vector a, Vector b, Vector c) {
  268.     return cross_prod(vec(a, b), vec(a, c));
  269. }
  270.  
  271. bool left_turn(Vector a, Vector b, Vector c) {
  272.     return double_greater(sign_of_turn(a, b, c), 0);
  273. }
  274.  
  275. bool right_turn(Vector a, Vector b, Vector c) {
  276.     return double_less(sign_of_turn(a, b, c), 0);
  277. }
  278.  
  279. struct Convex_Polygon : Polygon {
  280.     vector<Vector> points;
  281.    
  282.     Convex_Polygon() {}
  283.    
  284.     bool check_ccw() {
  285.         bool result = true;
  286.         int n = (int)points.size();
  287.         for (int i = 0; i + 2 < n; ++i) {
  288.             result &= double_greater(sign_of_turn(points[i], points[i + 1], points[i + 2]), 0);
  289.         }
  290.         result &= double_greater(sign_of_turn(points[n - 2], points[n - 1], points[0]), 0);
  291.         result &= double_greater(sign_of_turn(points[n - 1], points[0], points[1]), 0);
  292.         return result;
  293.     }
  294.    
  295.     bool in_angle(Vector x, int i, int j) {
  296.         assert(i <= j);
  297.         return (!right_turn(points[0], points[i], x)) && (!left_turn(points[0], points[j], x));
  298.     }
  299.    
  300.     bool have(Vector x) {
  301.         int n = (int)points.size();
  302.         if (!in_angle(x, 1, n - 1)) {
  303.             return false;
  304.         }
  305.         int l = 1, r = n - 1;
  306.         while (r - l > 1) {
  307.             int m = (l + r) / 2;
  308.             if (in_angle(x, 1, m)) {
  309.                 r = m;
  310.             } else {
  311.                 l = m;
  312.             }
  313.         }
  314.         assert(in_angle(x, 1, r));
  315.         l = r - 1;
  316.         return !double_less(sign_of_turn(points[l], points[r], x), 0);
  317.     }
  318.    
  319.     friend ostream &operator<<(ostream &out, const Convex_Polygon &p) {
  320.         for (Vector v : p.points) {
  321.             out << v << '\n';
  322.         }
  323.         return out;
  324.     }
  325.    
  326.     friend istream &operator>>(istream &in, Convex_Polygon &p) {
  327.         int n;
  328.         in >> n;
  329.         p.points.resize(n);
  330.         for (int i = 0; i < n; ++i) {
  331.             in >> p.points[i];
  332.         }
  333.         assert(p.check_ccw());
  334.         return in;
  335.     }
  336. };
  337.  
  338. Convex_Polygon convex_hull(Polygon p) {
  339.     sort(all(p.points), [&](Vector a, Vector b) {
  340.         return tie(a.x, a.y) < tie(b.x, b.y);
  341.     });
  342.     p.points.erase(unique(all(p.points)), p.points.end());
  343.     int n = (int)p.points.size();
  344.     Convex_Polygon hull;
  345.     if (n < 3) {
  346.         hull.points = p.points;
  347.         return hull;
  348.     }
  349.     vector<Vector> up, down;
  350.     for (int i = 0; i < n; ++i) {
  351.         if (i == 0 || i == n - 1 || right_turn(p[0], p[i], p[n - 1])) {
  352.             while (up.size() >= 2 && !right_turn(up[up.size() - 2], up.back(), p[i])) {
  353.                 up.pop_back();
  354.             }
  355.             up.push_back(p[i]);
  356.         }
  357.         if (i == 0 || i == n - 1 || left_turn(p[0], p[i], p[n - 1])) {
  358.             while (down.size() >= 2 && !left_turn(down[down.size() - 2], down.back(), p[i])) {
  359.                 down.pop_back();
  360.             }
  361.             down.push_back(p[i]);
  362.         }
  363.     }
  364.     hull.points = down;
  365.     for (int i = (int)up.size() - 2; i >= 1; --i) {
  366.         hull.points.push_back(up[i]);
  367.     }
  368.     return hull;
  369. }
  370.  
  371.  
  372. int main() {
  373. #ifdef LC
  374.     assert(freopen("input.txt", "r", stdin));
  375. #endif
  376.     ios::sync_with_stdio(false);
  377.     cin.tie(nullptr);
  378.     cout << fixed << setprecision(10);
  379.     cerr << fixed << setprecision(10);
  380.    
  381.     Polygon p;
  382.     cin >> p;
  383.     cout << p << endl;
  384.    
  385.     Vector q;
  386.     while (cin >> q) {
  387.         cout << q << ": " << p.have(q) << endl;
  388.     }
  389.    
  390.     return 0;
  391. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement