如何按顺时针方向对python中的坐标进行排序
How to sort coordinates in python in a clockwise direction
我有一些坐标点作为列表,首先根据 x
值排序,然后根据 y
值排序。我试过 and also 但它对我不起作用。这是我的观点的简化集:
points=[[0.,0.],[0.,1.],[1.,0.],[1.,1.],[1.,2.],[1.,3.],[2.,0.]]
我想按顺时针方向对它们进行排序。我的无花果清楚地表明了这一点。我从第一点开始(这里是 (0,0)
),然后放置具有相同 x
值但 y
更高的其他点。然后,我找出它们的 x
值为 1
的点,并从较高的 y
值排序到较低的值。在点 (1,1)
之后,我有两个点具有相同的 y
,我首先选择具有更高 x
的点。最后我想让我的排序列表为:
resor_poi=[[0.,0.],[0.,1.],[1.,3.],[1.,2.],[1.,1.],[2.,0.],[1.,0.]]
非常感谢提前提供的任何帮助。
一种方法是计算每个点相对于中心的角度(例如所有点的平均值),然后根据角度对点进行排序。要计算角度,您可以使用 atan2
函数。
如果该方法的结果没有给出您想要的顺序,请搜索 TSP(旅行商问题)。一般来说很难解决(是一个NP问题)但是如果点的数量很少,它可以被精确解决。如果点数多,则有近似找到好的解的算法。
from math import atan2
def argsort(seq):
#
#by unutbu
#
# 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]]
请注意最后两个点与中心的角度相同,所以要决定哪个点先出现是一个问题。
如果您想在这种情况下强制将较近的点排在最前面或最后,您可以在要排序的事物中包含一个次要指标(比如距离)。
例如使用包含距离值的内容来扩充 angles
列表 - 可能类似于:
polar_coords = [(atan2(x-cx, y-cy), ((x-cx)**2)+((y-cy)**2)) for x,y in list_of_xy_coords]
returns 点的极坐标(角度、距离),如果您随后对其进行排序,应该以一致的方式解决这些幅度平局。
P.S。归功于它应得的 - @Diego Palacios 的 atan2
正是从笛卡尔对转换为角度的东西,可能还有一种更整洁的方法来沿着这些线进行我的第二次计算的幅度部分。我还从对这个有用讨论的回答中“借用”了一个有用的 argsort
函数:Equivalent of Numpy.argsort() in basic python? 由@Boris Gorelik 提供
复制@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]
我有一些坐标点作为列表,首先根据 x
值排序,然后根据 y
值排序。我试过
points=[[0.,0.],[0.,1.],[1.,0.],[1.,1.],[1.,2.],[1.,3.],[2.,0.]]
我想按顺时针方向对它们进行排序。我的无花果清楚地表明了这一点。我从第一点开始(这里是 (0,0)
),然后放置具有相同 x
值但 y
更高的其他点。然后,我找出它们的 x
值为 1
的点,并从较高的 y
值排序到较低的值。在点 (1,1)
之后,我有两个点具有相同的 y
,我首先选择具有更高 x
的点。最后我想让我的排序列表为:
resor_poi=[[0.,0.],[0.,1.],[1.,3.],[1.,2.],[1.,1.],[2.,0.],[1.,0.]]
非常感谢提前提供的任何帮助。
一种方法是计算每个点相对于中心的角度(例如所有点的平均值),然后根据角度对点进行排序。要计算角度,您可以使用 atan2
函数。
如果该方法的结果没有给出您想要的顺序,请搜索 TSP(旅行商问题)。一般来说很难解决(是一个NP问题)但是如果点的数量很少,它可以被精确解决。如果点数多,则有近似找到好的解的算法。
from math import atan2
def argsort(seq):
#
#by unutbu
#
# 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]]
请注意最后两个点与中心的角度相同,所以要决定哪个点先出现是一个问题。
如果您想在这种情况下强制将较近的点排在最前面或最后,您可以在要排序的事物中包含一个次要指标(比如距离)。
例如使用包含距离值的内容来扩充 angles
列表 - 可能类似于:
polar_coords = [(atan2(x-cx, y-cy), ((x-cx)**2)+((y-cy)**2)) for x,y in list_of_xy_coords]
returns 点的极坐标(角度、距离),如果您随后对其进行排序,应该以一致的方式解决这些幅度平局。
P.S。归功于它应得的 - @Diego Palacios 的 atan2
正是从笛卡尔对转换为角度的东西,可能还有一种更整洁的方法来沿着这些线进行我的第二次计算的幅度部分。我还从对这个有用讨论的回答中“借用”了一个有用的 argsort
函数:Equivalent of Numpy.argsort() in basic python? 由@Boris Gorelik 提供
复制@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]