算法笔记--计算几何之点积叉积的应用

模板:

const double eps = 1e-10;
//考虑误差的加法
double add(double a, double b) {
    if(fabs(a + b) < eps * (fabs(a) + fabs(b))) return 0;
    return a + b;
}
//考虑误差的与0比较
int dcmp(double x) {
    if(fabs(x) < eps) return 0;
    else return x<0?-1:1;
}
struct P {
    double x, y;
    P(){}
    P(double x, double y) :x(x), y(y){}
    bool operator == (P p) {
        return dcmp(x - p.x) == 0 && dcmp(y - p.y) == 0;
    }
    P operator + (P p) {
        return P(add(x, p.x), add(y, p.y));
    }
    P operator - (P p) {
        return P(add(x, -p.x), add(y, -p.y));
    }
    P operator * (double p) {
        return P(x * p, y * p);
    }
    P operator / (double p) {
        return P(x / p, y / p);
    }
    //点积
    double dot(P p) {
        return add(x * p.x, y * p.y);
    }
    //叉积
    double cross(P p) {
        return add(x * p.y, -y * p.x);
    }
};
typedef P Vector;
//向量逆时针旋转
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 len(Vector a){
    return sqrt(a.dot(a));
}
//两向量的夹角
double angle(Vector a, Vector b) {
    return acos(a.dot(b) / len(a) / len(b));
}
//绝对值为三点确定的三角形的面积的两倍
double area2(Vector a, Vector b, Vector c) {
    return (b - a).cross(c - a);
}
//判断p点是否在线段a-b上
bool on_seg(P p, Vector a, Vector b) {
    return (a - p).cross(b - p) == 0 && (a - p).dot(b - p) <= 0;
}
//判断两条线段是否相交
bool intersect(Vector a, Vector b, Vector c, Vector d) {
    if(area2(a, b, c) == 0 && area2(a, b, d) == 0
    || area2(a, b, c) * area2(a, b, d) > 0
    || area2(c, d, a) * area2(c, d, b) > 0) return false;
    return true;
}
//判断两条线段是否有交点
bool _intersect(Vector a, Vector b, Vector c, Vector d) {
    if(area2(a, b, c) == 0 && area2(a, b, d) == 0 && !on_seg(a, c, d) && !on_seg(b, c, d)
    || area2(a, b, c) * area2(a, b, d) > 0
    || area2(c, d, a) * area2(c, d, b) > 0) return false;
    return true;
}
//极角排序,建议用long long
bool anglecmp(P a, P b) {
    if(a.y <= 0 && b.y > 0) return true;
    if(a.y > 0 && b.y <= 0) return false;
    if(!a.y && !b.y) return a.x < b.x;
    return a.cross(b) > 0;
}

 

posted @ 2018-04-17 17:05  Wisdom+.+  阅读(560)  评论(0编辑  收藏  举报