计算几何基础_点_向量_极角排序
附上一个讲极角排序还不错的博客
https://www.cnblogs.com/aiguona/p/7248311.html
struct Point { double x, y; Point () {} Point (double _x, double _y) : x(_x), y(_y) {} Point operator + (const Point &a) const { return Point(x + a.x, y + a.y); } // 叉积=0是指两向量平行(重合) Point operator - (const Point &a) const { return Point(x - a.x, y - a.y); } double operator ^ (const Point &a) const { return x * a.y - y * a.x; } // 叉积 double operator * (const Point &a) const { return x * a.x + y * a.y; } // 点积 // 定义给map set 之类用的.. 不要用极角 可能会出错 bool operator < (const Point &a) const { if (x != a.x) return x < a.x; return y < a.y; } }; typedef Point Vector; double GetLenght(Vector A) { return A * A; } // 获取长度 double GetLenght(Point A, Point B) { return sqrt((A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y)); } double GetAngle(Vector A, Vector B) { return acos( (A*B) / GetLenght(A) / GetLenght(B)); } // 获取夹角[-pi/2, pi/2] double GetArea(Vector A, Vector B) { return A ^ B; } // 四边形面积, 有正负 // AB --> AC A到B: B-A double GetArea(Point A, Point B, Point C) { return GetArea(B-A, C-A); } // 四边形面积, 有正负 double GetCross(Point st, Point ed1, Point ed2) { return (ed1 - st) ^ (ed2 - st); } // 叉积极角排序 // 直接把原点当作 极点 进行 极角排序. bool cmp_j_j(const Point &A, const Point &B) { if ((A ^ B) != 0.0) return (A ^ B) > 0.0; if (A.x != B.x) return A.x < B.x; return A.y < B.y; } // 叉积极角排序. // 以Qcmppt为起点 做极角排序. Point Qcmppt; bool cmp_j_j_j(const Point &A, const Point &B) { int m = (A-Qcmppt) ^ (B-Qcmppt); if (m != 0.0) return m > 0.0; if (A.x != B.x) return A.x < B.x; return false; } // atan2 极角排序 // atan2 赛高 听说速度快些 但是精度比叉积差些 听说,.,, 未实践 bool cmp_o_o(const Point &A, const Point &B) { if (atan2(A.y, A.x) != atan2(B.y, B.x)) return atan2(A.y, A.x) < atan2(B.y, B.x); if (A.x != B.x) return A.x < B.x; return A.y < B.y; } // 获取象限 // 如果在坐标轴上 看情况划分 int GetElephant(const Point &A) { if (A.x>0 && A.y>=0) return 1; if (A.x<=0 && A.y>0) return 2; if (A.x<0 && A.y<=0) return 3; if (A.x>=0 && A.y<0) return 4; } // 先按照象限排序 再极角排序 bool cmp_o_o_o(const Point &A, const Point &B) { if (GetElephant(A) != GetElephant(B)) return GetElephant(A) < GetElephant(B); return cmp_o_o(A, B); } // 水平排序 bool cmp_s_p(const Point &A, const Point &B) { if (A.x != B.x) return A.x < B.x; return A.y < B.y; }
struct Point { double x, y; Point () {} Point (double _x, double _y) : x(_x), y(_y) {} Point operator + (const Point &a) const { return Point(x + a.x, y + a.y); } // 叉积=0是指两向量平行(重合) Point operator - (const Point &a) const { return Point(x - a.x, y - a.y); } double operator ^ (const Point &a) const { return x * a.y - y * a.x; } // 叉积 double operator * (const Point &a) const { return x * a.x + y * a.y; } // 点积 // 定义给map set 之类用的.. 不要用极角 可能会出错 bool operator < (const Point &a) const { if (x != a.x) return x < a.x; return y < a.y;}};
typedef Point Vector;
double GetLenght(Vector A) { return A * A; } // 获取长度 double GetLenght(Point A, Point B) { return sqrt((A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y)); }
double GetAngle(Vector A, Vector B) { return acos( (A*B) / GetLenght(A) / GetLenght(B)); } // 获取夹角[-pi/2, pi/2]
double GetArea(Vector A, Vector B) { return A ^ B; } // 四边形面积, 有正负
// AB --> AC A到B: B-A double GetArea(Point A, Point B, Point C) { return GetArea(B-A, C-A); } // 四边形面积, 有正负
double GetCross(Point st, Point ed1, Point ed2) { return (ed1 - st) ^ (ed2 - st); }
// 叉积极角排序 // 直接把原点当作 极点 进行 极角排序. bool cmp_j_j(const Point &A, const Point &B) { if ((A ^ B) != 0.0) return (A ^ B) > 0.0; if (A.x != B.x) return A.x < B.x; return A.y < B.y;}
// 叉积极角排序. // 以Qcmppt为起点 做极角排序. Point Qcmppt; bool cmp_j_j_j(const Point &A, const Point &B) { int m = (A-Qcmppt) ^ (B-Qcmppt); if (m != 0.0) return m > 0.0; if (A.x != B.x) return A.x < B.x; return false;}
// atan2 极角排序// atan2 赛高 听说速度快些 但是精度比叉积差些 听说,.,, 未实践 bool cmp_o_o(const Point &A, const Point &B) { if (atan2(A.y, A.x) != atan2(B.y, B.x)) return atan2(A.y, A.x) < atan2(B.y, B.x); if (A.x != B.x) return A.x < B.x; return A.y < B.y;}
// 获取象限 // 如果在坐标轴上 看情况划分 int GetElephant(const Point &A) { if (A.x>0 && A.y>=0) return 1; if (A.x<=0 && A.y>0) return 2; if (A.x<0 && A.y<=0) return 3; if (A.x>=0 && A.y<0) return 4;}
// 先按照象限排序 再极角排序bool cmp_o_o_o(const Point &A, const Point &B) { if (GetElephant(A) != GetElephant(B)) return GetElephant(A) < GetElephant(B); return cmp_o_o(A, B);}
bool cmp_s_p(const Point &A, const Point &B) { if (A.x != B.x) return A.x < B.x;return A.y < B.y;}