首页 > 代码库 > ecnu1624求交集多边形面积
ecnu1624求交集多边形面积
链接
本来在刷hdu的一道题。。一直没过,看到谈论区发现有凹的,我这种方法只能过凸多边形的相交面积。。
就找来这道题试下水。
两个凸多边形相交的部分要么没有 要么也是凸多边形,那就可以把这部分单独拿出来极角排序、叉积求面积。这部分的顶点要么p在q内的顶点,要么是q在p内的顶点,要么是两凸多边形的交点。
用到了点在多边形内的判定模板。
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 10000 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 struct point 18 { 19 double x,y; 20 point(double x=0,double y =0 ):x(x),y(y) {} 21 } p[N],q[N],ch[N],chh[N]; 22 typedef point pointt; 23 point operator -(point a,point b) 24 { 25 return point(a.x-b.x,a.y-b.y); 26 } 27 int dcmp(double x) 28 { 29 if(fabs(x)<eps) return 0; 30 return x<0?-1:1; 31 } 32 double cross(point a,point b) 33 { 34 return a.x*b.y-a.y*b.x; 35 } 36 double dis(point a) 37 { 38 return sqrt(a.x*a.x+a.y*a.y); 39 } 40 double getarea(point p[],int n) 41 { 42 int i; 43 double area = 0; 44 for(i =0 ; i < n-1; i++) 45 area+=cross(p[i]-p[0],p[i+1]-p[0]); 46 area = fabs(area)/2; 47 return area; 48 } 49 bool PtInPolygon (point p, point ptPolygon[], int nCount) 50 { 51 int i,nCross = 0; 52 for(i =0 ; i< nCount ; i++) 53 { 54 point p1 = ptPolygon[i]; 55 point p2 = ptPolygon[(i+1)%nCount]; 56 if(dcmp(p1.y-p2.y)==0) continue; 57 if(dcmp(p.y-min(p1.y,p2.y))<0) continue; 58 if(dcmp(p.y-max(p1.y,p2.y))>=0) continue; 59 double x = (double)(p.y-p1.y)*(double)(p2.x-p1.x)/(double)(p2.y-p1.y)+p1.x; 60 if(x>p.x) nCross++; 61 } 62 return (nCross % 2 == 1); 63 } 64 bool segprointer(point a1,point a2,point b1,point b2) 65 { 66 double c1 = cross(a2-a1,b1-a1),c2 = cross(a2-a1,b2-a1); 67 double c3 = cross(b2-b1,a1-b1),c4 = cross(b2-b1,a2-b1); 68 return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0; 69 } 70 bool intersection1(point p1, point p2, point p3, point p4, point& p) // 直线相交 71 { 72 double a1, b1, c1, a2, b2, c2, d; 73 a1 = p1.y - p2.y; 74 b1 = p2.x - p1.x; 75 c1 = p1.x*p2.y - p2.x*p1.y; 76 a2 = p3.y - p4.y; 77 b2 = p4.x - p3.x; 78 c2 = p3.x*p4.y - p4.x*p3.y; 79 d = a1*b2 - a2*b1; 80 if (!dcmp(d)) return false; 81 p.x = (-c1*b2 + c2*b1) / d; 82 p.y = (-a1*c2 + a2*c1) / d; 83 return true; 84 } 85 double mul(point p0,point p1,point p2) 86 { 87 return cross(p1-p0,p2-p0); 88 } 89 90 bool cmp(point a,point b) 91 { 92 if(dcmp(mul(ch[0],a,b))==0) 93 return dis(a-ch[0])<dis(b-p[0]); 94 else 95 return dcmp(mul(ch[0],a,b))>0; 96 } 97 bool cmpp(point a,point b) 98 { 99 if(dcmp(a.x-b.x)==0) return a.y<b.y;100 return a.x<b.x;101 }102 int main()103 {104 int n,m,i,j;105 while(scanf("%d",&n)!=EOF)106 {107 108 for(i = 0; i < n ; i++)109 scanf("%lf%lf",&p[i].x,&p[i].y);110 p[n] = p[0];111 scanf("%d",&m);112 for(i = 0; i < m; i++)113 scanf("%lf%lf",&q[i].x,&q[i].y);114 q[m] = q[0];115 int g = 0;116 for(i = 0; i < n ; i ++)117 {118 if(PtInPolygon(p[i],q,m))119 ch[g++] = p[i];120 }121 for(i = 0; i < m ; i ++)122 {123 if(PtInPolygon(q[i],p,n))124 ch[g++] = q[i];125 }126 for(i = 0 ; i < n; i++)127 {128 for(j = 0; j < m ; j++)129 {130 if(segprointer(p[i],p[i+1],q[j],q[j+1])==0) continue;131 point pp;132 if(!intersection1(p[i],p[i+1],q[j],q[j+1],pp))continue;133 ch[g++] = pp;134 }135 }136 double ans = 0;//getarea(p,n)+getarea(q,m);137 if(g==0)138 ans = 0;139 else140 {141 int k = 0,o=0;142 sort(ch,ch+g,cmpp);143 chh[o++] = ch[0];144 for(i = 1; i < g; i++)145 if(dcmp(ch[i].x-ch[i-1].x)==0&&dcmp(ch[i].y-ch[i-1].y)==0)146 continue;147 else chh[o++] = ch[i];148 g = o;149 for(i = 1; i < g ; i ++)150 {151 if(dcmp(chh[i].y-chh[k].y)<0||(dcmp(chh[i].y-chh[k].y)==0&&dcmp(chh[i].x-chh[k].x)<0))152 k = i;153 }154 if(k!=0) swap(chh[k],chh[0]);155 sort(chh+1,chh+g,cmp);156 ans = getarea(chh,g);157 }158 printf("%.2f\n",ans);159 }160 return 0;161 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。