Your points appear to form a convex shape, which will allow this approach to work. Simply put, find the centroid of the points, then find the angle subtended from the centroid to each of these points. Sort the points based on this angle. I'm assuming the first column is horizontal and the second column is vertical in coordinates.
import numpy as np
fourPointsCard = [np.array([[508, 116]]), np.array([[351, 129]]), np.array([[371, 379]]), np.array([[527, 366]])]
arr = np.array(fourPointsCard)[:, 0] # Remove singleton dimension
# Find the centroid
cen = np.mean(arr, axis=0)
# Find the angle from each point to its centroid
angles = np.arctan2(arr[:,1] - cen[1], arr[:,0] - cen[0])
# Because arctan spans -pi to pi, let's switch to 0 to 2*pi
angles[angles < 0] = angles[angles < 0] + 2*np.pi
# Order based on angle - ascending order
ind = np.argsort(angles)
# Reorder your points
arr_sorted = arr[ind]
arr
will contain the original points in a NumPy array while arr_sorted
will sort the points in ascending order based on angle. Ascending order means that your points will be ordered clockwise. If you want counter-clockwise, sort on the negative by using ind = np.argsort(-angles)
.
Here is what the points look like before and after ordering:
In [20]: arr
Out[20]:
array([[508, 116],
[351, 129],
[371, 379],
[527, 366]])
In [21]: arr_sorted
Out[21]:
array([[527, 366],
[371, 379],
[351, 129],
[508, 116]])