How to sort vertices of a polygon in counter clockwise order?

How to sort vertices of a polygon in counter clockwise order?

I want to create a function (algorithm) which compares two vectors $\vec v$ and $\vec u$ which are vertices in a polygon. It should choose the vertex which counter clockwise index inside the polygon is higher. The first index should be the bottom left vertex.

pentagon example

I this example it should choose $\vec u$.

For the first quadrant I can say that $\vec u > \vec v$ if $|\vec u| > |\vec v|$ and $\forall\vec u > \forall\vec v$. The length should be weighted more than the angle in order that vertex 1 gets a lower index than vertex 2. But this rule only works for the first quadrant. I could first move the whole polygon into the first quadrant but I want to find a better solution. Any ideas?


If your polygon is convex, take any point in the interior of the polygon, e.g. the average of all the vertices. Then you can compute the angle of each vertex to the center point, and sort according to the computed angles. This will work for any point inside the polygon. Note you will get a circular ordering.


Here is my Java code based on the correct answer: 1) get centroid coordinates 2) calculate degree between two point, sort the point based on the degree

 private static class Point {
    int x;
    int y;

    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return "x=" + x + " y=" + y;
    }
}

public Point findCentroid(List<Point> points) {
    int x = 0;
    int y = 0;
    for (Point p : points) {
        x += p.x;
        y += p.y;
    }
    Point center = new Point(0, 0);
    center.x = x / points.size();
    center.y = y / points.size();
    return center;
}

public List<Point> sortVerticies(List<Point> points) {
    // get centroid
    Point center = findCentroid(points);
    Collections.sort(points, (a, b) -> {
        double a1 = (Math.toDegrees(Math.atan2(a.x - center.x, a.y - center.y)) + 360) % 360;
        double a2 = (Math.toDegrees(Math.atan2(b.x - center.x, b.y - center.y)) + 360) % 360;
        return (int) (a1 - a2);
    });
    return points;
}