zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    144     }
    145     return 0;
    146 }
    View Code
  • 相关阅读:
    堆、栈、值类型、引用类型分析总结 Part 2
    DataGridView打印
    学习使用ArrayList
    C#与Java之比较
    【原创】串口通信测试程序
    彩色校验码的制作
    C#中使用进度条
    【原创】 Ajax之ModalPopup编程实例
    常用正则表达式
    堆、栈、值类型、引用类型分析总结 Part 1
  • 原文地址:https://www.cnblogs.com/shangyu/p/3906635.html
Copyright © 2011-2022 走看看