Art Gallery POJ - 1279 (半平面交,内核面积)
Art Gallery
思路:半平面交求多边形内核
1 #include<iostream> 2 #include<fstream> 3 #include<iomanip> 4 #include<cstdio> 5 #include<cstring> 6 #include<algorithm> 7 #include<cstdlib> 8 #include<cmath> 9 #include<set> 10 #include<map> 11 #include<queue> 12 #include<stack> 13 #include<string> 14 #include<vector> 15 #include<sstream> 16 #include<cassert> 17 #define LL long long 18 #define eps 1e-7 19 #define inf 1<<30 20 using namespace std; 21 struct Point{ 22 double x,y; 23 }p[1505],tp[1505],q[1505]; 24 //叉积 25 double xmul(Point p0,Point p1,Point p2){ 26 return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x); 27 } 28 //通过两点,确定直线方程 29 double Get_equation(Point p1,Point p2,double &a,double &b,double &c){ 30 a=p2.y-p1.y; 31 b=p1.x-p2.x; 32 c=p2.x*p1.y-p1.x*p2.y; 33 } 34 //求交点 35 Point Intersection(Point p1,Point p2,double a,double b,double c){ 36 double u=fabs(a*p1.x+b*p1.y+c); 37 double v=fabs(a*p2.x+b*p2.y+c); 38 Point t; 39 t.x=(p1.x*v+p2.x*u)/(u+v);t.y=(p1.y*v+p2.y*u)/(u+v); 40 return t; 41 } 42 //求面积,正为顺时针,和叉积写法有关 43 double Get_area(Point p[],int n){ 44 double area=0; 45 for(int i=2;i<n;i++) 46 area+=xmul(p[1],p[i],p[i+1]); 47 return -area/2.0; 48 } 49 //改变顺序 50 double Change_dir(Point p[],int n){ 51 for(int i=1;i<=n/2;i++) 52 swap(p[i],p[n+1-i]); 53 } 54 //加入一条边,切割 55 void Cut(double a,double b,double c,Point p[],int &cnt){ 56 int tmp=0; 57 for(int i=1;i<=cnt;i++){ 58 //当前点就在右侧 59 if(a*p[i].x+b*p[i].y+c>-eps) tp[++tmp]=p[i]; 60 else{ 61 //前一个点在右侧,产生交点 62 if(a*p[i-1].x+b*p[i-1].y+c>eps) 63 tp[++tmp]=Intersection(p[i-1],p[i],a,b,c); 64 //同理 65 if(a*p[i+1].x+b*p[i+1].y+c>eps) 66 tp[++tmp]=Intersection(p[i],p[i+1],a,b,c); 67 } 68 } 69 for(int i=1;i<=tmp;i++) 70 p[i]=tp[i]; 71 p[0]=p[tmp];p[tmp+1]=p[1]; 72 cnt=tmp; 73 } 74 void slove(Point p[],int n){ 75 //默认顺时针,通过面积判断一下 76 if(Get_area(p,n)<eps) Change_dir(p,n); 77 p[0]=p[n];p[n+1]=p[1]; 78 // 79 for(int i=0;i<=n+1;i++) q[i]=p[i]; 80 int cnt=n; 81 for(int i=1;i<=n;i++){ 82 double a,b,c; 83 Get_equation(q[i],q[i+1],a,b,c); 84 Cut(a,b,c,p,cnt); 85 } 86 printf("%.2f\n",fabs(Get_area(p,cnt))); 87 } 88 int main(){ 89 int t,n; 90 scanf("%d",&t); 91 while(t--){ 92 scanf("%d",&n); 93 for(int i=1;i<=n;i++) 94 scanf("%lf%lf",&p[i].x,&p[i].y); 95 slove(p,n); 96 } 97 return 0; 98 }