struct Point { double x, y;
Point(){}
Point(double a, double b): x(a), y(b){}
};
typedef Point Vector;
Vector operator + (Vector a, Vector b) { return Vector( a.x + b.x, a.y + b.y ); }
Vector operator - (Vector a, Vector b) { return Vector( a.x - b.x, a.y - b.y ); }
Vector operator * (Vector a, double p) { return Vector( a.x * p, a.y * p); }
Vector operator / (Vector a, double p) { return Vector( a.x / p, a.y / p); }
int dcmp(double x) { if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; } // 精准判断正负号
// 点积,模长,两向量夹角, 向量角度,叉积,三角形面积,极角,逆时针旋转
double Dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; }
double Length(Vector a) { return sqrt( Dot(a, a) ); }
double Angle(Vector a, Vector b) { return acos(Dot(a, b) / Length(a) / Length(b)); }
double Angle(Vector a) { return atan2(a.y, a.x);}
double Cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; } // 大于0时,b在a的逆时针方向
double Area(Point A, Point B, Point C) { return Cross(B - A, C - A) / 2; } // 三角形面积叉乘公式
double PolarAngle(Vector a) { return atan2(a.y, a.x); }
Vector Rotate (Vector a, double rad) { return Vector( a.x*cos(rad) - a.y*sin(rad), a.x*sin(rad) + a.y*cos(rad) ); }
bool operator < (Vector a, Vector b) {
if(dcmp(PolarAngle(a) - PolarAngle(b)) == 0)
return dcmp(a.x - b.x) == 0 ? dcmp(a.y - b.y) < 0 : dcmp(a.x - b.x) < 0;
return dcmp(PolarAngle(a) - PolarAngle(b)) < 0;
} //优先级:极角 > x > y
bool operator == (Vector a, Vector b) { return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0; }
struct Line{ // 有向直线
Point A, B;
Line(){};
Line(Point P, Point Q) : A(P), B(Q) {}
};
// 判断线段AB是否跨立MN
bool straddle (Point A, Point B, Point M, Point N) {
Vector p0 = { N.x - M.x , N.y - M.y }; // 向量 MN
Vector p1 = { A.x - M.x , A.y - M.y }; // 向量 MA
Vector p2 = { B.x - M.x , B.y - M.y }; // 向量 MB
return Cross(p1, p0) * Cross(p2, p0) <= 0;
}
// 判断 线段AB为对角线构成的矩形 和 MN线段为对角线构成的矩形 是否存在重叠
bool overlap (Point A, Point B, Point M, Point N){
Point P = { max(min(A.x, B.x), min(M.x, N.x)), max(min(A.y, B.y), min(M.y, N.y))};
Point Q = { min(max(A.x, B.x), max(M.x, N.x)), min(max(A.y, B.y), max(M.y, N.y))};
return P.x <= Q.x && P.y <= Q.y;
}
// 判断线段AB和MN是否相交
bool intersect (Point A, Point B, Point M, Point N) {
return straddle(A, B, M, N) && straddle(M, N, A, B) && overlap(A, B, M, N);
}
07-05
5万+
04-08
878