• 计算几何模板整理


    基础知识:

    二维的:

    //2-D
    
    int my(double A){//处理应精度比大小不准确的问题 
        if(fabs(A)<eps)return 0;
        if(A<0)return -1;
        if(A>0)return 1;
        return 0;
    }
     
    struct Point{//
        double x,y;
    }point[N];
    Point operator +(Point A,Point B){//
        return (Point){A.x+B.x,A.y+B.y};
    }
    Point operator -(Point A,Point B){//
        return (Point){A.x-B.x,A.y-B.y};
    }
    Point operator *(Point A,double B){//数乘 
        return (Point){A.x*B,A.y*B};//结果为向量
    }
    double operator ^(Point A,Point B){//叉乘 
        return A.x*B.y-A.y*B.x;//结果为z轴向量(这里简化成标量了) 
    }
    double operator *(Point A,Point B){//点乘 
        return A.x*B.x+A.y*B.y;//结果为标量
    }
    double len(Point A,Point B){//两点间距离 
        double X=A.x-B.x;
        double Y=A.y-B.y;
        return sqrt(X*X+Y*Y);
    }
    
    struct Line{//线 
        int num[2];//起点终点 
        double theta;//斜率
        double len(){//线的长度 
            double A=point[num[0]].x-point[num[1]].x;
            double B=point[num[0]].y-point[num[1]].y;
            return sqrt(A*A+B*B);
        }
    }line[N];
    double len(Point X,Line Y){
        double A=point[Y.num[1]].x-point[Y.num[0]].x;
        double B=point[Y.num[0]].y-point[Y.num[1]].y;
        double C1=point[Y.num[1]].y*point[Y.num[0]].x;
        double C2=point[Y.num[0]].y*point[Y.num[1]].x;
        double C=C1-C2;
        return fabs(A*X.y-B*X.x+C)/sqrt(A*A+B*B);
    }
    Point inter(Line A,Line B){//求交点 
        Point x=point[A.num[0]]-point[B.num[0]]; 
        Point y=point[A.num[1]]-point[A.num[0]];
        Point z=point[B.num[1]]-point[B.num[0]];
        double k=(z^x)/(y^z);
        return point[A.num[0]]+y*k;
    }
    bool cmp(Line A,Line B){//按斜率排序 
        if(my(A.theta-B.theta)<0)return 1;
        if(my(A.theta-B.theta)>0)return 0;//斜率小的在前面 
        if(my(A.theta-B.theta)==0)return my((A.num[1]-A.num[0])^(B.num[1]-A.num[0]))>0;
        //斜率一样时将点靠外的优先排在前面 
        return 0;
    }
    bool judge(Line A,Line l1,Line l2){//判断A是否在l1l2之内 
        Point o=inter(l1,l2);
        return (my((point[A.num[1]]-point[A.num[0]])^(o-point[A.num[0]]))<0);//在l1l2之内返回1 
    }
    2-D

    三维的:

    //3-D 
    
    int my(double A){//处理应精度比大小不准确的问题 
        if(fabs(A)<eps)return 0;
        if(A<0)return -1;
        if(A>0)return 1;
        return 0;
    } 
    
    struct Point{//
        double x,y,z; 
        void shake(){//微小扰动(防止四点共面)
            double Rand=(rand()/RAND_MAX-0.5)*eps;
            x+=Rand;y+=Rand;z+=Rand;
        }
        double len(){//从原点到点的向量的长度 
            return sqrt(x*x+y*y+z*z);
        }
    }point[N];
    Point operator +(Point A,Point B){//
        return (Point){A.x+B.x,A.y+B.y,A.z+B.z};
    }
    Point operator -(Point A,Point B){//
        return (Point){A.x-B.x,A.y-B.y,A.z-B.z};
    }
    Point operator ^(Point A,Point B){//叉乘-结果为向量 
        return (Point){A.y*B.z-A.z*B.y,A.z*B.x-A.x*B.z,A.x*B.y-A.y*B.x};
    }
    double operator *(Point A,Point B){//点乘-结果为标量 
        return A.x*B.x+A.y*B.y+A.z*B.z;
    }
    
    struct Plane{//
        int num[3];//三点确定一个面,逆时针记录下三个点 
        Point legal(){//面的法向量
            Point A=point[num[1]]-point[num[0]];
            Point B=point[num[2]]-point[num[0]];
            return A^B;
        }
        double S(){//面的面积 
            return legal().len()/2.0;
        }
    }plane[N];
    double len(Point A,Plane B){//点到面的距离 
        Point legal=B.legal();
        return legal*(A-point[B.num[0]])/legal.len();
    }
    bool see(Point A,Plane B){//点到多面体的面可不可视 
        return my(B.legal()*(A-point[B.num[0]]))>=0;
    }
    3-D

    旋转卡壳:待补

    半平面交:待补

  • 相关阅读:
    windows php
    使用 powershell 的 grep 过滤文本
    一个命令巧妙查看git版本演变史
    面试官一听就想发offer的自我介绍,到底是怎么做的?
    用了5年的git,你竟然还不知道它的工作原理
    接口测试到底怎么做,看完这篇文章彻底搞清楚
    一文学会jenkins pipline自动化构建
    Fiddler经典版安装设置流程
    没想到一个简单的重命名,在git中也有这么多学问
    1小时学会jenkins集成邮件/微信/钉钉通知
  • 原文地址:https://www.cnblogs.com/passione-123456/p/12269396.html
Copyright © 2020-2023  润新知