(模板)计算几何点线面形基础知识总结

int sgn(double x){
    if(abs(x)<eps) return 0;
    if(x<0) return -1;
    return 1;
}

struct Point{
    double x,y;
    Point(){}
    Point(double xx,double yy):x(xx),y(yy){}
    Point operator + (const Point& b){
        return Point(x+b.x,y+b.y);
    }
    Point operator - (const Point& b){
        return Point(x-b.x,y-b.y);
    }
    double operator * (const Point& b){
        return x*b.x+y*b.y;
    }
    double operator ^ (const Point& b){
        return x*b.y-b.x*y;
    }
};

struct Line{
    Point s,e;
    Line(){}
    Line(Point ss,Point ee){
        s=ss,e=ee;
    }
}line[maxn];

  以上是点和线的基本定义,函数sgn用来判断double型变量x的符号。

1 . 叉积判断直线和线段相交:

double xmult(Point p0,Point p1,Point p2){  //p0p1 ^ p0p2
    return (p1-p0)^(p2-p0);
}

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;
}

2. 叉积判断线段相交(证明见https://blog.csdn.net/wordsin/article/details/79215342):

bool inter(Line l1,Line l2){           //判断线段l1和l2是否相交
    return
        max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x)&&
        max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x)&&
        max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y)&&
        max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y)&&
        sgn((l1.s-l2.s)^(l2.e-l2.s))*sgn((l1.e-l2.s)^(l2.e-l2.s))<=0&&
        sgn((l2.s-l1.s)^(l1.e-l1.s))*sgn((l2.e-l1.s)^(l1.e-l1.s))<=0;
}

3. 叉积判断直线相交,并相交时求交点(证明见https://www.cnblogs.com/jklover/p/10484313.html):

void solve(){          //判断ab和cd直线的关系
    Point a=Point(x1,yy1);
    Point b=Point(x2,yy2);
    Point c=Point(x3,yy3);
    Point d=Point(x4,yy4);
    if(sgn((b-a)^(d-c))==0){
        if(sgn((c-a)^(d-a))==0) flag=0;  //重合
        else flag=1;      //平行
        return;
    }
    flag=2;                 //相交
    double t=((a-c)^(c-d))/((a-b)^(c-d));
    ans=Point(a.x+(b.x-a.x)*t,a.y+(b.y-a.y)*t);   //交点
}

猜你喜欢

转载自www.cnblogs.com/FrankChen831X/p/11498774.html