hdu3060Area2(任意多边形相交面积)

链接

多边形的面积求解是通过选取一个点(通常为原点或者多边形的第一个点)和其它边组成的三角形的有向面积。

对于两个多边形的相交面积就可以通过把多边形分解为三角形,求出三角形的有向面积递加。三角形为凸多边形,因此可以直接用凸多边形相交求面积的模板。

凸多边形相交后的部分肯定还是凸多边形,所以只需要判断哪些点是相交部分上的点,最后求下面积。

  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 510
 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];
 22 typedef point pointt;
 23 pointt operator + (point a,point b)
 24 {
 25     return point(a.x+b.x,a.y+b.y);
 26 }
 27 pointt operator - (point a,point b)
 28 {
 29     return point(a.x-b.x,a.y-b.y);
 30 }
 31 int dcmp(double x)
 32 {
 33     if(fabs(x)<eps) return 0;
 34     else return x<0?-1:1;
 35 }
 36 bool operator == (const point &a,const point &b)
 37 {
 38     return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
 39 }
 40 double cross(point a,point b)
 41 {
 42     return a.x*b.y-a.y*b.x;
 43 }
 44 double Polyarea(point p[],int n)
 45 {
 46     if(n<3) return 0;
 47     double area = 0;
 48     for(int i = 0 ; i < n ; i++)
 49     area+=cross(p[i],p[i+1]);
 50     return fabs(area)/2;
 51 }
 52 //double Polyarea(point p[], int n)
 53 //{
 54 //    if(n < 3) return 0.0;
 55 //    double s = p[0].y * (p[n - 1].x - p[1].x);
 56 //    p[n] = p[0];
 57 //    for(int i = 1; i < n; ++ i)
 58 //        s += p[i].y * (p[i - 1].x - p[i + 1].x);
 59 //    return fabs(s * 0.5);
 60 //}
 61 bool intersection1(point p1, point p2, point p3, point p4, point& p)      // 直线相交
 62 {
 63     double a1, b1, c1, a2, b2, c2, d;
 64     a1 = p1.y - p2.y;
 65     b1 = p2.x - p1.x;
 66     c1 = p1.x*p2.y - p2.x*p1.y;
 67     a2 = p3.y - p4.y;
 68     b2 = p4.x - p3.x;
 69     c2 = p3.x*p4.y - p4.x*p3.y;
 70     d = a1*b2 - a2*b1;
 71     if (!dcmp(d))    return false;
 72     p.x = (-c1*b2 + c2*b1) / d;
 73     p.y = (-a1*c2 + a2*c1) / d;
 74     return true;
 75 }
 76 
 77 double convexpolygon(point p[],point q[],int n,int m)
 78 {
 79     int i,j;
 80     point ch[20],cnt[20];
 81     p[n] = p[0],q[m] = q[0];
 82     memcpy(ch,q,sizeof(point)*(m+1));
 83     int f2,g = 0 ;
 84     for(i = 0 ;i < n; i++)
 85     {
 86         int f1 = dcmp(cross(p[i+1]-p[i],ch[0]-p[i]));
 87         g = 0 ;
 88         for(j = 0 ;j < m; j++,f1 = f2)
 89         {
 90             if(f1>=0) cnt[g++] = ch[j];
 91             f2 = dcmp(cross(p[i+1]-p[i],ch[j+1]-p[i]));
 92             if((f1^f2)==-2)
 93             {
 94                 point pp;
 95                 intersection1(p[i],p[i+1],ch[j],ch[j+1],pp);
 96                 cnt[g++] = pp;
 97             }
 98         }
 99         cnt[g] = cnt[0];
100         memcpy(ch,cnt,sizeof(point)*(g+1));
101         m = g;
102     }
103     return Polyarea(ch,g);
104 }
105 double solve(point p[],point q[],int n,int m)
106 {
107     int i,j;
108     double area = 0;
109     point tp[10],tq[10];
110     tp[0] = p[0];tq[0] = q[0];
111     for(i = 1 ;i < n-1; i++)
112     {
113         int k1 = dcmp(cross(p[i]-p[0],p[i+1]-p[0]));
114         tp[1] = p[i],tp[2] = p[i+1];
115         if(k1 < 0) swap(tp[1],tp[2]);
116 
117         for(j = 1 ;j < m-1 ;j++)
118         {
119             tq[1] = q[j],tq[2] = q[j+1];
120             int k2 = dcmp(cross(q[j]-q[0],q[j+1]-q[0]));
121             if(k2<0) swap(tq[1],tq[2]);
122 
123             area+=convexpolygon(tp,tq,3,3)*k1*k2;
124         }
125     }
126     return Polyarea(p,n)+Polyarea(q,m)-area;
127 }
128 int main()
129 {
130     int n,m,i;
131     while(scanf("%d%d",&n,&m)!=EOF)
132     {
133         for(i = 0; i < n ;i++)
134         {
135             scanf("%lf%lf",&p[i].x,&p[i].y);
136         }
137         for(i = 0; i < m; i++)
138         {
139             scanf("%lf%lf",&q[i].x,&q[i].y);
140         }
141         p[n] = p[0],q[m] = q[0];
142         double ans = solve(p,q,n,m);
143         printf("%.2f\n",ans);
144     }
145     return 0;
146 }
View Code

 

posted @ 2014-08-12 10:13  _雨  阅读(1160)  评论(0编辑  收藏  举报