排序坐标 [已关闭]

Sort coordinates [closed]

提问人:Al_Pacino 提问时间:9/13/2023 最后编辑:Al_Pacino 更新时间:9/13/2023 访问量:83

问:


想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。

2个月前关闭。

你能帮我正确地对点(x 和 y 对谱)列表(数组)进行排序吗? 我使用了以下功能,但它并不总是给我想要的。 示例是所附的图片。

我希望按以下顺序连接点:1 -> 2 -> 3 -> 4 -> 5。

但是,它们按拧紧顺序连接:1 -> 4 -> 2 -> 3 -> 5。

如何编辑代码以制作我想要的东西?

感谢您的帮助!

order_of_points

我想要这个特定的顺序,以便 voronoi 区域正确连接,如下图所示(蓝线)。我拥有的点是定义特定区域的 voronoi 图中的点。 简而言之,我将尝试在示例中解释我正在尝试做什么:

  1. 假设我有 15 组点。在每组点中,可以有不同数量的点。
  2. 15 个点中的第一组点是我感兴趣的集合,因为考虑到所有其他 14 组点,我想在第一组点周围获得沃罗诺伊区域。假设在第一组点中有 10 个点。
  3. 因此,为了做到这一点,我合并了所有 15 组点的点,创建了一个 voronoi 图。
  4. 从那个 voronoi 图中,我知道前 10 个点来自第一组点周围的区域,所以我可以得到它们并合并在一起。
  5. “combined_coords”是我的第一组点周围的沃罗诺伊地区的点。
  6. 现在我想对它们进行排序,以便以正确的顺序从它们定义多边形,就像在 voronoi 图上一样。
  7. 我无法访问 shapely、geopandas 等库。只有 numpy 和 scipy。

voronoi_diagram

combined_coords = np.array(
[[ 5766.28476155, 19516.99300136],
 [ 5765.3326747 , 19516.2217852 ],
 [ 5764.33255982, 19515.68693966],
 [ 5762.69492707, 19515.17292775],
 [ 5762.05045578, 19515.29517553],
 [ 5762.02505098, 19516.45055273],
 [ 5762.28121558, 19517.78513446],
 [ 5762.62958104, 19518.74867786],
 [ 5763.31238375, 19519.86920443],
 [ 5763.72620097, 19520.19250031],
 [ 5764.24999132, 19520.88744217],
 [ 5764.65547718, 19521.18117486],
 [ 5765.21676807, 19522.12631202],
 [ 5765.67501467, 19522.40253271],
 [ 5766.79878351, 19528.51536924],
 [ 5766.81357218, 19528.52972979],
 [ 5766.54317078, 19523.59611998],
 [ 5766.92157601, 19525.04371133],
 [ 5767.67457849, 19529.12581027],
 [ 5771.5263795 , 19524.43240175],
 [ 5770.59556598, 19522.45791971],
 [ 5770.45102759, 19521.34643935],
 [ 5769.91919814, 19521.21760643],
 [ 5768.52296931, 19520.39572883],
 [ 5767.63542881, 19519.1100208 ],
 [ 5767.57293753, 19519.06926975],
 [ 5766.99422734, 19518.06749945],
 [ 5766.76994398, 19517.86007797]]    
)
new_points = sorting_function(combined_coords)
def sorting_function(xy_e):
    #step 1
    xl=xy_e[:,0]
    yl=xy_e[:,1]
    xc=sum(xl)/len(xl)
    yc=sum(yl)/len(yl)

    xa=np.array(xl)-xc
    ya=np.array(yl)-yc

    #step 3
    q=[{},{},{},{}]
    for i in range(len(xa)):
        if (xa[i]<0 and ya[i]<0):
            q[0][i]=(xa[i],ya[i])
        elif (xa[i]<0 and ya[i]>0):
            q[1][i]=(xa[i],ya[i])
        elif (xa[i]>0 and ya[i]>0):
            q[2][i]=(xa[i],ya[i])
        else:
            q[3][i]=(xa[i],ya[i])

    #step 4        
    alpha={}
    for i in range(len(q)):
        for j in q[i].keys():
            beta=np.degrees(np.arctan(abs(q[i][j][1])/abs(q[i][j][0])))
            if i==0:
                s=90-beta
            elif i==1:
                s=90+beta
            elif i==2:
                s=270-beta
            else:
                s=270+beta
            alpha[j]=s

    #step 5  

    xy = xy_e.tolist()

    re_xy=[]
    sorted_alpha=sorted(alpha.values())
    for i in sorted_alpha:
        for k,l in alpha.items():
            if i==l:
                check_p=xy[k] in re_xy
                if not check_p:
                    re_xy.append(xy[k])
    return re_xy
Python 排序 坐标

评论

0赞 pho 9/13/2023
您看到想要按升序 y 坐标进行排序。
0赞 pho 9/13/2023
这回答了你的问题吗?如何对 x-y 坐标列表进行排序
4赞 trincot 9/13/2023
请解释一下你要遵循的逻辑。为什么你想要不同的顺序?它的定义是什么?
0赞 Tim Roberts 9/13/2023
您希望如何进行这种排序?作为人类,你可以看到它,但计算机怎么知道你想要什么呢?我想您可以在列表中搜索“最近的下一个点”。
0赞 Al_Pacino 9/13/2023
@trincot,编辑了带有解释的帖子

答:

1赞 strojan 9/13/2023 #1

似乎您只想按 y 值对坐标进行排序,这可以用更简单的方式完成。

coords = [[5,2],[2,7],[3,4]]   # Your array of coordinates

coords = sorted(coords, key=lambda x: x[1])

输出:[[5, 2], [3, 4], [2, 7]]

评论

0赞 user19077881 9/13/2023
也许值得指出的是,lambda 函数中的 x 是坐标对,x[1] 是 y 坐标。对于经验不足的人来说,另一个名字 wouid 更清楚。
0赞 Al_Pacino 9/13/2023
@strojan感谢您的解决方案,但它并没有达到我想要的效果。请尝试使用我添加到帖子中的点,您会发现点的顺序不正确,无法创建正确的形状。
-1赞 JohnyCapo 9/13/2023 #2

我可能会创建一个 and(走过它)就像(这取决于你)。您可以简单地从第一个点开始,然后找到下一个最近的点(根据 X + Y 差异的左右邻居)。我相信这可能有效,但必须进行测试+稍作修改。classsort itbinary tree or just regular tree

评论

0赞 Al_Pacino 9/13/2023
谢谢!我可以使用的代码有什么例子吗?
0赞 JohnyCapo 9/13/2023
我相信蒂姆·罗伯茨(Tim Roberts)刚刚为您说得很清楚。它按照我脑海中的方式工作。
2赞 Tim Roberts 9/13/2023 #3

这按最近距离排序。

import numpy as np
import matplotlib.pyplot as plt
import math

combined_coords = np.array(
[[ 5766.28476155, 19516.99300136],
 [ 5765.3326747 , 19516.2217852 ],
 [ 5764.33255982, 19515.68693966],
 [ 5762.69492707, 19515.17292775],
 [ 5762.05045578, 19515.29517553],
 [ 5762.02505098, 19516.45055273],
 [ 5762.28121558, 19517.78513446],
 [ 5762.62958104, 19518.74867786],
 [ 5763.31238375, 19519.86920443],
 [ 5763.72620097, 19520.19250031],
 [ 5764.24999132, 19520.88744217],
 [ 5764.65547718, 19521.18117486],
 [ 5765.21676807, 19522.12631202],
 [ 5765.67501467, 19522.40253271],
 [ 5766.79878351, 19528.51536924],
 [ 5766.81357218, 19528.52972979],
 [ 5766.54317078, 19523.59611998],
 [ 5766.92157601, 19525.04371133],
 [ 5767.67457849, 19529.12581027],
 [ 5771.5263795 , 19524.43240175],
 [ 5770.59556598, 19522.45791971],
 [ 5770.45102759, 19521.34643935],
 [ 5769.91919814, 19521.21760643],
 [ 5768.52296931, 19520.39572883],
 [ 5767.63542881, 19519.1100208 ],
 [ 5767.57293753, 19519.06926975],
 [ 5766.99422734, 19518.06749945],
 [ 5766.76994398, 19517.86007797]]    
)

def sorting_function(xy):
    xy = xy.tolist()
    out = [xy.pop(3)]
    while xy:
        dist = 9999999999999999999999
        distn = -1
        for n,x1y1 in enumerate(xy):
            d1 = math.dist(out[-1], x1y1)
            if d1 < dist:
                dist = d1
                distn = n
        print(distn)
        out.append( xy.pop(distn) )
    return np.array(out)
            
new_points = sorting_function(combined_coords)
x = new_points[:,0]
y = new_points[:,1]
plt.plot(x,y)
plt.show()

评论

0赞 JohnyCapo 9/13/2023
这正是我的意思@Al_Pacino 只是使用它。
1赞 Tim Roberts 9/13/2023
是的,但是..这并不像看起来那么酷,因为初始点的选择可能会有所不同。这很接近,但并不完美。
0赞 JohnyCapo 9/13/2023
每个代码在开始时都有自己的弱点,但你明确了该走哪条路。它只需要请求方提供更多的effor。
0赞 Al_Pacino 9/13/2023
谢谢大家!我测试了这组点,它按照我想要的方式工作。将测试所有其他点,因为我有数千个点:-)并将更新它的进展方式
0赞 Al_Pacino 9/13/2023
如何正确选择在“out = [xy.pop(3)]”里面弹出哪个点?为什么这里是 3 个,其他点组合如何选择?