poj2451Uyuw's Concert(半平面交)
逆时针给出线段,如果模板是顺时针的修改下系数的符号进行平面交即可。
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 20100 12 #define LL long long 13 #define INF 0xfffffff 14 const double eps = 1e-8; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 int m; 18 int cCnt,curCnt; 19 struct point 20 { 21 double x,y; 22 point(double x=0,double y =0 ):x(x),y(y) {} 23 }; 24 point points[N],p[N],q[N]; 25 void getline(point x,point y,double &a,double &b,double &c) 26 { 27 a = x.y - y.y; 28 b = y.x - x.x; 29 c = x.x * y.y-y.x * x.y; 30 } 31 void initial() 32 { 33 for(int i = 1; i <= m; ++i)p[i] = points[i]; 34 p[m+1] = p[1]; 35 p[0] = p[m]; 36 cCnt = m; 37 } 38 point intersect(point x,point y,double a,double b,double c) 39 { 40 double u = fabs(a * x.x + b * x.y + c); 41 double v = fabs(a * y.x + b * y.y + c); 42 point pt; 43 pt.x=(x.x * v + y.x * u) / (u + v); 44 pt.y=(x.y * v + y.y * u) / (u + v); 45 return pt; 46 } 47 void cut(double a,double b ,double c) 48 { 49 curCnt = 0; 50 for(int i = 1; i <= cCnt; ++i) 51 { 52 if(a*p[i].x + b*p[i].y + c >= 0)q[++curCnt] = p[i]; 53 else 54 { 55 if(a*p[i-1].x + b*p[i-1].y + c > 0) 56 q[++curCnt] = intersect(p[i],p[i-1],a,b,c); 57 if(a*p[i+1].x + b*p[i+1].y + c > 0) 58 q[++curCnt] = intersect(p[i],p[i+1],a,b,c); 59 } 60 } 61 for(int i = 1; i <= curCnt; ++i)p[i] = q[i]; 62 p[curCnt+1] = q[1]; 63 p[0] = p[curCnt]; 64 cCnt = curCnt; 65 } 66 void solve() 67 { 68 double area = 0; 69 for(int i = 1; i <= cCnt; ++i) 70 area += p[i].x * p[i + 1].y - p[i + 1].x * p[i].y; 71 area = fabs(area / 2.0); 72 printf("%.1f\n",area); 73 74 } 75 void GuiZhengHua() 76 { 77 //规整化方向,逆时针变顺时针,顺时针变逆时针 78 for(int i = 1; i < (m+1)/2; i ++) 79 swap(points[i], points[m-i]); 80 } 81 int main() 82 { 83 points[1] = point(0,0); 84 points[4] = point(0,10000); 85 points[3] = point(10000,10000); 86 points[2] = point(10000,0); 87 points[5] = p[1]; 88 int n,i; 89 while(scanf("%d",&n)!=EOF) 90 { 91 m = 4; 92 initial(); 93 for(i = 1; i <= 4; ++i) 94 { 95 double a,b,c; 96 getline(points[i],points[i+1],a,b,c); 97 cut(a,b,c); 98 } 99 for(i = 1 ; i <= 2*n ; i+=2) 100 { 101 point p1,p2; 102 scanf("%lf%lf%lf%lf",&p1.x,&p1.y,&p2.x,&p2.y); 103 double a,b,c; 104 getline(p1,p2,a,b,c); 105 cut(a,b,c); 106 } 107 108 // m = 2*n+4; 109 //GuiZhengHua(); 110 //points[m+1] = points[1]; 111 solve(); 112 } 113 return 0; 114 }