计算几何の板子

发布时间 2023-08-08 16:15:50作者: CCComfy

一 精度处理

\(eps\)\(sgn\)

const double eps=1e-8;
int sgn(double x){//判断大小
    if(fabs(x)<eps)return 0;    
    else return x<0?-1:1;
}

二 点

1 点的初始化

向量的表示形式上与点完全相同
重载点运算符,支持向量的四种运算

struct Point{
    double x,y;
    Point(){}
    Point(double x,double y):x(x),y(y){}
    Point operator + (Point B){return Point(x+B.x,y+B.y);}
    Point operator - (Point B){return Point(x-B.x,y-B.y);}
    Point operator * (double k){return Point(x*k,y*k);}
    Point operator / (double k){return Point(x/k,y/k);}
};
2 两点间距离
inline double getdis(Point a,Point b){
    return hypot(a.x-b.x,a.y-b.y);
}

三 向量的点积,叉积

证明略
点积:

il double Dot(Point a,Point b){
    return a.x*b.x+a.y*b.y;
}

叉积:

il double Cross(Point a,Point b){
    return a.x*b.y-a.y*b.x;
}

四 线,线段

1 线段的初始化

①.直接用两个点表示线/线段

struct Line{Point p1,p2;};

②.其他nb的写法,咕~

2 两直线位置关系
il int Line_relation(Line v1,Line v2){
    if(sgn(Cross(v1.p2-v1.p1,v2.p2-v2.p1))==0){
        return 0;
    }
    return 1;
}//0:共线 /平行   1:相交 
3 两线段是否相交
il bool Cross_segment(Point a,Point b,Point c,Point d){
    double c1=Cross(b-a,c-a),c2=Cross(b-a,d-a);
    double d1=Cross(d-c,a-c),d2=Cross(d-c,b-c);
    return sgn(c1)*sgn(c2)<=0 && sgn(d1)*sgn(d2)<=0;
}
4 求两线段的交点
il Point Cross_point(Point a,Point b,Point c,Point d){
    double s1=Cross(b-a,c-a);
    double s2=Cross(b-a,d-a);
    return Point(c.x*s2-d.x*s1,c.y*s2-d.y*s1)/(s2-s1);
}
5 已知横坐标求纵坐标
il double get_y(Line v,double x){
    double k=(v.p1.y-v.p2.y)/(v.p1.x-v.p2.x);
    double b=v.p1.y-k*v.p1.x;
    return k*x+b;
}
6 已知纵坐标求横坐标
il double get_x(Line v,double y){
    double k=(v.p1.y-v.p2.y)/(v.p1.x-v.p2.x);
    double b=v.p1.y-k*v.p1.x;
    return (y-b)/k;
}