Ruby 如何对点对进行排序,以便它们相互连接?

Ruby 如何对点对进行排序,以便它们相互连接?,ruby,geometry,Ruby,Geometry,我有一个向量对数组,它们都是沿多边形顺时针方向的边。问题是,它们的顺序不对。我希望对它们进行排序,以便阵列的起点和终点是相同的向量,并且每个单独的点重叠(端点到起点): 最常用的Ruby方式是什么 编辑:矢量是“矩阵”库中的对象,但它们可以像数组一样进行索引,例如未排序的_点[0][0][0]是-5首先将原始点对数组转换为地图,第一个点为键,第二个点为值: ptsMap = Hash[ * unsorted_points.flatten(1) ] => {Vector[-5, 0] =

我有一个向量对数组,它们都是沿多边形顺时针方向的边。问题是,它们的顺序不对。我希望对它们进行排序,以便阵列的起点和终点是相同的向量,并且每个单独的点重叠(端点到起点):

最常用的Ruby方式是什么


编辑:矢量是“矩阵”库中的对象,但它们可以像数组一样进行索引,例如
未排序的_点[0][0][0]
-5
首先将原始点对数组转换为地图,第一个点为键,第二个点为值:

ptsMap = Hash[ * unsorted_points.flatten(1) ]

=> {Vector[-5, 0]  => Vector[-3, 2],
    Vector[-3, 2]  => Vector[3, 2],
    Vector[-3, -2] => Vector[-5, 0],
    Vector[3, 2]   => Vector[5, 0],
    Vector[3, -2]  => Vector[-3, -2],
    Vector[5, 0]   => Vector[3, -2] }
然后从第一个点对开始,通过贴图从第二个点链接到第一个点(我注意到数组不包含“点”,它包含两点之间的边):

ordered_edges=(1…unsorted_points.size)。注入([unsorted_points.first])do|acc_|
nextPt=附件最后[1]
acc[[向量[-5,0],向量[-3,2]],
[向量[-3,2],向量[3,2]],
[向量[3,2],向量[5,0]],
[向量[5,0],向量[3,-2]],
[向量[3,-2],向量[-3,-2]],
[向量[-3,-2],向量[-5,0]]
请注意,在此上下文中,点不具有严格的可比性,因此不存在总排序(如简单的
排序所需)。每个点对都描述了一条边,该边提供了部分排序。假设第一条边的头部是您想要的第一个点,上面将找到一个候选总排序


如果原始列表实际上没有描述一组离散连接点,则此技术将失败。使用Ruby可能会得到更可靠的结果。Ruby为此提供了一个库:。使用此库,您可以检测原始边集何时不是单个强连接组件。

[编辑:我最初提出了两种方法,一种是使用排序,另一种是递归。@dbenhur表明,
sort
不起作用,因为数组中的元素没有完整的排序。因此,我删除了这种方法。作为记录,我误导排序的核心是:

 unsorted.sort {|v1,v2| (v1 == first || v1[1]==v2[0]) ? -1 : 1}
第二种方法是使用递归。经过反思,很明显我可以在一个简单的循环中做同样的事情,如下所示。]

sorted = [unsorted_points.shift]
until unsorted_points.empty?
  node = sorted[-1][1]
  target = unsorted_points.find {|e| e[0] == node}
  sorted << unsorted_points.delete(target)
end
sorted
  # => [[Vector[-5,  0], Vector[-3,  2]],
        [Vector[-3,  2], Vector[ 3,  2]],
        [Vector[ 3,  2], Vector[ 5,  0]],
        [Vector[ 5,  0], Vector[ 3, -2]],
        [Vector[ 3, -2], Vector[-3, -2]],
        [Vector[-3, -2], Vector[-5,  0]]]
sorted=[unsorted_points.shift]
直到未排序的_点为空?
节点=已排序[-1][1]
目标=未排序的_点。查找{| e | e[0]==节点}
已排序[[Vector[-5,0],Vector[-3,2]],
[向量[-3,2],向量[3,2]],
[向量[3,2],向量[5,0]],
[向量[5,0],向量[3,-2]],
[向量[3,-2],向量[-3,-2]],
[向量[-3,-2],向量[-5,0]]

你需要告诉我们什么是向量,特别是如何从向量中提取坐标。@sawa在Ruby stdlib中;假设我们知道这一点,这个问题似乎是合理的。:)我认为在一般情况下,你不可能真正做出一个
排序
。它意外地在OPs原始排序上起作用,但它在其他初始排序上失败了(例如:
[[Vector[5,0],Vector[3,2]],[Vector[-3,2],Vector[3,2]],[Vector[-5,0],Vector[-3,2]],[Vector[3,2],Vector[3,2][5,0]]、[Vector[3,-2]、[Vector[-3,-2]]、[Vector[-3,-2]、[Vector[-5,0]]]]
当我对你的评论中的数组应用
排序时,我得到了以下结果('Vector'未显示):
[[5,0]、[3,-2]]、[3,-2]、[-3,-2]、[-3,-2]、[5,0]、[-5,0]、[-5,2]、[-5,2]、[-5,2]、[3,2]、[3,2]、[5]
。这不对吗?@dbenhur,你可能对
@sort
不起作用是正确的,因为我们没有完整的排序。我想考虑一下。我假设
@sort
在所有连续对满足排序时终止。在ruby 2.0.0p195中,
[[Vector[5,0],Vector[3,-2],[Vector[-3,2],Vector[3,2]],[矢量[3、[2、[3、[3、[5、[5、[5、[5、[5、[5、[5、[5、[5、[5、[5、[5、[5、[5、[5、[5、[5、[0.0.0.0.0.0.矢量[[5,5,0,0,0]矢量.矢量[[3,0,0,0.0,0,0,0.矢量]]矢量.矢量.矢量[5,0.矢量.矢量.矢量.矢量.矢量.矢量.矢量.矢量.矢量.矢量.3.矢量.矢量.3.矢量.矢量.矢量.3.3.3,5.矢量.矢量.3,5.矢量.3,5.矢量.3.3.矢量.矢量.3.矢量.3.3.矢量.3.3.矢量.矢量.3.3.矢量.3.3.矢量.3.3.3.3.矢量.3.3.3.矢量.3,Vector[3,-2]],[Vector[3,-2],Vector[-3,-2]]].
数组#排序
是一种分而治之的算法,它将数组划分为选定轴上下的子数组,然后递归到每个子数组中。当它下降到单个元素的分区时终止。
 unsorted.sort {|v1,v2| (v1 == first || v1[1]==v2[0]) ? -1 : 1}
sorted = [unsorted_points.shift]
until unsorted_points.empty?
  node = sorted[-1][1]
  target = unsorted_points.find {|e| e[0] == node}
  sorted << unsorted_points.delete(target)
end
sorted
  # => [[Vector[-5,  0], Vector[-3,  2]],
        [Vector[-3,  2], Vector[ 3,  2]],
        [Vector[ 3,  2], Vector[ 5,  0]],
        [Vector[ 5,  0], Vector[ 3, -2]],
        [Vector[ 3, -2], Vector[-3, -2]],
        [Vector[-3, -2], Vector[-5,  0]]]