zoukankan      html  css  js  c++  java
  • 计算几何板子

    #include <iostream>
    #include <string.h>
    #include <queue>
    #include <stdio.h>
    #include <algorithm>
    #include <math.h>
    typedef long long ll;
    using namespace std;
    const int maxn=1e4+10;
    const int mod=998244353;
    using namespace std;
    
    const ll eps = 1e-8;
    int sgn(ll x)
    {
        if(fabs(x) < eps)return 0;
        if(x < 0) return -1;
        return 1;
    }
    struct Point
    {
        ll x,y;
        Point(){}
        Point(ll _x,ll _y)
        {
            x = _x;y = _y;
        }
        Point operator -(const Point &b)const
        {
            return Point(x - b.x,y - b.y);
        }
        ll operator ^(const Point &b)const
        {
            return x*b.y - y*b.x;
        }
        ll operator *(const Point &b)const
        {
            return x*b.x + y*b.y;
        }
        ll operator ==(const Point &b)const
        {
            return x==b.x&&y==b.y;
        }
    };
    struct Line { Point s,e; Line(){} Line(Point _s,Point _e) { s = _s;e = _e; } }; ll xmult(Point p0,Point p1,Point p2) //p0p1 X p0p2 { return (p1-p0)^(p2-p0); } ll xmult(Point p0,Point p1,Point p2,Point p3) //p0p1 X p2p3 { return (p1-p0)^(p3-p2); } bool Seg_inter_line(Line l1,Line l2) //判断直线l1和线段l2是否相交 { return sgn(xmult(l2.s,l1.s,l1.e))*sgn(xmult(l2.e,l1.s,l1.e)) <= 0; } ll dist(Point a,Point b) { return sqrt( (b - a)*(b - a) ); } //多边形面积s的二倍(参数按逆时针给出) ll get_mianji(Point *P,int num) { ll ans=0; for(int i=0;i<num;i++) { ans+=P[i]^P[(i+1)%num]; } return ans; } //多边形形面积e
    //凸包s Point tubao[maxn]; int num_tubao; Point t(0,1e9+7); bool cmp_jijiao(Point p1,Point p2) { if(xmult(t, p1, p2)>0) { return 1; } else if(xmult(t, p1, p2)==0) { return dist(t, p1)<dist(t, p2); } else return 0; } void get_tubao(Point *P,int num) { t.x=0; t.y=1e9+7; for(int i=0;i<num;i++) { if(P[i].y<t.y) { t=P[i]; } else if(P[i].y==t.y) { t.x=min(P[i].x,t.x); } } sort(P, P+num, cmp_jijiao); num_tubao=2; tubao[0]=P[0];tubao[1]=P[1]; for(int i=2;i<num;i++) { while(xmult(tubao[num_tubao-2], tubao[num_tubao-1], P[i])<0) { num_tubao--; } tubao[num_tubao]=P[i]; num_tubao++; } } //凸包e //旋转卡壳s(求最大四边形面积) ll ro_ka(Point *P,int num) { ll ans=0; //去掉重复的点s int num2=1; for(int i=1;i<num;i++) { if(P[i].x==P[i-1].x&&P[i].y==P[i-1].y) { continue; } else { P[num2]=P[i]; num2++; } } num=num2; //去掉重复的点e for(int i=0;i<num;i++) P[i+num]=P[i]; //检查是否凸包上的点全部共线s int flag=1; for(int i=2;i<num;i++) { if(xmult(P[0], P[1], P[2])!=0) flag=0; } if(flag==1) return 0; //检查是否凸包上的点全部共线e for(int i=0;i<num;i++){ int l=i,r; for(int j=i+1;j<num;j++) { if(xmult(P[l], P[l+1], P[j],P[j+1])<0){ r=j; break; } } for(int j=i+1;j<num;j++) { while(xmult(P[l], P[l+1], P[i],P[j])>0) l++; while(xmult(P[r], P[r+1], P[i],P[j])<0) r++; Point t[4]={P[i],P[l],P[j],P[r]}; ans=max(ans,get_mianji(t, 4)); } } return ans; } //旋转卡壳e
    //坐标旋转s
    
    Point rotate(Point p,double angle){
        Point v = p;
        double c = cos(angle), s = sin(angle);
        return Point(v.x*c - v.y*s , v.x*s + v.y*c);
    }
    //坐标旋转e
     
    //半平面交s
    Point dad_anticlock[maxn];//输入弄好就行了
    Line dad_half_line[maxn],que[maxn];
        //得到极角角度
    double getAngle(Point a) {
      return atan2(a.y, a.x);
    }
    
        //得到极角角度
    double getAngle(Line a) {
      return atan2(a.e.y - a.s.y, a.e.x - a.s.x);
    }
    bool onRight(Line a, Line b, Line c) {
      Point o = getIntersectPoint(b, c);
      if (((a.e - a.s) ^ (o - a.s)) < 0) return true;
      return false;
    }
    bool cmp_half(Line L1,Line L2)
    {
        Point va = L1.e - L1.s, vb = L2.e - L2.s;
        double A =  getAngle(va), B = getAngle(vb);
        if (fabs((double)(A - B)) < eps) return ((va) ^ (L2.e - L1.s)) >= 0;
        return A < B;
    }
    bool Is_half(int num)
    {
        for(int i=0;i<num;i++)
        {
            dad_half_line[i].s=dad_anticlock[i];
            dad_half_line[i].e=dad_anticlock[(i+1)%num];
        }
        sort(dad_half_line, dad_half_line+num, cmp_half);
        
        int head = 0, tail = 0, cnt = 0;//模拟双端队列
        //去重,极角相同时取最后一个。
        for (int i = 0; i < num - 1; i++) {
            if (fabs(getAngle(dad_half_line[i]) - getAngle(dad_half_line[i + 1])) < eps) {
                continue;
            }
            dad_half_line[cnt++] = dad_half_line[i];
        }
        dad_half_line[cnt++] = dad_half_line[num - 1];
        
        
        for (int i = 0; i < cnt; i++) {
            //判断新加入直线产生的影响
            while(tail - head > 1 && onRight(dad_half_line[i], que[tail - 1], que[tail - 2])) tail--;
            while(tail - head > 1 && onRight(dad_half_line[i], que[head], que[head + 1])) head++;
            que[tail++] = dad_half_line[i];
          }
          //最后判断最先加入的直线和最后的直线的影响
          while(tail - head > 1 && onRight(que[head], que[tail - 1], que[tail - 2])) tail--;
          while(tail - head > 1 && onRight(que[tail - 1], que[head], que[head + 1])) head++;
          if (tail - head < 3) return false;
          return true;
        
    }
    
    //半平面交e
  • 相关阅读:
    浏览器返回错误汇总分析
    黄金投资品种众多 个人如何投资黄金
    .NET设计模式系列文章 (转自TerryLee's Tech Space)
    .NET设计模式(7):创建型模式专题总结(Creational Pattern)
    一个很经典的下拉式菜单(附效果)
    .NET设计模式(16):模版方法(Template Method)
    搜索引擎优化基础(转并整理添加)
    .NET设计模式(18):迭代器模式(Iterator Pattern)
    【ASP.NET】网页中嵌入视频的三种方法
    .NET设计模式(15):结构型模式专题总结
  • 原文地址:https://www.cnblogs.com/King-of-Dark/p/12628938.html
Copyright © 2011-2022 走看看