poj 1474 Video Surveillance 半平面交
http://poj.org/problem?id=1474
和前面做过的两道一样,又是一题判断多边形是否存在核问题,照样粘贴模板。
点是顺时针给出。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 const double MAX =100000000; 7 const double pi =acos(-1.0); 8 const double eps=1e-8; 9 int m,s; 10 struct node 11 { 12 double x,y; //注意类型 13 }tr[110],p[110],q[110]; 14 int sig(double k) 15 { 16 return (k<-eps)?-1:(k>eps); 17 } 18 void interect(node x,node y,double a,double b,double c) 19 { 20 double u=fabs(a*x.x+b*x.y+c); 21 double v=fabs(a*y.x+b*y.y+c); 22 q[++s].x=(x.x*v+y.x*u)/(u+v); 23 q[s].y=(x.y*v+y.y*u)/(u+v); 24 } 25 //利用半平面切割 26 void cut(double a,double b,double c) 27 { 28 s=0; 29 int i; 30 for(i=1;i<=m;i++) //遍历所有顶点是否能观察到该边 31 { 32 if(sig(a*p[i].x+b*p[i].y+c)>=0)//因为线段是顺时针给出的,如果是逆时针就是<=0 33 { 34 q[++s]=p[i]; //若是则存储 35 } 36 else 37 { 38 if(sig(a*p[i-1].x+b*p[i-1].y+c)>0)//逆时针就是<0 39 interect(p[i-1],p[i],a,b,c); 40 if(sig(a*p[i+1].x+b*p[i+1].y+c)>0)//逆时针就是<0 41 interect(p[i+1],p[i],a,b,c); 42 } 43 } 44 //最后的p数组存放半平面的点集合 45 for(i=1;i<=s;i++) 46 p[i]=q[i]; 47 p[s+1]=p[1],p[0]=p[s]; 48 m=s; 49 } 50 51 52 int main() 53 { 54 int n,i,j,t=1; 55 while(scanf("%d",&n),n) 56 { 57 for(i=0;i<n;i++) 58 { 59 scanf("%lf%lf",&tr[i].x,&tr[i].y); 60 p[i+1]=tr[i]; //初始化边界 61 } 62 tr[n]=tr[0]; 63 p[n+1]=p[1];p[0]=p[n]; 64 m=n; 65 double a,b,c; 66 for(i=0;i<n;i++) 67 { 68 a=tr[i+1].y-tr[i].y; //计算出相邻两点所在直线ax+by+c=0 69 b=tr[i].x-tr[i+1].x; 70 c=tr[i+1].x*tr[i].y-tr[i].x*tr[i+1].y; 71 cut(a,b,c); 72 } 73 printf("Floor #%d\n",t++); 74 if(!m) puts("Surveillance is impossible.");//这里如果有一个点,或者一条线段都可以,所以判断m是不是等于0就行了,不用判断面积 75 else 76 puts("Surveillance is possible."); 77 printf("\n"); 78 } 79 return 0; 80 }