计算几何基础

主要运用到向量间的点乘和叉乘.

const double eps = 1e-9; 

// 1.精度 
inline int sgn(double x) {
    if(abs(x) < eps) return 0;
    else return x < 0 ? -1 : 1;
}
//向量 
typedef struct Vector{
    double x,y;
    Vector(){x = 0,y = 0;}
    Vector(double _x,double _y):x(_x),y(_y){}
    bool operator < (const Vector &a) const {
        return sgn(x-a.x) < 0 || (sgn(x-a.x)==0&&sgn(y-a.y)<0);
    }
    void print(){printf("%lf %lf\n",x,y);}
}Point;

//各种重载 
Vector operator +(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
Vector operator -(Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}
Vector operator *(Vector a,double b){return Vector(a.x*b,a.y*b);}
Vector operator /(Vector a,double b){return Vector(a.x/b,a.y/b);} 
bool operator ==(Vector a,Vector b){return sgn(a.x-b.x)==0&&sgn(a.y-b.y);}

double Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}//点乘 
double Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}//叉乘

double Len(Vector a){return sqrt(Dot(a,a));}//a的模 
double Len2(Vector a) {return Dot(a,a);} //a方 

//线段类 
struct Line{
    Point s,t;
    Line(){}
    Line(Point a,Point b):s(a),t(b){}
    bool operator <(Line a)const{
        return sgn(Cross(t-s,a.t-a.s))>=0;
    }
};

//向量旋转 rad 
Vector Rotate(Vector a,double rad){
    return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
}

//点到线距离 
double DisTL(Point p,Point a,Point b){ 
    Vector v1 = b - a, v2 = p - a;
    return abs(Cross(v1,v2)/Len(v1));
}

//点到线段距离
double DisTS(Point p,Point a,Point b){
    if(a == b) return Len(p-a);
    Vector v1 = b - a, v2 = p - a, v3 = p - b;
    if(sgn(Dot(v1,v2)) < 0) return Len(v2);
    else if(sgn(Dot(v1,v3)) > 0) return Len(v3);
    else return DisTL(p,a,b);
} 

//点线位置关系
bool OnLeft(Line l,Point p) {
    return sgn(Cross(l.t-l.s,p-l.s)) >= 0;
}
//点在线段上 
bool OnSeg(Point p,Point a,Point b){
    return DisTL(p,a,b)==0&&sgn(Dot(p-a,p-b))&&!(p==a)&&!(p==b); 
} 

//直线相交交点 面积求比例
Point LI(Line a,Line b){
    Vector v = a.s-b.s, v2 = a.t-a.s v3 = b.t-b.s;
    double t = Cross(v2,v)/Cross(v1,v2);
    return a.s+v1*t;
} 
// 直线与线段相交:端点叉积不同
bool isLSI(Line l1,Line l2){
    Vector v=l1.t-l1.s,u=l2.s-l1.s,w=l2.t-l1.s;
    return sgn(Cross(v,u))!=sgn(Cross(v,w));
}
//线段与线段相交
bool isSSI(Line l1,Line l2){
    return isLSI(l1,l2)&&isLSI(l1,l2);
}

你可能感兴趣的:(叉积和点积的运用,几何公式)