是半平面交模板题
逆时针给出 n 个凸多边形的顶点坐标,求它们交的面积。
例如 n=2 时,两个凸多边形如下图:

则相交部分的面积为 5.233。
输入格式
第一行有一个整数 n,表示凸多边形的个数,以下依次描述各个多边形。
第 i 个多边形的第一行包含一个整数 mi,表示多边形的边数,以下 mi 行每行两个整数,逆时针给出各个顶点的坐标。
#include<iostream> #include<cmath> #include<math.h> #include<algorithm> using namespace std; #define x first #define y second using namespace std; typedef pair<double,double>PDD; const int N=510; const double eps = 1e-8; int cnt=0; struct Line { PDD st,ed; }line[N]; PDD pg[N],ans[N]; int q[N]; int sign(double x) { if(fabs(x)<eps) return 0; if(x<0) return 0; return 1; } int dcmp(double x,double y) { if(fabs(x-y)<eps) return 0; if(x<y) return -1; return 1; } double getangle(const Line& a) { return atan2(a.ed.y-a.st.y,a.ed.x-a.st.x); } PDD operator - (PDD a,PDD b) { return {a.x-b.x,a.y-b.y}; } double cross(PDD a,PDD b) { return a.x*b.y-a.y*b.x; } double area(PDD a,PDD b,PDD c) { return cross(b-a,c-a); } bool cmp(const Line& a,const Line& b) { double A=getangle(a),B=getangle(b); if(!dcmp(A,B)) return area(a.st,a.ed,b.ed)<0; return A<B; } PDD getlineintersection(PDD p,PDD v,PDD q,PDD w) { auto u=p-q; double t=cross(w,u)/cross(v,w); return {p.x+v.x*t,p.y+v.y*t}; } PDD getlineintersection(Line a,Line b) { return getlineintersection(a.st,a.ed-a.st,b.st,b.ed-b.st); } bool onright(Line& a,Line& b,Line& c) { auto o=getlineintersection(b,c); return sign(area(a.st,a.ed,o))<=0; } double halfplaneintersection() { sort(line,line+cnt,cmp); int hh=0,tt=-1; for(int i=0;i<cnt;i++) { if(i&&!dcmp(getangle(line[i]),getangle(line[i-1]))) continue; while (hh+1<=tt&&onright(line[i],line[q[tt - 1]],line[q[tt]])) tt--; while (hh+1<=tt&&onright(line[i],line[q[hh]],line[q[hh + 1]])) hh++; q[++tt]=i; } while(hh+1<=tt&&onright(line[q[hh]],line[q[tt-1]],line[q[tt]])) tt--; while(hh+1<=tt&&onright(line[q[tt]],line[q[hh]],line[q[hh+1]])) hh++; q[++tt]=q[hh]; int k=0; for(int i=hh;i<tt;i++) { ans[k++]=getlineintersection(line[q[i]],line[q[i+1]]); } double res=0; for(int i=1;i+1<k;i++) { res+=area(ans[0],ans[i],ans[i+1]); } return res/2; } int main() { int n,m; cin>>n; while(n--) { cin>>m; for(int i=0;i<m;i++) { cin>>pg[i].x>>pg[i].y; } for(int i=0;i<m;i++) { line[cnt++] = {pg[i],pg[(i+1)%m]}; } } double res=halfplaneintersection(); printf("%.3lf\n",res); return 0; }
本文来自博客园,作者:magicat,转载请注明原文链接:https://www.cnblogs.com/magicat/p/15559073.html
浙公网安备 33010602011771号