• 【无聊放个模板系列】 半平面交


    求半平面交的面积

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define Maxn 1100
    
    struct P {double x,y;};
    struct L {P a,b;double slop;}l[Maxn];
    //半平面只方向向量a->b的左部分
    //slop 极角
    int cnt;
    
    P operator - (P x,P y)
    {
        P tt;
        tt.x=x.x-y.x;
        tt.y=x.y-y.y;
        return tt;
    }
    
    P operator + (P x,P y)
    {
        P tt;
        tt.x=x.x+y.x;
        tt.y=x.y+y.y;
        return tt;
    }
    
    double Dot(P x,P y) {return x.x*y.x+x.y*y.y;}
    double Cross(P x,P y) {return x.x*y.y-x.y*y.x;}
    
    bool operator < (L a,L b)
    {
        if(a.slop!=b.slop)return a.slop<b.slop;
        return Cross(a.b-a.a,b.b-a.a)>0;
    }
    
    P operator * (P X,double y)
    {
        P tt;
        tt.x=X.x*y;
        tt.y=X.y*y;
        return tt;
    }
    
    P a[Maxn];
    L q[Maxn];
    int tot;
    
    P inter(L a,L b)
    {
        P X=a.a-a.b,Y=b.a-b.b,nw;
        double tt;
        nw=b.a-a.a;
        tt=Cross(nw,X)/Cross(X,Y);
        P ans=b.a+Y*tt;
        return ans;
    }
    
    bool jud(L a,L b,L c)
    {
        P p=inter(a,b);
        return Cross(c.b-c.a,p-c.a)<0;
    }
    
    void opp()
    {
        for(int i=1;i<=cnt;i++)
        {
            printf("%.2lf %.2lf %.2lf %.2lf = %.2lf 
    ",l[i].a.x,l[i].a.y,l[i].b.x,l[i].b.y,l[i].slop);
        }
        printf("
    ");
    }
    
    void output()
    {
        for(int i=1;i<=tot;i++) printf("%2lf %.2lf
    ",a[i].x,a[i].y);
        printf("
    ");
    }
    
    void op(int L,int R)
    {
        for(int i=L;i<=R;i++)
            printf("%lf %lf %lf %lf
    ",l[i].a.x,l[i].a.y,l[i].b.x,l[i].b.y);
        printf("
    ");
    }
    
    void ffind()
    {
        for(int i=1;i<=cnt;i++)
          l[i].slop=atan2(l[i].b.y-l[i].a.y,l[i].b.x-l[i].a.x);
        sort(l+1,l+1+cnt);
        
        // opp();
        
        int L=1,R=0;
        //去重?
        tot=0;
        for(int i=1;i<=cnt;i++)
        {
            if(l[i].slop!=l[i-1].slop) tot++;
            l[tot]=l[i];
        }
        cnt=tot;tot=0;
        // opp();
        q[++R]=l[1];q[++R]=l[2];
        for(int i=3;i<=cnt;i++)
        {
            while(L<R&&jud(q[R-1],q[R],l[i])) R--;
            while(L<R&&jud(q[L+1],q[L],l[i])) L++;
            q[++R]=l[i];
            // op(L,R);
        }
    	if(L<R&&jud(q[R-1],q[R],q[L])) R--;
            op(L,R);
        q[R+1]=q[L];
        for(int i=L;i<=R;i++)
          a[++tot]=inter(q[i],q[i+1]);
      // output();
    }
    
    void init()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lf%lf%lf%lf
    ",&l[i].a.x,&l[i].a.y,&l[i].b.x,&l[i].b.y);
        }
        cnt=n;
    }
    
    void get_area()
    {
        double ans=0;
        for(int i=1;i<tot;i++)
        {
            ans+=Cross(a[i],a[i+1]);
        }
        ans+=Cross(a[tot],a[1]);
        if(tot<3) ans=0;
        printf("%.3lf
    ",ans/2);
    }
    
    int main()
    {
        init();
        ffind();
        get_area();
        return 0;
    }
    

      

    没有删调试的。

    输入半平面,输出面积。

    样例:

    6
    4 5 2 0
    9 2 5 6
    3 1 9 5
    5 1 7 5
    8 2 9 4
    5 7 3 5

    输出:

    10.459

    2016-12-25 14:39:14

  • 相关阅读:
    Typora设置插入图片居左
    android模拟器横屏后屏幕不自动旋转的问题
    (转) word: 通过Office 2007发布博客
    Typora导出文件到github指令
    c++函数式编程 笔记
    关于PostMan的一个坑
    VS Code中Golang远程开发的调试和测试
    在GoLand/Pycharm中安装Copilot时遇到“waiting for github authentication”
    安装kubetest报错 "ambiguous import: found package cloud.google.com/go/storage in multiple modules:"
    window 客户端抓包详解
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6219514.html
Copyright © 2020-2023  润新知