zoukankan      html  css  js  c++  java
  • HDU3060 Area2 简单多边形面积并

    不需要正规的三角剖分,用求多边形面积的思想,从一点出发连接多边形的边得到很多三
    角形,三角形有向边方向决定有向面积有正有负,相加得到多边形面积的正值或负值。
    把两个多边形都分成若干这样的三角形,求每对三角形的交,根据两三角形有向边顺逆时
    针关系确定相交面积的正负号,最后两多边形面积和减去相交面积。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<math.h>
      5 #include<algorithm>
      6 const int maxn = 555;
      7 const int maxisn = 10;
      8 const double eps = 1e-8;
      9 const double pi = acos(-1.0);
     10 int dcmp(double x)
     11 {
     12     if(x > eps) return 1;
     13     return x < -eps ? -1 : 0;
     14 }
     15 inline double min(double a, double b)
     16 {return a < b ? a : b;}
     17 inline double max(double a, double b)
     18 {return a > b ? a : b;}
     19 inline double Sqr(double x)
     20 {return x * x;}
     21 struct Point
     22 {
     23     double x, y;
     24     Point(){x = y = 0;}
     25     Point(double a, double b)
     26     {x = a, y = b;}
     27     inline Point operator-(const Point &b)const
     28     {return Point(x - b.x, y - b.y);}
     29     inline Point operator+(const Point &b)const
     30     {return Point(x + b.x, y + b.y);}
     31     inline double dot(const Point &b)const
     32     {return x * b.x + y * b.y;}
     33     inline double cross(const Point &b, const Point &c)const
     34     {return (b.x - x) * (c.y - y) - (c.x - x) * (b.y - y);}
     35 };
     36 Point LineCross(const Point &a, const Point &b, const Point &c, const Point &d)
     37 {
     38     double u = a.cross(b, c), v = b.cross(a, d);
     39     return Point((c.x * v + d.x * u) / (u + v), (c.y * v + d.y * u) / (u + v));
     40 }
     41 double PolygonArea(Point p[], int n)
     42 {
     43     if(n < 3) return 0.0;
     44     double s = p[0].y * (p[n - 1].x - p[1].x);
     45     p[n] = p[0];
     46     for(int i = 1; i < n; ++ i)
     47         s += p[i].y * (p[i - 1].x - p[i + 1].x);
     48     return fabs(s * 0.5);
     49 }
     50 double CPIA(Point a[], Point b[], int na, int nb)//ConvexPolygonIntersectArea
     51 {
     52     Point p[maxisn], tmp[maxisn];
     53     int i, j, tn, sflag, eflag;
     54     a[na] = a[0], b[nb] = b[0];
     55     memcpy(p, b, sizeof(Point) * (nb + 1));
     56     for(i = 0; i < na && nb > 2; ++ i)
     57     {
     58         sflag = dcmp(a[i].cross(a[i + 1], p[0]));
     59         for(j = tn = 0; j < nb; ++ j, sflag = eflag)
     60         {
     61             if(sflag >= 0) tmp[tn ++] = p[j];
     62             eflag = dcmp(a[i].cross(a[i + 1], p[j + 1]));
     63             if((sflag ^ eflag) == -2)
     64                 tmp[tn ++] = LineCross(a[i], a[i + 1], p[j], p[j + 1]);
     65         }
     66         memcpy(p, tmp, sizeof(Point) * tn);
     67         nb = tn, p[nb] = p[0];
     68     }
     69     if(nb < 3) return 0.0;
     70     return PolygonArea(p, nb);
     71 }
     72 double SPIA(Point a[], Point b[], int na, int nb)//SimplePolygonIntersectArea
     73 {
     74     int i, j;
     75     Point t1[4], t2[4];
     76     double res = 0, if_clock_t1, if_clock_t2;
     77     a[na] = t1[0] = a[0], b[nb] = t2[0] = b[0];
     78     for(i = 2; i < na; ++ i)
     79     {
     80         t1[1] = a[i - 1], t1[2] = a[i];
     81         if_clock_t1 = dcmp(t1[0].cross(t1[1], t1[2]));
     82         if(if_clock_t1 < 0) std::swap(t1[1], t1[2]);
     83         for(j = 2; j < nb; ++ j)
     84         {
     85             t2[1] = b[j - 1], t2[2] = b[j];
     86             if_clock_t2 = dcmp(t2[0].cross(t2[1], t2[2]));
     87             if(if_clock_t2 < 0) std::swap(t2[1], t2[2]);
     88             res += CPIA(t1, t2, 3, 3) * if_clock_t1 * if_clock_t2;
     89         }
     90     }
     91     return PolygonArea(a, na) + PolygonArea(b, nb) - res;
     92 }
     93 Point p1[maxn], p2[maxn];
     94 int n1, n2;
     95 int main()
     96 {
     97     int i;
     98     while(scanf("%d%d", &n1, &n2) != EOF)
     99     {
    100         for(i = 0; i < n1; ++ i) scanf("%lf%lf", &p1[i].x, &p1[i].y);
    101         for(i = 0; i < n2; ++ i) scanf("%lf%lf", &p2[i].x, &p2[i].y);
    102         printf("%.2f\n", SPIA(p1, p2, n1, n2) + eps);
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    mysql通过data目录恢复数据库
    CentOS安装TortoiseSVN svn 客户端
    CentOS上安装Node.js
    PHP--进行模块化设计
    PHP开发绝对不能违背的安全铁则
    达内培训:php在线端口扫描器
    使用 PHP 限制下载速度
    使用无限生命期Session的方法
    使用php作linux自动执行脚本
    腾讯星座运势api
  • 原文地址:https://www.cnblogs.com/CSGrandeur/p/2675237.html
Copyright © 2011-2022 走看看