裸的半平面交,关于半平面交的入门请看神犇博客:http://blog.csdn.net/accry/article/details/6070621
然而代码我是抄的proverbs的……
大体思路是这样的:(一个增量算法)
维护一个当前的半平面交的点集,每次用一条直线去cut它:
依次枚举“凸包”上的点,点在直线左边则保留下来了,否则就丢掉=。=
同时判一下如果“凸包”上连续的两个点分别在直线两侧,就加入这条“凸包”上的线段与直线的交点= =
然后新点集get!
最后求个面积>_>
有个trick是如果给的顺序是顺时针,需要反转成逆时针(用算多边形面积的方法就可以判断,如果是逆时针,面积为正)
1 Source Code 2 Problem: 1279 User: sdfzyhy 3 Memory: 720K Time: 32MS 4 Language: G++ Result: Accepted 5 6 Source Code 7 8 //POJ 1279 9 #include<cmath> 10 #include<vector> 11 #include<cstdio> 12 #include<cstring> 13 #include<cstdlib> 14 #include<iostream> 15 #include<algorithm> 16 #define rep(i,n) for(int i=0;i<n;++i) 17 #define F(i,j,n) for(int i=j;i<=n;++i) 18 #define D(i,j,n) for(int i=j;i>=n;--i) 19 #define pb push_back 20 using namespace std; 21 inline int getint(){ 22 int v=0,sign=1; char ch=getchar(); 23 while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();} 24 while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();} 25 return v*sign; 26 } 27 const int N=1e5+10; 28 const double INF=1e9; 29 typedef long long LL; 30 /******************tamplate*********************/ 31 const double eps=1e-8; 32 int dcmp(double x){return x>eps ? 1 : x<-eps ? -1 : 0;} 33 struct Poi{ 34 double x,y; 35 Poi(){} 36 Poi(double x,double y):x(x),y(y){} 37 void read(){scanf("%lf%lf",&x,&y);} 38 }p[N],tp[N],s[N],o; 39 typedef Poi Vec; 40 Vec operator - (const Poi&a,const Poi &b){return Vec(a.x-b.x,a.y-b.y);} 41 42 int n; 43 double Cross(const Vec &a,const Vec &b){return a.x*b.y-a.y*b.x;} 44 double getarea(Poi *p,int n){ 45 double ans=0.0; 46 F(i,1,n) ans+=Cross(p[i]-o,p[i+1]-o); 47 return ans*0.5; 48 } 49 Poi getpoint(const Poi &a,const Poi &b,const Poi &c,const Poi &d){ 50 Poi ans,tmp=b-a; 51 double k1=Cross(d-a,c-a),k2=Cross(c-b,d-b); 52 ans.x=a.x+tmp.x*k1/(k1+k2); 53 ans.y=a.y+tmp.y*k1/(k1+k2); 54 return ans; 55 } 56 57 void init(){ 58 n=getint(); 59 F(i,1,n) p[i].read(); 60 p[n+1]=p[1]; 61 } 62 void Change(){ 63 F(i,1,n>>1) swap(p[i],p[n-i+1]); 64 p[n+1]=p[1]; 65 } 66 void getcut(){ 67 tp[1]=tp[5]=Poi(-INF,-INF); 68 tp[2]=Poi(INF,-INF); 69 tp[3]=Poi(INF,INF); 70 tp[4]=Poi(-INF,INF); 71 int num=4,size=0; 72 F(i,1,n){ 73 size=0; 74 F(j,1,num){ 75 if (dcmp(Cross(p[i+1]-p[i],tp[j]-p[i]))>=0) 76 s[++size]=tp[j]; 77 if (dcmp(Cross(p[i+1]-p[i],tp[j]-p[i]) * 78 Cross(p[i+1]-p[i],tp[j+1]-p[i]))<0) 79 s[++size]=getpoint(p[i],p[i+1],tp[j],tp[j+1]); 80 } 81 s[size+1]=s[1]; 82 F(j,1,size+1) tp[j]=s[j]; 83 num=size; 84 } 85 n=num; 86 } 87 int main(){ 88 #ifndef ONLINE_JUDGE 89 freopen("1279.in","r",stdin); 90 freopen("1279.out","w",stdout); 91 #endif 92 int T=getint(); 93 while(T--){ 94 init(); 95 if (dcmp(getarea(p,n))<=0) Change(); 96 getcut(); 97 printf("%.2f\n",fabs(getarea(s,n))); 98 } 99 return 0; 100 }