Sort the points/coordinates of a circle into a logical sequence

Question:

Basically, I have a list of x,y,z coordinates read from a csv file that forms a rough circle and are not in order [[82.41657257, 0.863095999, -5400.0], [82.4160614, 0.0, -5400.0], [82.41255188, -0.863053977, -5400.0], [82.40731812, 1.726186991, -5400.0],....... I have the centre of the circle but cannot work out how to sort the points. Is there any way of sorting these points into a logical order (clockwise)?

import csv
coorinput=[]
#open and read file
with open("test.csv","rb") as readfile:
reader = csv.reader(readfile, dialect = 'excel',skipinitialspace = True)
for row in reader:
    coorinput.append(map(float, row))

#call sort function here
Asked By: bolt19

||

Answers:

You can use trigonometry to find the angle each point makes with the X axis:

from math import atan2
coorinput.sort(key=lambda c:atan2(c[0], c[1]))
Answered By: Hardmath123

Building upon Hardmath123’s answer, a more general solution requires normalization to center the data points around (0, 0).

import numpy as np


def sort_points(xy: np.ndarray) -> np.ndarray:
    # normalize data  [-1, 1]
    xy_sort = np.empty_like(xy)
    xy_sort[:, 0] = 2 * (xy[:, 0] - np.min(xy[:, 0]))/(np.max(xy[:, 0] - np.min(xy[:, 0]))) - 1
    xy_sort[:, 1] = 2 * (xy[:, 1] - np.min(xy[:, 1])) / (np.max(xy[:, 1] - np.min(xy[:, 1]))) - 1

    # get sort result
    sort_array = np.arctan2(xy_sort[:, 0], xy_sort[:, 1])
    sort_result = np.argsort(sort_array)

    # apply sort result
    return xy[sort_result]


points = np.array(
        [
            [0, 1],
            [0, -1],
            [1, 0],
            [-1, 0],
            [1, 1],
            [-1, 1]
        ]
    )

# the '+5' will non-centered the data
points = points + 5  

sorted_points = sort_points(points)
#sorted_points = array([[4, 5],
#                       [4, 6],
#                       [5, 6],
#                       [6, 6],
#                       [6, 5],
#                       [5, 4]])
Answered By: basil_man