计算几何の板子

一 精度处理

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

求向量的长度:

il double Len(Point a){return sqrt(Dot(a,a));}

四 线,线段

1 线段的初始化

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

struct Line{Point p1,p2;};

②.其他nb的写法,咕~

2 点与直线的位置关系
l int Point_Line_relation(Line v,Point p){
    int c=sgn(Cross(p-v.p1,v.p2-v.p1));
    if(c<0)return 1;//在左侧
    else if(c>0)return 2;//在右侧
    return 0;//在线上
}
3点在直线上的投影
il Point Point_Line_proj(Line v,Point p){
    double k=Dot(v.p2-v.p1,p-v.p1)/Len2(v.p2-v.p1);
    return v.p1+(v.p2-v.p1)*k;
}
4 点关于直线的对称点
il Point Point_Line_symmetry(Line v,Point p){
    Point mid=Point_Line_proj(v,p);
    return Point(2*mid.x-p.x,2*mid.y-p.y);
}
5 两直线位置关系
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:相交 
6 两线段是否相交
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;
}
7 求两线段的交点
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);
}
8 已知横坐标求纵坐标
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;
}
9 已知纵坐标求横坐标
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;
}

DL%%%

posted @ 2023-08-08 16:14  CCComfy  阅读(75)  评论(3编辑  收藏  举报