[英]How to sort coordinates in python in a clockwise direction
I have some coordinate points as list which are sorted firstly based on the x
and then y
values.我有一些坐标点作为列表,首先根据
x
和y
值排序。 I tried this solution and also this one but it did not work for me.我尝试了这个解决方案和这个解决方案,但它对我不起作用。 This is a simplified set of my points:
这是我的一组简化的观点:
points=[[0.,0.],[0.,1.],[1.,0.],[1.,1.],[1.,2.],[1.,3.],[2.,0.]]
I want to resort them in a clockwise angle.我想以顺时针的角度使用它们。 My fig clearly shows it.
我的无花果清楚地表明了这一点。 I start from the first point (it is
(0,0)
here) and put other point which have the same x
value but their y
is higher.我从第一个点开始(这里是
(0,0)
),然后放置具有相同x
值但它们的y
更高的其他点。 Then, I go for the points that their x
values is 1
and sort from higher y
values to lower ones.然后,我对它们的
x
值为1
的点进行 go 并从较高的y
值到较低的排序。 After point (1,1)
I have two points with the same y
and I pick first the point with higher x
.在点
(1,1)
之后,我有两个y
相同的点,我首先选择x
较高的点。 Finally I want to to have my sorted list as:最后我想让我的排序列表为:
resor_poi=[[0.,0.],[0.,1.],[1.,3.],[1.,2.],[1.,1.],[2.,0.],[1.,0.]]
One way would be to compute the angle of each point with respect the center (mean of all points for example), and then sort the points according to the angle.一种方法是计算每个点相对于中心的角度(例如所有点的平均值),然后根据角度对点进行排序。 To compute the angle, you can use the
atan2
function.要计算角度,您可以使用
atan2
function。
If the results from that method don't give the order you desire, search for the TSP (Travelling Salesman Problem).如果该方法的结果没有给出您想要的顺序,请搜索 TSP(旅行推销员问题)。 In general is difficult to solve (is a NP problem) but it can be solved exactly if the numbers of points is small.
一般来说很难解决(是一个 NP 问题),但如果点的数量很少,它可以准确地解决。 If the number of points is large, then there are algorithms that approximately find a good solution.
如果点的数量很大,那么有一些算法可以近似地找到一个好的解决方案。
from math import atan2
def argsort(seq):
#http://stackoverflow.com/questions/3382352/equivalent-of-numpy-argsort-in-basic-python/3382369#3382369
#by unutbu
#https://stackoverflow.com/questions/3382352/equivalent-of-numpy-argsort-in-basic-python
# from Boris Gorelik
return sorted(range(len(seq)), key=seq.__getitem__)
def rotational_sort(list_of_xy_coords, centre_of_rotation_xy_coord, clockwise=True):
cx,cy=centre_of_rotation_xy_coord
angles = [atan2(x-cx, y-cy) for x,y in list_of_xy_coords]
indices = argsort(angles)
if clockwise:
return [list_of_xy_coords[i] for i in indices]
else:
return [list_of_xy_coords[i] for i in indices[::-1]]
points=[[0.,0.],[0.,1.],[1.,0.],[1.,1.],[1.,2.],[1.,3.],[2.,0.]]
rotational_sort(points, (0,0),True)
[[0.0, 0.0],
[0.0, 1.0],
[1.0, 3.0],
[1.0, 2.0],
[1.0, 1.0],
[1.0, 0.0],
[2.0, 0.0]]
Notice the last two points have the same angle from the centre, so it's a toss up to say which one should come first.请注意,最后两点与中心的角度相同,所以要说哪一个应该先出现是一个折腾。
If you wanted to force closer points to be first, or last in this situation, you could include a secondary metric (say distance) to be included in the thing to be sorted.如果您想在这种情况下强制较近的点排在第一位或最后,您可以在要排序的事物中包含一个次要指标(例如距离)。
eg augment the angles
list with something that includes a distance value - maybe something like:例如,使用包含距离值的内容来增加
angles
列表 - 可能类似于:
polar_coords = [(atan2(x-cx, y-cy), ((x-cx)**2)+((y-cy)**2)) for x,y in list_of_xy_coords]
Which returns the polar coordinates (angle,distance) of the points, which if you then sorted, should resolve these magnitude-tie-breaks in a consistent fashion.它返回点的极坐标(角度,距离),如果您随后对其进行排序,则应该以一致的方式解决这些幅度-tie-breaks。
PS Credit where it's due - @Diego Palacios's atan2
is precisely the thing to convert from cartesian pairs to angles, there's probably a more tidy way to do the magnitude part of my second calculation along those lines too. PS Credit 应得的-@Diego Palacios 的
atan2
正是将笛卡尔对转换为角度的东西,可能还有一种更整洁的方法来完成我的第二次计算的幅度部分。 I've also "borrowed" a useful argsort
function here from an answer to this helpful discussion: Equivalent of Numpy.argsort() in basic python?我还从对这个有用讨论的回答中“借用”了一个有用的
argsort
function: Equivalent of Numpy.argsort() in basic python? courtesy of @Boris Gorelik由@Boris Gorelik 提供
To copy the answer from @Thomas Kimber, this is a version in numpy that also calculates the center point by taking the mean of all points in each dimension:要复制@Thomas Kimber 的答案,这是 numpy 中的一个版本,它还通过取每个维度中所有点的平均值来计算中心点:
def rotational_sort(list_of_xy_coords):
cx, cy = list_of_xy_coords.mean(0)
x, y = list_of_xy_coords.T
angles = np.arctan2(x-cx, y-cy)
indices = np.argsort(angles)
return list_of_xy_coords[indices]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.