• 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
    ",ans);
    159     }
    160     return 0;
    161 }
    View Code
  • 相关阅读:
    .NET平台下,初步认识AutoMapper
    python 二分查找算法
    01背包问题(动态规划)python实现
    NSSM安装服务
    iis .apk .ipa下载设置
    动态规划 转载
    leetcode 5 查找最长的回文子串
    [DEncrypt] MySecurity--安全加密/Base64/文件加密 (转载)
    [DEncrypt] HashEncode--哈希加密帮助类 (转载)
    [DEncrypt] Encrypt--加密/解密/MD5加密 (转载)
  • 原文地址:https://www.cnblogs.com/shangyu/p/3905194.html
Copyright © 2020-2023  润新知