模板 - 计算几何 - 多边形

1、注意 ^ 运算符的优先级是很低的。
2、注意重合点和共线点的情况

const double eps = 1e-9;
const double PI = acos(-1.0);

int sgn(double x) {
    return (abs(x) <= eps) ? 0 : (x > 0 ? 1 : -1);
}

struct Point {
    double x, y;
    Point() {}
    Point(double x, double y): x(x), y(y) {}

    double len() {
        return sqrt(x * x + y * y);
    }

    friend Point operator+(const Point &a, const Point &b) {
        return Point(a.x + b.x, a.y + b.y);
    }
    friend Point operator-(const Point &a, const Point &b) {
        return Point(a.x - b.x, a.y - b.y);
    }
    friend Point operator*(const Point &p, const double &k) {
        return Point(k * p.x, k * p.y);
    }
    friend Point operator*(const double &k, const Point &p) {
        return Point(k * p.x, k * p.y);
    }
    friend bool operator==(const Point &a, const Point &b) {
        return (sgn(a.x - b.x) == 0) && (sgn(a.y - b.y) == 0);
    }
    friend double operator*(const Point &a, const Point &b) {
        return a.x * b.x + a.y * b.y;
    }
    friend double operator^(const Point &a, const Point &b) {
        return a.x * b.y - a.y * b.x;
    }
    friend double dis(const Point &a, const Point &b) {
        return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
    }

    //返回绕原点旋转A弧度的结果
    Point Rotate(const double &A) {
        return Point(x * cos(A) - y * sin(A), x * sin(A) + y * cos(A));
    }
};

线段/直线

struct Segment {
    Point s, t;
    Segment() {}
    Segment(const Point &s, const Point &t): s(s), t(t) {}

    //返回点到线段的距离
    double PointDistanceWithSegment(const Point &p) {
        if(sgn((p - s) * (t - s)) < 0)
            return (p - s).len();
        if(sgn((p - t) * (s - t)) < 0)
            return (p - t).len();
        return abs((s - p) ^ (t - p)) / dis(s, t);
    }

    //返回点到直线的投影
    Point PointProjectToLine(const Point &p) {
        double r = ((t - s) * (p - s)) / ((t - s) * (t - s));
        return s + r * (t - s);
    }

    //判断点是否在线段上
    bool PointOnSegment(const Point &p) {
        return (sgn((p - s) ^ (t - s)) == 0) && (sgn((p - s) * (p - t)) <= 0);
    }

    //判断两条直线是否平行
    bool LineParallelWithLine(const Segment &l) {
        return !sgn((s - t) ^ (l.s - l.t));
    }
};

还差一个直线交点和直线向法向量方向平移。

凸包

构造一个凸包

二分判断一个点是否在凸包内

求凸包的直径

半平面交

圆与直线的交点

圆与多边形交的面积,使用三角剖分,然后求一个三角形和一个圆的面积。不需要是凸包。

圆与圆的交点

最小圆覆盖

圆的面积并

posted @ 2020-02-05 17:57  KisekiPurin2019  阅读(119)  评论(0编辑  收藏  举报