计算几何基础_点_向量_极角排序

附上一个讲极角排序还不错的博客

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;}

posted @ 2018-08-02 16:03  过路人1998  阅读(258)  评论(0编辑  收藏  举报