首页 > 代码库 > poj2451Uyuw's Concert(半平面交)

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 }
View Code