Polygons HDU - 1632 (半平面交)

Polygons

HDU - 1632

 题意:求两个多边形的"异或"面积.

半平面交~

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int maxn = 50010;
  4 const int inf = 0x3f3f3f3f;
  5 const double eps = 1e-8;
  6 struct Point {
  7     double x,y;
  8     Point (double x = 0, double y = 0) : x(x), y(y) {}
  9 };
 10 typedef Point Vector;
 11 Vector operator + (Vector a, Vector b) {
 12     return Vector (a.x + b.x, a.y + b.y);
 13 }
 14 Vector operator * (Vector a, double s) {
 15     return Vector (a.x * s, a.y * s);
 16 }
 17 Vector operator / (Vector a, double p) {
 18     return Vector (a.x / p, a.y / p);
 19 }
 20 Vector operator - (Point a, Point b) {
 21     return Vector (a.x - b.x, a.y - b.y);
 22 }
 23 bool operator < (Point a, Point b) {
 24     return a.x < b.x || (a.x == b.x && a.y < b.y);
 25 }
 26 int dcmp (double x) {
 27     if(fabs(x) < eps) return 0;
 28     return x < 0 ? -1 : 1;
 29 }
 30 bool operator == (const Point &a, const Point &b) {
 31     return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
 32 }
 33 double Dot(Vector a, Vector b) {
 34     return a.x * b.x + a.y * b.y;
 35 }
 36 double Cross (Vector a, Vector b) {
 37     return a.x * b.y - a.y * b.x;
 38 }
 39 //半平面交
 40 struct Line{
 41     Point p;
 42     Vector v;
 43     double rad;
 44     Line () {}
 45     Line (Point p, Vector v) : p(p), v(v) {
 46         rad = atan2(v.y,v.x);
 47     }
 48     bool operator < (const Line &L) const {
 49         return rad < L.rad;
 50     }
 51 };
 52 bool OnLeft(Line L, Point p) {
 53     return Cross(L.v, p - L.p) > 0;
 54 }
 55 Point GetLineIntersection (Line a, Line b) {
 56     Vector u = a.p - b.p;
 57     double t = Cross(b.v, u) / Cross(a.v, b.v);
 58     return a.p + a.v*t;
 59 }
 60 
 61 int HalfplaneIntersection(Line *L, int n,Point *poly) {
 62     sort(L, L+n);
 63     int first,last;
 64     Point *p = new Point[n];
 65     Line *q = new Line[n];  //双端队列
 66     q[first = last = 0] = L[0];
 67     for(int i = 1; i < n; i++) {
 68         while(first < last && !OnLeft(L[i], p[last-1])) last--;   //去尾
 69         while(first < last && !OnLeft(L[i], p[first])) first++; 
 70         q[++last] = L[i];
 71         if(dcmp(Cross(q[last].v, q[last-1].v)) == 0) {
 72             last--;
 73             if(OnLeft(q[last], L[i].p)) q[last] = L[i];
 74         }
 75         if(first < last) p[last-1] = GetLineIntersection (q[last-1],q[last]);
 76     }
 77     while(first < last && !OnLeft(q[first], p[last-1])) last--;  //删除无用平面
 78     if(last - first <= 1) {
 79         delete []p;
 80         delete []q;
 81        return 0;  //空集    
 82     }
 83     p[last] = GetLineIntersection (q[last], q[first]);
 84     int m = 0;
 85     for(int i = first; i <= last; i++) poly[m++] = p[i];
 86     delete []p;
 87     delete []q;
 88     return m;
 89 }
 90 Point p1[maxn], p2[maxn], poly[maxn];
 91 Line line[maxn];
 92 
 93 double ConvexPolygonArea(Point *p, int n) {
 94     double area = 0;
 95     for(int i = 1; i < n-1; i++) {
 96         area += Cross(p[i] - p[0], p[i+1] - p[0]);
 97     }
 98     return area / 2;
 99 }
100 
101 int main(){
102     int n, m;
103 //    freopen("in.txt", "r", stdin);
104     while(scanf("%d", &n) && n){
105         for(int i = 0; i < n; i++){
106             scanf("%lf %lf", &p1[i].x, &p1[i].y);
107         }
108         p1[n] = p1[0];
109         for(int i = 0; i < n; i++){
110            line[i] = Line(p1[i], p1[i] - p1[i+1]);
111         }
112         scanf("%d", &m);
113         for(int i = 0; i < m; i++){
114             scanf("%lf %lf", &p2[i].x, &p2[i].y);
115         }
116         p2[m] = p2[0];
117         for(int i = 0; i < m; i++){
118             line[i+n] = Line(p2[i], p2[i] - p2[i+1]);
119         }
120         int sz = HalfplaneIntersection(line, n+m, poly);
121         double ans = - ConvexPolygonArea(p1, n) - ConvexPolygonArea(p2, m) - 2*ConvexPolygonArea(poly, sz);
122         printf("%8.2lf", ans);
123     }
124     puts("");
125     return 0;
126 }
View Code

 

posted @ 2017-10-16 23:58  yijiull  阅读(218)  评论(0编辑  收藏  举报