【问题标题】:How to sort coordinates in python in a clockwise direction如何按顺时针方向对python中的坐标进行排序
【发布时间】:2021-08-16 12:07:27
【问题描述】:

我有一些坐标点作为列表,首先根据x 然后y 值排序。我试过this solutionthis one 但它对我不起作用。这是我的一组简化观点:

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.]]

我非常感谢您提前提供的任何帮助。

【问题讨论】:

  • 我建议从阅读stackoverflow.com/questions/6989100/…开始
  • 亲爱的@Daweo,我阅读了这个解决方案。谢谢你寄给我。但不幸的是它不在 Pythun 中,我认为如果我找到一种基于 xy 值对点进行排序的方法对我来说更有意义。
  • 这能回答你的问题吗? Sort points in clockwise order?
  • 亲爱的@Paul,不幸的是它对我没有帮助,因为它不在 python 中,相信对我来说,如果我处理 xy 值会更有效率。我想要一种将我的观点模式作为算法的方法。
  • 亲爱的@Ali_d,我强烈建议您阅读 cmets 中链接的问题和答案。此链接包含您所要求的答案。事实上,它们不在 python 中。答案描述了算法。在 python 中实现这些算法是你的工作。

标签: python algorithm sorting coordinates triangulation


【解决方案1】:
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]]

请注意,最后两点与中心的角度相同,所以要决定哪个先出现是一个折腾。

如果您想在这种情况下强制较近的点排在第一位或最后,您可以在要排序的事物中包含一个辅助指标(例如距离)。

例如使用包含距离值的内容扩充 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 的礼貌

【讨论】:

  • 亲爱的@Thomas Kimber,我尝试了你的方法,但不幸的是它在其他点数安排上失败了。你能帮我看看这个例子吗:points=[[1.,3.],[1.,4.],[2.,2.],[2.,4.],[3.,1.],[3.,4.],[4.,1.],[4.,2.],[4.,3.],[4.,4.]]。新的有序点不符合我想要的模式。很抱歉给您添了这么多麻烦。
  • 这是我收到的订单[[1.0, 4.0], [1.0, 3.0], [2.0, 4.0], [3.0, 4.0], [2.0, 2.0], [4.0, 4.0], [4.0, 3.0], [4.0, 2.0], [3.0, 1.0], [4.0, 1.0]]。当我在纸上绘图时看起来不错 - 再次 (2,2) 和 (4,4) 共享相同的角度,因此不确定您可能希望从原点顺时针扫描首先出现哪个。但是让建议的 polar_coordinates 改变可以解决这个问题。您希望该点集合的顺序是什么?
  • 我知道你的算法很好,但我想把它设为[[1.0, 3.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.0], [4.0, 4.0], [4.0, 3.0], [4.0, 2.0], [4.0, 1.0], [3.0, 1.0], [2.0, 2.0]]。我真的不知道如何从几何上说。如果您绘制它们并在此评论中查看我的排序,您会明白我的逻辑。再次感谢。
  • 我想通过这些点创建一个多边形,每个点都应该连接到下一个点。所以,我想以这种方式订购它们。
  • 好的,所以您希望它们按顺时针方向从图形的中心而不是从坐标系的原点开始。只需将centre_of_rotation_xy_coord 设置为位于您的形状内的坐标 - 例如,在位置 (3,3),您将获得所需的顺序。如果我这样做,我会得到[[2.0, 2.0], [1.0, 3.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.0], [4.0, 4.0], [4.0, 3.0], [4.0, 2.0], [4.0, 1.0], [3.0, 1.0]]
【解决方案2】:

一种方法是计算每个点相对于中心的角度(例如所有点的平均值),然后根据角度对点进行排序。要计算角度,可以使用atan2 函数。

如果该方法的结果没有给出您想要的顺序,请搜索 TSP(旅行推销员问题)。通常很难解决(是一个 NP 问题),但如果点的数量很少,它可以准确地解决。如果点的数量很大,那么有一些算法可以近似地找到一个好的解决方案。

【讨论】:

  • 感谢您花时间解决我的问题。你不认为可以将点的模式作为一种算法吗?恐怕角度不起作用。
  • 我不确定你所说的“点模式”是什么意思。您要解决的是找到具有这些点的多边形。但是,有多个多边形适合您的点(解决方案不是唯一的)。因此,您必须选择一个标准来找到您的多边形。求解 TSP 将为您提供周长最短的多边形。角度排序算法可能会给你另一个(或相同的)多边形。如果这些方法都没有给出你想要的,你必须首先清楚你的标准是什么来找到点的顺序。您当前的标准没有明确定义。
【解决方案3】:

要复制@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]

【讨论】:

    猜你喜欢
    • 2018-12-07
    • 2017-06-10
    • 2011-10-22
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-05
    • 2021-11-05
    相关资源
    最近更新 更多