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         else

140         {

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 }
View Code

 

你可能感兴趣的:(交集)