Polygons HDU - 1632 (半平面交)
Polygons
题意:求两个多边形的"异或"面积.
半平面交~
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 }