Sort points by angle from given axis?

前端 未结 8 2880
無奈伤痛
無奈伤痛 2021-02-19 12:11

How can I sort an array of points/vectors by counter-clockwise increasing angle from a given axis vector?

For example:

相关标签:
8条回答
  • 2021-02-19 12:35

    If S is an array of PointF, and mid is the PointF in the centre:

    S = S.OrderBy(s => -Math.Atan2((s.Y - mid.Y), (s.X - mid.X))).ToArray();
    

    will sort the list in order of rotation around mid, starting at the point closest to (-inf,0) and go ccw (clockwise if you leave out the negative sign before Math).

    0 讨论(0)
  • 2021-02-19 12:36
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    
    struct Point {
        static double base_angle;
        static void set_base_angle(double angle){
            base_angle = angle;
        }
        double x;
        double y;
        Point(double x, double y):x(x),y(y){}
        double Angle(Point o = Point(0.0, 0.0)){
            double dx = x - o.x;
            double dy = y - o.y;
            double r = sqrt(dx * dx + dy * dy);
            double angle = atan2(dy , dx);
            angle -= base_angle;
            if(angle < 0) angle += M_PI * 2;
            return angle;
        }
    };
    double Point::base_angle = 0;
    
    ostream& operator<<(ostream& os, Point& p){
        return os << "Point(" << p.x << "," << p.y << ")";
    }
    
    bool comp(Point a, Point b){
        return a.Angle() < b.Angle();
    }
    
    int main(){
        Point p[] = { Point(-4., -4.), Point(-6., 3.), Point(2., -4.), Point(1., 5.) };
        Point::set_base_angle(p[0].Angle());
        sort(p, p + 4, comp);
        Point::set_base_angle(0.0);
        for(int i = 0;i< 4;++i){
            cout << p[i] << " angle:" << p[i].Angle() << endl;
        }
    }
    

    DEMO

    Point(-4,-4) angle:3.92699
    Point(2,-4) angle:5.17604
    Point(1,5) angle:1.3734
    Point(-6,3) angle:2.67795
    
    0 讨论(0)
提交回复
热议问题