..

计算几何の基操

写完了发现 double 不能重载。

#include <iostream>
#include <algorithm>
#include <cmath>

typedef double dbl;

const dbl eps = 1e-6;

bool operator<(const dbl &a, const dbl &b) {
    return b - a > eps;
}

bool operator>(const dbl &a, const dbl &b) {
    return a - b > eps;
}

bool operator==(const dbl &a, const dbl &b) {
    return std::abs(a - b) < eps;
} 

bool operator<=(const dbl &a, const dbl &b) {
    return (a < b) || (a == b);
}

bool operator>=(const dbl &a, const dbl &b) {
    return (a > b) || (a == b);
}

bool operator!=(const dbl &a, const dbl &b) {
    return std::abs(a - b) >= eps;
}

struct Point {
    dbl x;
    dbl y;

    Point operator-(const Point &other) const {
        Point ret;
        ret.x = x - other.x;
        ret.y = y - other.y;
        return ret;
    }

    //  模长
    dbl len() {
        return sqrt(x * x + y * y);
    }

    //  点积
    dbl dot(const Point &other) {
        return x * other.x + y * other.y;
    }

    //  叉积
    dbl cross(const Point &other) {
        return x * other.y - y * other.x;
    }

    bool operator<(const Point &other) {
        if ((y > 0) != (other.y > 0)) return (y > 0) > (other.y > 0);
        return this->cross(other) > 0;
    }
};

//  判断点在向量的哪一侧(左 or 右)
int judgeWhichSide(Point p, Point v) {
    dbl c = v.cross(p);
    if (c == 0) return 0;       //  上
    else if (c < 0) return 1;   //  右
    else if (c > 0) return -1;  //  左
}

//  判断点 c 是否在直线 ab 上
bool judgeOnLine(Point c, Point a, Point b) {
    return (b - a).cross(c - a) == 0;
}

//  判断点 c 是否在线段 ab 上
bool judgeOnSegment(Point c, Point a, Point b) {
    if (!judgeOnLine(c, a, b)) return false;
    dbl minX = std::min(a.x, b.x);
    dbl maxX = std::max(a.x, b.x);
    dbl minY = std::min(a.y, b.y);
    dbl maxY = std::max(a.y, b.y);
    return (minX <= c.x && c.x <= maxX) && (minY <= c.y && c.y <= maxY);
}

//  判断两条线段 ab 和 cd 是否相交
bool judgeSegmentIntersect(Point a, Point b, Point c, Point d) {
    if (std::abs(judgeWhichSide(a, c - d) + judgeWhichSide(b, c - d)) == 2) return false;
    if (std::abs(judgeWhichSide(c, a - b) + judgeWhichSide(d, a - b)) == 2) return false;
    return true;
}

//  点 p 到直线 bc 的最短距离
dbl disPoint2Line(Point p, Point b, Point c) {
    return std::abs((p - b).cross(p - c) / (b - c).len());
}

//  点 p 到线段 bc 的最短距离:
dbl disPoint2Segment(Point p, Point b, Point c) {
    if ((c - b).dot(p - b) < 0) return std::abs((p - b).len());
    if ((b - c).dot(p - c) < 0) return std::abs((p - c).len());
    return disPoint2Line(p, b, c);
}

int main() {
    return 0;
}