zoukankan      html  css  js  c++  java
  • Geometry

    模版 未完成

    #include <bits/stdc++.h>
    using namespace std;
    
    /*
    点、直线、线段、三角形、正方形、矩形、凸多边形、多边形
    
    点/向量与点/向量:
        1.0 旋转
        1.0 点积叉积
            定比分点(无)
        1.1 判向量平行
        1.2 * 判三点共线
        1.3 求两点的中垂线
    直线与直线:
        2.1 判关系
        2.2 求交点
        2.3 求距离
    线段与直线:
        3.1 判关系
        3.2 求交点
    点与直线:
        4.1 判关系
        4.2 求对称点
        4.3 最近点
        4.4 求距离
    点与线段:
        5.1 判关系
        5.2 最近点
        5.3 求距离
        5.4 * 两点在线段同侧/异侧
    线段与线段:
        6.1 判关系(端点)
        6.2 求交点
    7.0 * 镜面反射问题
    */
    
    const double eps = 1e-8;
    const double pi = acos(-1.0);
    
    inline int dcmp(double x)
    {
        if(fabs(x)<eps) return 0;
        return x>0?1:-1;
    }
    
    //弧度与角度互换
    double radian_to_angle(double r) {return r*180/pi;}
    double angle_to_radian(double a) {return a*pi/180;}
    
    struct point {
        double x,y;
        point(double _x=0, double _y=0) {x=_x;y=_y;}
        void in() {scanf("%lf%lf",&x,&y);}
        void out() {printf("%lf %lf
    ",x,y);}
        friend bool operator < (point &a, point &b) {return a.x<b.x || (a.x==b.x && a.y<b.y);}
        friend point operator + (point a, point b) {return point(a.x+b.x,a.y+b.y);}
        friend point operator - (point a, point b) {return point(a.x-b.x,a.y-b.y);}
        friend double operator * (point a, point b) {return a.x*b.x+a.y*b.y;}
        friend double operator ^ (point a, point b) {return a.x*b.y-a.y*b.x;}
        friend point operator * (double k,point b) {return point(b.x*k,b.y*k);}
        point transXY(double B) // 逆时针旋转B度,B是弧度
        {
            point res;
            res.x = x*cos(B) - y*sin(B);
            res.y = x*sin(B) + y*cos(B);
            return res;
        }
    };
    typedef point Vector;
    double dot(point &a,point &b) {return a*b;}
    double cross(point &a, point &b) {return a^b;}
    double dist(point &a, point &b) {return sqrt((a-b)*(a-b));}
    double length(point &a) {return sqrt(a.x*a.x+a.y*a.y);}
    double xmult(point p1,point p2,point p0){
        return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
    }
    
    
    struct line {
        point u,v;
        double a,b,c;
        line() {}
        line(point _u,point _v)
        {
            u=_u,v=_v; // 8ed73db
            a = v.y-u.y; // 4599bb23
            b = -(v.x-u.x); // 39f20c2a
            c = v.y*(v.x-u.x)-v.x*(v.y-u.y); // 347cb769
        }
    };
    
    // 1.1
    bool Vector_para(Vector a, Vector b)
    {
        return dcmp(a^b)==0;
    }
    // 1.2
    bool three_point_in_line(point &a,point &b,point &c)
    {
        return Vector_para(b-a,c-a);
    }
    
    // 1.3 求两点中垂线
    line bisector(point &a, point &b)
    {
        line ab(a,b),ans;
        double midx=(a.x+b.x)/2, midy=(a.y+b.y)/2; // 3519efcd
        ans.a=ab.b; ans.b=-ab.a; ans.c=-ab.b*midx+ab.a*midy; // 341d916e
        return ans;
    }
    
    // 2.1 判断两直线位置,0重合,1平行,2相交
    //verson1: use u,v
    int judge_2line_coincide_or_para_or_inter_v1(line &a,line &b)
    {
        if(dcmp((a.u-a.v)^(b.u-b.v))==0) // 44347297
            return dcmp((a.u-b.v)^(b.u-b.v))!=0; // 20d22e85
        else return 2;
    }
    //verson2: use a,b,c
    int judge_2line_coincide_or_para_or_inter_v2(line &a,line &b)
    {
        if(dcmp(a.a*b.b-b.a*a.b)==0) // 20f46b56
            return dcmp(a.a*b.c-a.c*b.a)!=0; // 2cefea01
        else return 2;
    }
    
    // 2.2 求两直线交点,需要先判相交
    //verson1: use u,v
    point crosspoint_2line_v1(line &a,line &b)
    {
        point res = a.u;
        double t = ((a.u-b.u)^(b.u-b.v))/((a.u-a.v)^(b.u-b.v)); // 2019555a
        res.x += (a.v.x-a.u.x)*t; // 6b331eac
        res.y += (a.v.y-a.u.y)*t; // 4cd716ef
        return res;
    }
    //verson2:
    point crosspoint_2line_v2(line &a,line &b)
    {
        point res;
        double d = a.a*b.b-b.a*a.b; // 1a9cbb06
        res.x = (a.b*b.c-b.b*a.c)/d; // f8eeeeb
        res.y = (a.c*b.a-b.c*a.a)/d; // 25d5407c
        return res;
    }
    
    // 2.3 求两直线距离,需要先判平行
    double dist_2line(line &a,line &b)
    {
        double k;
        if(dcmp(b.a)==0) k=a.b/b.b; // 567a2861
        else k=a.a/b.a; // 6db44184
        return fabs(a.c/k-b.c)/sqrt(b.a*b.a+b.b*b.b); // 246b031f
    }
    
    // 3.1 判直线与线段关系 第一个参数直线 第二个参数线段
    int judge_relation_line_seg(line &a,line &b) // 0重合 1平行 2相交 3不平行且无交点
    {
        double x = (b.u-a.v)^(a.u-a.v); // 9ff5dba
        double y = (b.v-a.v)^(a.u-a.v); // 2b98d22e
        if(dcmp(x)==0 && dcmp(y)==0) return 0; // 16743f4e
        if(dcmp((a.u-a.v)^(b.u-b.v))==0) return 1; // 65c6becd
        if(dcmp(x)*dcmp(y)<=0) return 2; // 61ab621b
        return 3;
    }
    
    // 3.2 求直线与线段交点
    //     先判直线与线段关系,是否相交,然后使用2.2算法
    
    // 4.1 判点与直线关系
    // verson 1: use u,v
    int judge_relation_point_line_v1(line &l, point &p) // 0点在线上 1点在线外
    {
        return dcmp((p-l.v)^(l.u-l.v))!=0;
    }
    // verson 2: use a,b,c
    int judge_relation_point_line_v2(line &l, point &p)
    {
        return dcmp(p.x*l.a+p.y*l.b+l.c)!=0;
    }
    
    // 4.2 求点关于直线的对称点
    // verson 1:
    point sym_point_line_v1(line &l,point &p)
    {
        Vector v1,v2;
        v1 = l.u-l.v;
        v2 = p-l.v;
        double a = asin((v1^v2)/(length(v1)*length(v2)));
        double b = (v1*v2)/(length(v1)*length(v2));
        if(b<0) a=dcmp(a)*pi-a;
        return v2.transXY(-2*a)+(l.v);
    }
    // verson 2:
    point sym_point_line_v2(line &l,point &p)
    {
        point res;
        double d;
        d = l.a*l.a+l.b*l.b;
        res.x = (l.b*l.b*p.x-l.a*l.a*p.x-2*l.a*l.b*p.y-2*l.a*l.c)/d;
        res.y = (l.a*l.a*p.y-l.b*l.b*p.y-2*l.a*l.b*p.x-2*l.b*l.c)/d;
        return res;
    }
    
    // 4.3 求点到直线最近点
    // verson 1:
    point nearestpoint_point_line(line &l, point &p)
    {
        point t = p;
        t.x += l.u.y-l.v.y;
        t.y += l.v.x-l.u.x;
        line l2(t,p);
        return crosspoint_2line_v1(l,l2);
    }
    // verson 2: 求对称点后用直线交点
    
    // 4.4 求点到直线距离
    // verson 1:
    double dist_point_line_v1(line &l,point &p)
    {
        return fabs(((p-l.v)^(l.u-l.v))/dist(l.u,l.v));
    }
    // verson 2:
    double dist_point_line_v2(line &l,point &p)
    {
        return fabs((l.a*p.x+l.b*p.y+l.c)/sqrt(l.a*l.a+l.b*l.b));
    }
    
    // 5.1 判点与线段关系
    int judge_relation_point_seg(line &l,point &p) // 0在线上 1在线外
    {
        if(dcmp(p.x-max(l.u.x,l.v.x))>0 || dcmp(p.x-min(l.u.x,l.v.x))<0 ||
           dcmp(p.y-max(l.u.y,l.v.y))>0 || dcmp(p.y-min(l.u.y,l.v.y))<0)
            return 1;
        return dcmp((p-l.v)^(l.u-l.v))!=0;
    }
    
    // 5.2 求点到线段最近点
    point nearestpoint_point_seg(line &l,point &p)
    {
        point ab = l.v-l.u;
        point ac = p-l.u;
        double f = ab*ac;
        if(f<0) return l.u;
        double d = ab*ab;
        if(f>d) return l.v;
        f/=d;
        return l.u+f*ab;
    }
    
    // 5.3 求点到线段距离
    double dist_point_seg(line &l,point &p)
    {
        point ab = l.v-l.u;
        point ac = p-l.u;
        double f = ab*ac;
        if(f<0) return dist(p,l.u);
        double d = ab*ab;
        if(f>d) return dist(p,l.v);
        f/=d;
        point t = l.u+f*ab;
        return dist(p,t);
    }
    
    // 5.4 判断点在直线的同侧/异侧
    int side_2point_line(line &l,point &p1,point &p2) // 0点在线上 1同侧 -1异侧
    {
        int a = dcmp(xmult(p1,l.u,l.v));
        int b = dcmp(xmult(p2,l.u,l.v));
        return a*b;
    }
    
    // 6.1 判两线段关系
    // 6.1.1 包括端点
    int judge_relation_2seg(line &a,line &b) // 0重合 1平行 2相交 3没关系
    {
        return 0;
    }
    
    int main()
    {
        freopen("case.txt","r",stdin);
        point a,b;
        int _;
        cin>>_;
        while(_--)
        {
            a.in(); b.in();
            line l(a,b);
            a.in(); b.in();
    
            cout<<side_2point_line(l,a,b)<<endl;
        }
        return 0;
    }

    8

    0 0 1 1
    100 0 1 0

    0 0 1 1
    0 0 0 100

    0 0 1 1
    1 0 0 1

    0 0 1 1
    0 1 0 100


    -1 -1 100 100
    100 99

    -1 0 1 0
    0 1

    100 -100 10000 -100
    0 -100

    0 0 0 1
    100 0

    100 100 -1 0
    0 1

    0 -1 1 0
    5 -1

    5 1 -1 0
    1 0

    -1 -1 1 1
    1 -1 -1 1

    -10 0 10 0
    0 -5 5 5

    0 50 100 100
    50 0 75 50

  • 相关阅读:
    javascript定时器,取消定时器,及js定时器优化方法
    Systen,IO
    批量地理位置解析
    数据库分区分表(sql、mysql)
    数据库还原的多种方式
    js前端文件收集(一)
    NPOI解决由于excel删除数据导致空行读取问题
    echarts2.0tooltip边框限制导致tooltip显示不全解决办法
    数据库备份通用脚本
    echarts 用marlkline画线 同时配置中含有datazoom,怎么设置markline
  • 原文地址:https://www.cnblogs.com/someblue/p/4005695.html
Copyright © 2011-2022 走看看