• 计算几何板子题【2019牛客国庆集训派对day7——三角形和矩形】【多边形相交的面积】


    链接:https://ac.nowcoder.com/acm/contest/1112/J
    来源:牛客网

    题目描述

    Bobo 有一个三角形和一个矩形,他想求他们交的面积。
    具体地,三角形和矩形由 8 个整数 x1,y1,x2,y2,x3,y3,x4,y4x_1, y_1, x_2, y_2, x_3, y_3, x_4, y_4x1,y1,x2,y2,x3,y3,x4,y4 描述。
    表示三角形的顶点坐标是 (x1,y1),(x1,y2),(x2,y1)(x_1, y_1), (x_1, y_2), (x_2, y_1)(x1,y1),(x1,y2),(x2,y1),
    矩形的顶点坐标是 (x3,y3),(x3,y4),(x4,y4),(x4,y3)(x_3, y_3), (x_3, y_4), (x_4, y_4), (x_4, y_3)(x3,y3),(x3,y4),(x4,y4),(x4,y3).

    输入描述:

    输入包含不超过 30000 组数据。
    每组数据的第一行包含 4 个整数 x1,y1,x2,y2x_1, y_1, x_2, y_2x1,y1,x2,y2 (x1≠x2,y1≠y2x_1 eq x_2, y_1 eq y_2x1=x2,y1=y2).
    第二行包含 4 个整数 x3,y3,x4,y4x_3, y_3, x_4, y_4x3,y3,x4,y4 (x3<x4,y3<y4x_3 < x_4, y_3 < y_4x3<x4,y3<y4).
    (0≤xi,yi≤1040 leq x_i, y_i leq 10^40xi,yi104)

    输出描述:

    对于每组数据,输出一个实数表示交的面积。绝对误差或相对误差小于 10−610^{-6}106 即认为正确。
    示例1

    输入

    复制
    1 1 3 3
    0 0 2 2

    输出

    复制
    1.00000000
    示例2

    输入

    复制
    0 3 3 1
    0 0 2 2

    输出

    复制
    0.75000000
    示例3

    输入

    复制
    4462 1420 2060 2969
    4159 257 8787 2970

    输出

    复制
    439744.13967527
    AC代码:
      1 /* 
      2  * 多边形的交,多边形的边一定是要按逆时针方向给出 
      3  * 还要判断是凸包还是凹包,调用相应的函数 
      4  * 面积并,只要和面积减去交即可 
      5  */  
      6 #include <bits/stdc++.h>  
      7 using namespace std;  
      8   
      9 const int maxn = 300;  
     10 const double eps = 1e-8;  
     11 int dcmp(double x)  
     12 {  
     13     if(x > eps) return 1;  
     14     return x < -eps ? -1 : 0;  
     15 }  
     16 struct Point  
     17 {  
     18     double x, y;  
     19 };  
     20 double cross(Point a,Point b,Point c) ///叉积  
     21 {  
     22     return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);  
     23 }  
     24 Point intersection(Point a,Point b,Point c,Point d)  
     25 {  
     26     Point p = a;  
     27     double t =((a.x-c.x)*(c.y-d.y)-(a.y-c.y)*(c.x-d.x))/((a.x-b.x)*(c.y-d.y)-(a.y-b.y)*(c.x-d.x));  
     28     p.x +=(b.x-a.x)*t;  
     29     p.y +=(b.y-a.y)*t;  
     30     return p;  
     31 }  
     32 //计算多边形面积  
     33 double PolygonArea(Point p[], int n)  
     34 {  
     35     if(n < 3) return 0.0;  
     36     double s = p[0].y * (p[n - 1].x - p[1].x);  
     37     p[n] = p[0];  
     38     for(int i = 1; i < n; ++ i)  
     39         s += p[i].y * (p[i - 1].x - p[i + 1].x);  
     40     return fabs(s * 0.5);  
     41 }  
     42 double CPIA(Point a[], Point b[], int na, int nb)//ConvexPolygonIntersectArea  
     43 {  
     44     Point p[20], tmp[20];  
     45     int tn, sflag, eflag;  
     46     a[na] = a[0], b[nb] = b[0];  
     47     memcpy(p,b,sizeof(Point)*(nb + 1));  
     48     for(int i = 0; i < na && nb > 2; i++)  
     49     {  
     50         sflag = dcmp(cross(a[i + 1], p[0],a[i]));  
     51         for(int j = tn = 0; j < nb; j++, sflag = eflag)  
     52         {  
     53             if(sflag>=0) tmp[tn++] = p[j];  
     54             eflag = dcmp(cross(a[i + 1], p[j + 1],a[i]));  
     55             if((sflag ^ eflag) == -2)  
     56                 tmp[tn++] = intersection(a[i], a[i + 1], p[j], p[j + 1]); ///求交点  
     57         }  
     58         memcpy(p, tmp, sizeof(Point) * tn);  
     59         nb = tn, p[nb] = p[0];  
     60     }  
     61     if(nb < 3) return 0.0;  
     62     return PolygonArea(p, nb);  
     63 }  
     64 double SPIA(Point a[], Point b[], int na, int nb)///SimplePolygonIntersectArea 调用此函数  
     65 {  
     66     int i, j;  
     67     Point t1[4], t2[4];  
     68     double res = 0, num1, num2;  
     69     a[na] = t1[0] = a[0], b[nb] = t2[0] = b[0];  
     70     for(i = 2; i < na; i++)  
     71     {  
     72         t1[1] = a[i-1], t1[2] = a[i];  
     73         num1 = dcmp(cross(t1[1], t1[2],t1[0]));  
     74         if(num1 < 0) swap(t1[1], t1[2]);  
     75         for(j = 2; j < nb; j++)  
     76         {  
     77             t2[1] = b[j - 1], t2[2] = b[j];  
     78             num2 = dcmp(cross(t2[1], t2[2],t2[0]));  
     79             if(num2 < 0) swap(t2[1], t2[2]);  
     80             res += CPIA(t1, t2, 3, 3) * num1 * num2;  
     81         }  
     82     }  
     83    // res=fabs(res);
     84     return res;  
     85 }  
     86 Point p1[maxn], p2[maxn];  
     87 int n1, n2;  
     88 int main()  
     89 {  
     90            int x1,x2,x3,x4,y1,y2,y3,y4;
     91        while(~    scanf("%d %d %d %d",&x1,&y1,&x2,&y2)){
     92            
     93        
     94            scanf("%d %d %d %d",&x3,&y3,&x4,&y4);
     95               p1[0].x = x1;p1[0].y = y1;
     96         p1[1].x = x1;p1[1].y = y2;
     97         p1[2].x = x2;p1[2].y = y1;
     98 
     99         p2[0].x = x3;p2[0].y = y3;
    100         p2[1].x = x3;p2[1].y = y4;
    101         p2[2].x = x4;p2[2].y = y4;
    102         p2[3].x = x4;p2[3].y = y3;
    103          double s1 = SPIA(p1,p2,3,4);
    104         printf("%.8f
    ",fabs(s1));
    105     }
    106     return 0;  
    107 }  
  • 相关阅读:
    atitit...触发器机制 ltrigger mechanism sumup .的总结O8f
    atitit. 集合groupby 的实现(2)---自定义linq查询--java .net php
    atitit. groupby linq的实现(1)-----linq框架选型 java .net php
    atitit.j2ee 1.5 1.6 的不同跟 Servlet 3.0新特性总结
    Atitit. 常用街机系统and 模拟器总结 snk neo geo cps mame sfc smc
    atitit. access token是什么??微信平台公众号开发access_token and Web session保持状态机制
    atitit.二进制数据无损转字符串网络传输
    atitit.压缩算法 ZLib ,gzip ,zip 最佳实践 java .net php
    Atitit.现实生活中最好使用的排序方法-----ati排序法总结
    atitit.修复xp 操作系统--重装系统--保留原来文件不丢失
  • 原文地址:https://www.cnblogs.com/pengge666/p/11650001.html
Copyright © 2020-2023  润新知