问题描述
我有一些坐标点作为列表,它们首先根据 x
和 y
值进行排序。我尝试了 this solution 和 this one 但它对我不起作用。这是我的观点的简化集:
points=[[0.,0.],[0.,1.],[1.,2.],3.],[2.,0.]]
我想以顺时针角度使用它们。我的无花果清楚地表明了这一点。我从第一点开始(这里是 (0,0)
)并放置其他具有相同 x
值但它们的 y
值更高的点。然后,我去寻找它们的 x
值为 1
的点,并从较高的 y
值排序到较低的值。在点 (1,1)
之后,我有两个具有相同 y
的点,我首先选择具有较高 x
的点。最后,我想将我的排序列表设为:
resor_poi=[[0.,0.]]
解决方法
一种方法是计算每个点相对于中心的角度(例如所有点的平均值),然后根据角度对点进行排序。要计算角度,您可以使用 atan2
函数。
如果该方法的结果没有给出您想要的顺序,请搜索 TSP(旅行商问题)。一般来说很难解决(是一个 NP 问题),但如果点的数量很少,它可以准确地解决。如果点数很大,那么有算法可以近似找到一个好的解决方案。
,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.,2.],3.],[2.,0.]]
rotational_sort(points,(0,0),True)
[[0.0,0.0],[0.0,1.0],[1.0,3.0],2.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]
它返回点的极坐标(角度、距离),如果您随后对其进行排序,则应以一致的方式解决这些数量级的决胜局。
附言归功于它 - @Diego Palacios 的 atan2
正是从笛卡尔对转换为角度的东西,可能还有一种更整洁的方法可以沿着这些线进行我的第二次计算的幅度部分。我还在此有用的讨论中“借用”了一个有用的 argsort
函数:Equivalent of Numpy.argsort() in basic python? 由 @Boris Gorelik 提供