Advertisement
despotovski01

Konveksni Poligoni

May 7th, 2017
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.40 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int PARALLEL = 0;
  5. const int CW = 1;
  6. const int CCW = 2;
  7. // polygon tools
  8.  
  9. class Vector {
  10. public:
  11.     double x, y;
  12.     Vector(double _x, double _y){
  13.         x = _x;
  14.         y = _y;
  15.     }
  16.  
  17.     double cross(const Vector& v){
  18.         return x * v.y - y * v.x;
  19.     }
  20.  
  21.     double dot(const Vector& v){
  22.         return x*v.x + y*v.y;
  23.     }
  24. };
  25.  
  26. class Point {
  27. public:
  28.     double x, y;
  29.     Point(double _x = 0, double _y = 0){
  30.         x = _x;
  31.         y = _y;
  32.     }
  33. };
  34.  
  35. int orientation(Point p1, Point p2, Point p3){
  36.     double s = (p2.y - p1.y) * (p3.x - p2.x);
  37.     double t = (p2.x - p1.x) * (p3.y - p2.y);
  38.     if(s == t){
  39.         return PARALLEL;
  40.     }
  41.     return s > t ? CW : CCW;
  42. }
  43.  
  44. bool onSegment(Point p1, Point p2, Point r){
  45.     if(r.x >= min(p1.x,p2.x) && r.x <= max(p1.x,p2.x) && r.y >= min(p1.y,p2.y) && r.y <= max(p1.y,p2.y)){
  46.         return true;
  47.     }
  48.     return false;
  49. }
  50.  
  51. class Line {
  52. public:
  53.     Point p1, p2;
  54.     Line(double x1 = 0, double y1 = 0, double x2 = 0, double y2 = 0){
  55.         p1 = Point(x1, y1);
  56.         p2 = Point(x2, y2);
  57.     }
  58.  
  59.     Line(Point _p1, Point _p2){
  60.         p1 = _p1;
  61.         p2 = _p2;
  62.     }
  63.  
  64.     Point intersection(const Line& l){
  65.         double a1 = p2.y - p1.y;
  66.         double b1 = p1.x - p2.x;
  67.         double c1 = a1*p1.x + b1*p1.y;
  68.         double a2 = l.p2.y - l.p1.y;
  69.         double b2 = l.p1.x - l.p2.x;
  70.         double c2 = a2*l.p1.x + b2*l.p1.y;
  71.         double det = a1 * b2 - a2 * b1;
  72.         if(det == 0){
  73.             return Point(0, 0);
  74.         } else {
  75.             double x = (b2*c1 - b1*c2)/det;
  76.             double y = (a1*c2 - a2*c1)/det;
  77.             return Point(x, y);
  78.         }
  79.     }
  80.  
  81.     bool intersects(const Line &l){
  82.         int o1 = orientation(p1,p2,l.p1);
  83.         int o2 = orientation(p1,p2,l.p2);
  84.         int o3 = orientation(l.p1,l.p2,p1);
  85.         int o4 = orientation(l.p1,l.p2,p2);
  86.         if(o1 != o2 && o3 != o4){
  87.             return true;
  88.         } else if(o1 == PARALLEL && o2 == PARALLEL && o3 == PARALLEL && o4 == PARALLEL){
  89.             if(onSegment(p1,p2,l.p1) || onSegment(p1,p2,l.p2) || onSegment(l.p1,l.p2,p1) || onSegment(l.p1,l.p2,p2)){
  90.                 return true;
  91.             }
  92.         }
  93.         return false;
  94.     }
  95. };
  96.  
  97. double areaOfPolygon(vector<Point> &points){
  98.     double res = 0;
  99.     for(int i = 1;i<points.size()-1;++i){
  100.         Vector u(points[i].x - points[0].x, points[i].y - points[0].y);
  101.         Vector v(points[i+1].x - points[0].x, points[i+1].y - points[0].y);
  102.         res += u.cross(v);
  103.     }
  104.     return abs(res / 2.0);
  105. }
  106.  
  107. bool inside(Point a, Line* lines, int n){
  108.     int MAX_TRIES = 1000;
  109.     int MOD = 100007;
  110.     int in = 0, out = 0;
  111.     double maxX = -1e18, maxY = -1e18;
  112.     for(int i = 0;i<n;++i){
  113.         maxX = max(maxX, lines[i].p1.x);
  114.         maxX = max(maxX, lines[i].p2.x);
  115.         maxY = max(maxY, lines[i].p1.y);
  116.         maxY = max(maxY, lines[i].p2.y);
  117.     }
  118.     for(int tries = 0;tries < MAX_TRIES;++tries){
  119.         double px = rand() % (int)MOD + maxX+MOD+1;
  120.         double py = rand() % (int)MOD + maxY+MOD+1;
  121.         Line l(a, Point(px, py));
  122.         int cnt = 0;
  123.         for(int i = 0;i<n;++i){
  124.             if(l.intersects(lines[i])){
  125.                 cnt++;
  126.             }
  127.         }
  128.         if(cnt % 2){
  129.             in++;
  130.         } else {
  131.             out++;
  132.         }
  133.     }
  134.     return in > out;
  135. }
  136.  
  137. double distSq(const Point& a, const Point& b){
  138.     return pow(a.x - b.x, 2) + pow(a.y - b.y, 2);
  139. }
  140.  
  141. Point refPoint;
  142.  
  143. int angleCmp(const Point& p1, const Point& p2) {
  144.     int o = orientation(refPoint, p1, p2);
  145.     if (o == 0){
  146.         return (distSq(refPoint, p2) >= distSq(refPoint, p1));
  147.     }
  148.     return (o == CCW);
  149. }
  150.  
  151. Point nextToLast(stack<Point>& pstack){
  152.     Point prev = pstack.top();
  153.     pstack.pop();
  154.     Point res = pstack.top();
  155.     pstack.push(prev);
  156.     return res;
  157. }
  158.  
  159. vector<Point> convexHull(vector<Point> points, int n){
  160.     Point first = points[0];
  161.     int minIdx = 0;
  162.     for(int i = 1;i<n;++i){
  163.         if(points[i].y < first.y || (points[i].y == first.y && points[i].x < first.x)){
  164.             first = points[i];
  165.             minIdx = i;
  166.         }
  167.     }
  168.     refPoint = first;
  169.     swap(points[0], points[minIdx]);
  170.     sort(points.begin()+1, points.end(), angleCmp);
  171.     int m = 1;
  172.     for(int i = 1;i<n;++i){
  173.         while(i < n-1 && orientation(refPoint, points[i], points[i+1]) == 0){
  174.             i++;
  175.         }
  176.         points[m] = points[i];
  177.         m++;
  178.     }
  179.     if(m < 3){
  180.         return vector<Point>();
  181.     }
  182.     stack<Point> pstack;
  183.     pstack.push(points[0]);
  184.     pstack.push(points[1]);
  185.     pstack.push(points[2]);
  186.     for(int i = 3;i<m;++i){
  187.         while(orientation(nextToLast(pstack), pstack.top(), points[i]) != CCW){
  188.             pstack.pop();
  189.         }
  190.         pstack.push(points[i]);
  191.     }
  192.     vector<Point> res;
  193.     while(!pstack.empty()){
  194.         res.push_back(pstack.top());
  195.         pstack.pop();
  196.     }
  197.     reverse(res.begin(), res.end());
  198.     return res;
  199. }
  200.  
  201. double roundTwo(double a){
  202.     double curr = round(a * 100);
  203.     return curr / 100;
  204. }
  205.  
  206. int main(){
  207.     ios::sync_with_stdio(false);
  208.     srand(time(0));
  209.     int a, b;
  210.     cin>>a>>b;
  211.     Point pa[a], pb[b];
  212.     Line la[a], lb[b];
  213.     for(int i = 0;i<a;++i){
  214.         int x,y;
  215.         cin>>x>>y;
  216.         pa[i] = Point(x, y);
  217.     }
  218.     for(int i = 0;i<b;++i){
  219.         int x,y;
  220.         cin>>x>>y;
  221.         pb[i] = Point(x, y);
  222.     }
  223.     for(int i = 0;i<a;++i){
  224.         la[i] = Line(pa[i], pa[(i+1) % a]);
  225.     }
  226.     for(int i = 0;i<b;++i){
  227.         lb[i] = Line(pb[i], pb[(i+1) % b]);
  228.     }
  229.     vector<Point> insidePoints;
  230.     for(int i = 0;i<a;++i){
  231.         for(int j = 0;j<b;++j){
  232.             if(la[i].intersects(lb[j])){
  233.                 insidePoints.push_back(la[i].intersection(lb[j]));
  234.             }
  235.         }
  236.     }
  237.     for(int i = 0;i<a;++i){
  238.         if(inside(pa[i], lb, b)){
  239.             insidePoints.push_back(pa[i]);
  240.         }
  241.     }
  242.     for(int i = 0;i<b;++i){
  243.         if(inside(pb[i], la, a)){
  244.             insidePoints.push_back(pb[i]);
  245.         }
  246.     }
  247.     vector<Point> ch;
  248.     if(insidePoints.size() > 2){
  249.         ch = convexHull(insidePoints, insidePoints.size());
  250.     }
  251.     double res = 0;
  252.     if(ch.size() >= 3){
  253.         res = areaOfPolygon(ch) ;
  254.     }
  255.     cout<<roundTwo(res)<<endl;
  256.     return 0;
  257. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement