提问人:Al_Pacino 提问时间:9/13/2023 最后编辑:Al_Pacino 更新时间:9/13/2023 访问量:83
排序坐标 [已关闭]
Sort coordinates [closed]
问:
你能帮我正确地对点(x 和 y 对谱)列表(数组)进行排序吗? 我使用了以下功能,但它并不总是给我想要的。 示例是所附的图片。
我希望按以下顺序连接点:1 -> 2 -> 3 -> 4 -> 5。
但是,它们按拧紧顺序连接:1 -> 4 -> 2 -> 3 -> 5。
如何编辑代码以制作我想要的东西?
感谢您的帮助!
我想要这个特定的顺序,以便 voronoi 区域正确连接,如下图所示(蓝线)。我拥有的点是定义特定区域的 voronoi 图中的点。 简而言之,我将尝试在示例中解释我正在尝试做什么:
- 假设我有 15 组点。在每组点中,可以有不同数量的点。
- 15 个点中的第一组点是我感兴趣的集合,因为考虑到所有其他 14 组点,我想在第一组点周围获得沃罗诺伊区域。假设在第一组点中有 10 个点。
- 因此,为了做到这一点,我合并了所有 15 组点的点,创建了一个 voronoi 图。
- 从那个 voronoi 图中,我知道前 10 个点来自第一组点周围的区域,所以我可以得到它们并合并在一起。
- “combined_coords”是我的第一组点周围的沃罗诺伊地区的点。
- 现在我想对它们进行排序,以便以正确的顺序从它们定义多边形,就像在 voronoi 图上一样。
- 我无法访问 shapely、geopandas 等库。只有 numpy 和 scipy。
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
答:
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 差异的左右邻居)。我相信这可能有效,但必须进行测试+稍作修改。class
sort it
binary 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 个,其他点组合如何选择?
评论