..
计算几何の基操
写完了发现 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;
}