如何顺时针或逆时针对坐标对象数组进行排序?

How to sort an array of coordinate objects clockwise or counterclockwise?

提问人:ivovchoc 提问时间:11/16/2023 最后编辑:ivovchoc 更新时间:11/19/2023 访问量:222

问:

演示:https://codesandbox.io/s/new-bird-rx8zxd


我有一个坐标对象数组,我需要实现一种排序机制,以顺时针或逆时针方向排列它们。起点可以是任何起点。在此示例中,磁贴大小为 54。相邻顶点具有相同的坐标。

此数组:

    [
      { x: 0, y: 108 },
      { x: 0, y: 54 },
      { x: 108, y: 108 },
      { x: 54, y: 54 },
      { x: 108, y: 0 },
      { x: 54, y: 0 }
    ]

应该分类如下:

    [
      { x: 54, y: 0 },
      { x: 108, y: 0 },
      { x: 108, y: 108 },
      { x: 0, y: 108 },
      { x: 0, y: 54 },
      { x: 54, y: 54 }      
    ]

示例 1:
Example 1

示例 2:
Example_2

这种按顺时针顺序对点进行排序的解决方案对我没有帮助。
特别是,它不适用于我描述的示例。

JavaScript 算法 排序 计算几何

评论

1赞 ivovchoc 11/16/2023
stackoverflow.com/questions/6989100/......这个解决方案对我没有帮助。例如,它不适用于我描述的示例。
0赞 jabaa 11/17/2023
您能否将您的尝试展示为带有调试详细信息的最小可重现示例?为什么在预期结果之间和预期结果之间?我认为另一个问题的答案对你不起作用,因为你的预期结果既不是顺时针排序也不是逆时针排序。{ x: 0, y: 54 }{ x: 108, y: 108 }{ x: 54, y: 54 }
0赞 ivovchoc 11/17/2023
@jabaa我在描述中为图像添加了坐标。我们有选择瓷砖的功能。例如,我选择了一个图形,如图所示。我计算了它的边缘点 - 这是我们的坐标数组。现在我需要按这个顺序对它们进行排序。
0赞 jabaa 11/17/2023
好的,现在我明白了顺序。我认为你应该寻找科学论文。我认为这是一个非常复杂的问题。我什至不确定这是否可能。我怀疑相同的点数组会导致不同的多边形。积分从何而来?也许你可以修复源头。
0赞 greybeard 11/17/2023
(最接近的原因是无稽之谈 - 没有什么可调试的。

答:

0赞 ruakh 11/19/2023 #1

与其把它看作是一个“排序”问题,不如把它看作是一个“找邻居”的问题;对于每个点,我们希望在列表中找到它旁边的点。

一些观察:

  • 所有点都是不同的;也就是说,永远不会有两个点具有相同的 X 坐标和相同的 Y 坐标。
  • 每个点都有两个相邻点:一个具有相同的 x 坐标,一个具有相同的 y 坐标。
  • 对于任何给定的 x 坐标,对于某些 k,将正好有 2个 k 点;同样,对于任何给定的 y 坐标。
  • 如果两个点是相邻点,则它们之间的线上没有其他点。更正式地说:如果 (x 1, y) 和 (x 2, y) 是邻居,那么没有 (x 3, y) 和 x 1 < x 3 < x2;x, y 1) 和 (xy2) 也是如此。
  • 因此,对于任何给定的 x 坐标,具有最小和第二少 y 坐标的点是相邻点,具有第三少和第四少 y 坐标的点是相邻点,依此类推;同样,对于任何给定的 y 坐标。

因此,我们可以按如下方式对列表进行“排序”:

  1. 首先,找到所有共享 x 坐标的邻居对。为此,请创建一个列表,其中包含按 x 坐标排序的点,并回退到按 y 坐标排序。然后是邻居,是邻居,等等。sortedByXThenYsortedByXThenY[0]sortedByXThenY[1]sortedByXThenY[2]sortedByXThenY[3]
  2. 接下来,通过执行相同的方法查找共享 y 坐标的所有相邻对象对。
  3. 选择某个点作为第一个点。选择第一个点的相邻点之一(例如,具有相同 x 坐标的相邻点)作为第二个点。选择第二个点的另一个相邻点(具有相同 y 坐标的相邻点)作为第三个点。继续,直到您选择了所有点。

评论

0赞 ivovchoc 11/19/2023
如果我理解正确的话,我尝试实现此功能。我添加了 rearrangePoints 函数,您可以在 DEMO 中查看它。这适用于简单的形状。但是,例如,如果我从瓷砖创建一个十字形,这是一个 12 边形,那么坐标就不再有序了。
0赞 ruakh 11/19/2023
@ivovchoc:对不起,我不会试图弄清楚你的演示。请在此处的问题中输入所有必要的信息。但是 FWIW,这种方法适用于像 . ➕
0赞 ivovchoc 11/19/2023
在确定形状的所有边缘点后,是否需要添加此功能?
0赞 ruakh 11/19/2023
@ivovchoc:“边缘点”是什么意思?输入应该是顶点列表(其中 n 表示 n 个顶点),输出将是(可能)不同顺序的相同 n 个顶点的列表。
0赞 ivovchoc 11/19/2023
是的,这就是我的意思。我所说的边缘点是指形状的所有角。好的,我会尝试更多地使用这种方法。