头
constexpr long double EPS = 1E-10;
const long double PI = acos(-1.0);
using T = long double;
点, 向量 都用point来表示
struct Point {
T x = 0, y = 0;
Point operator+(const Point &o) const {return {x + o.x, y + o.y};}
Point operator-(const Point &o) const {return {x - o.x, y - o.y};}
Point operator-() const {return {-x, -y};}
Point operator*(T fac) const {return {x * fac, y * fac};}
Point operator/(T fac) const {return {x / fac, y / fac};}
bool operator<(const Point &o) const {
return std::tie(x, y) < std::tie(o.x, o.y);
}
friend std::istream &operator>>(std::istream &is, Point &p) {
return is >> p.x >> p.y;
}
friend std::ostream &operator<<(std::ostream &os, Point p) {
return os << "(" << p.x << ", " << p.y << ")";
}
};
向量点积
T dot(const Point &a, const Point &b) { // 计算点积
return a.x * b.x + a.y * b.y;
}
T angle(const Point &a, const Point &b) { // 求夹角 (弧度制)
return acosl(dot(a, b) / len(a) / len(b));
}
向量叉积
几何意义: 两向量所张成的平行四边形的有向面积, b在a逆时针为正, 顺时针为负
T cross(const Point &a, const Point &b) { // 两向量叉积
return a.x * b.y - a.y * b.x;
}
T cross(const Point &a, const Point &b, const Point &c) {
return cross(b - a, c - a);
// ab向量与ac向量的叉积
// c在直线ab左侧 > 0, 右侧 < 0, 共线 = 0
}
向量模长
T len(const Point &a) { // 求模长
return sqrtl(a.x * a.x + a.y * a.y);
}
两点距离
T dis2(const Point &a, const Point &b) { // 距离的平方
return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
T dis(const Point &a, const Point &b) { // 距离
return sqrtl(dis2(a, b));
}
向量夹角
T angle(const Point &a, const Point &b) { // 求夹角
return acosl(dot(a, b) / len(a) / len(b)); //(弧度制) [0, π]
return acosl(dot(a, b) / len(a) / len(b)) * (180 / PI); // 转化为角度制 [0, 180]
}
点在向量的哪边
T cross(const Point &a, const Point &b, const Point &c) { // ab向量与ac向量的叉积
return cross(b - a, c - a); // c在直线ab左侧 > 0,
// 右侧 < 0, 共线 = 0
}
逆转角
Point rotate(const Point &a, const Point &b, T theta) { // 逆转角, ab向量逆时针
//旋转theta度,ac为转后向量
// c为返回值
return {
(b.x - a.x) * cosl(theta) - (b.y - a.y) * sinl(theta) + a.x,
(b.x - a.x) * sinl(theta) + (b.y - a.y) * cosl(theta) + a.y
};
}