Algorithm 如何对旋转矩形的点进行排序?

Algorithm 如何对旋转矩形的点进行排序?,algorithm,Algorithm,它是角度小于90度的旋转矩形。 它可能是时钟方向或逆时钟方向。我喜欢将这些点排序为矩形的原始序列。 就像文本注释一样,1、2、3、4 我的算法是: 1.找到最左边、最右边、最上面、最下面的点, 2.比较顶部的.x和底部的.x 3.根据比较值,可以找到四角序列。 4.从四个角点开始,计算矩形边缘的线函数,然后排列其他点 我不确定是否有其他更有效或更优雅的算法来解决这个问题。 多谢各位 假设矩形已顺时针旋转了一些小于90度的角度。在这种情况下,请注意,顶行中的第(i+1)个点始终位于第i个点的下方和

它是角度小于90度的旋转矩形。 它可能是时钟方向或逆时钟方向。我喜欢将这些点排序为矩形的原始序列。 就像文本注释一样,1、2、3、4

我的算法是: 1.找到最左边、最右边、最上面、最下面的点, 2.比较顶部的.x和底部的.x 3.根据比较值,可以找到四角序列。 4.从四个角点开始,计算矩形边缘的线函数,然后排列其他点

我不确定是否有其他更有效或更优雅的算法来解决这个问题。
多谢各位

假设矩形已顺时针旋转了一些小于90度的角度。在这种情况下,请注意,顶行中的第(i+1)个点始终位于第i个点的下方和右侧。因此,我们可以剥离行:

  • 按y坐标(即从上到下)按降序对所有点进行排序
  • 将这些已排序的点放入链接列表中。(这不是必需的,但可以提高点删除的效率。)
  • 设置i=1
  • 设置lastX=-inf
  • 将p设置为指向已排序点列表中的第一个元素。如果没有剩余的元素,我们就完成了
  • 从p开始,扫描点列表,直到找到一个x坐标大于lastX的点,表明它位于上一个添加点的右侧。(在每行的第一次迭代中,始终取列表中的第一个点。)
  • 如果可以找到这一点:

    • 从链接列表中删除此点并将其标记为i
    • 将p设置为列表中的下一个点
    • 设置i=i+1
    • 将lastX设置为刚添加点的x坐标
    • 转到6以查找此行中的下一个点
    否则:

    • 我们已经完成了这一行,其中的所有点都已从链表中删除。转到4开始下一行
  • 这是一个O(n^2)算法,因为一旦找到了一行中最右边的点,它就会在从顶部开始处理下一行之前浪费地遍历所有剩余的点。这可能已经足够好了,但是通过维护一个包含从左到右排序的所有点的单独链表,并在从上到下列表的每个节点中提供一个指向从左到右列表中相应节点的额外字段,时间复杂度可以降低到O(nlog n)。由于顶行中最右边的点始终是整个点集中最右边的点,因此我们可以通过测试刚刚删除的点是否对应于整个从左到右列表中的最后一点来检测一行何时在短短的O(1)时间内完成。无论何时从上到下列表中删除点,都必须从左到右列表中删除该点


    但是如果矩形是逆时针旋转的呢?正如评论家n.m.指出的那样,如果没有进一步的信息,就无法将这种情况与顺时针旋转区分开来:逆时针旋转d度的n×m矩形看起来完全像顺时针旋转(90-d)度的m×n矩形。如果您有一些其他信息可以区分这些情况,则可以使用与之前相同的算法处理逆时针旋转,但要注意第一行(或任何一行)的宽度,然后重新排列标签。

    假设矩形已顺时针旋转了一些小于90度的角度。在这种情况下,请注意,顶行中的第(i+1)个点始终位于第i个点的下方和右侧。因此,我们可以剥离行:

  • 按y坐标(即从上到下)按降序对所有点进行排序
  • 将这些已排序的点放入链接列表中。(这不是必需的,但可以提高点删除的效率。)
  • 设置i=1
  • 设置lastX=-inf
  • 将p设置为指向已排序点列表中的第一个元素。如果没有剩余的元素,我们就完成了
  • 从p开始,扫描点列表,直到找到一个x坐标大于lastX的点,表明它位于上一个添加点的右侧。(在每行的第一次迭代中,始终取列表中的第一个点。)
  • 如果可以找到这一点:

    • 从链接列表中删除此点并将其标记为i
    • 将p设置为列表中的下一个点
    • 设置i=i+1
    • 将lastX设置为刚添加点的x坐标
    • 转到6以查找此行中的下一个点
    否则:

    • 我们已经完成了这一行,其中的所有点都已从链表中删除。转到4开始下一行
  • 这是一个O(n^2)算法,因为一旦找到了一行中最右边的点,它就会在从顶部开始处理下一行之前浪费地遍历所有剩余的点。这可能已经足够好了,但是通过维护一个包含从左到右排序的所有点的单独链表,并在从上到下列表的每个节点中提供一个指向从左到右列表中相应节点的额外字段,时间复杂度可以降低到O(nlog n)。由于顶行中最右边的点始终是整个点集中最右边的点,因此我们可以通过测试刚刚删除的点是否对应于整个从左到右列表中的最后一点来检测一行何时在短短的O(1)时间内完成。无论何时从上到下列表中删除点,都必须从左到右列表中删除该点

    但是如果矩形是逆时针旋转的呢?正如评论家n.m.指出的那样,如果没有进一步的信息,就无法将这种情况与顺时针旋转区分开来:一个n×m的矩形逆时针旋转了d度