将单元格组转换为多边形的算法

Algorithm to convert cell groups into a polygon

假设我目前有一组细胞可以被认为是“开”或“关”,就像这张照片(白色表示关闭,黑色表示打开)

Cells

单元格基本上是大小为1的正方形,每个角可以通过以下方式计算:

p0 = p
p1 = p + (0, 1)
p2 = p + (1, 1)
p3 = p + (1, 0)

所以每个单元格本身实际上是一个具有 4 个顶点的多边形

我想生成一个有序的顶点列表,创建一个多边形,其中所有单元格都组合在一起,删除内部和冗余顶点,如下所示:

Cells Grouped

所以,我在尝试解决这个问题时遇到的算法只检测顶点,并且它们检测正确,实际上它的代码非常简单。它是这样工作的:

foreach cell
    foreach corner of the cell //each corner is a vertex of a square cell
        if !vertex_list.contains(corner) 
            vertex_list.add(corner)
        else 
        vertex_list.remove(corner)
            endif
        endfor
endfor

但是,它没有正确地对它们进行排序,如果我遍历每个顶点从它到前一个顶点画一条线,它会产生一团糟

我如何创建一个算法来生成排序的顶点列表以创建多边形?

您可以采用这种方法:

  1. 为每个顶点(角)创建节点对象。每个节点都有(唯一的)x、y 坐标和四个对邻居的引用:上、右、下、左。这些中的每一个要么引用另一个节点(指针),要么为空(当该方向上没有边缘时)。例如,如果您有两个相邻的单元格,则此步骤将创建 6 个节点(不是 8 个,因为这些单元格共享 2 个顶点,并且只应为每个唯一顶点创建一个节点)。您将为这些节点创建一个哈希表 (dictionary/map),以它们的 x、y 坐标为键,以避免为同一顶点创建多个节点。

  2. 找到最北端的节点。这是起始节点。也将其命名为当前节点。

  3. 将当前方向设置为“右”

  4. 当当前节点在当前方向有邻居时,做:

    • 使那个邻居成为当前节点
    • 将(现在)当前节点添加到解决方案
    • 改变counter-clockwise旋转的方向,如果对了就补上。如果它是起来的,让它离开,...等等
    • 如果当前节点为起始节点,则结束算法
  5. 由于当前节点在当前方向上已经没有邻居了,所以改变当前方向顺时针旋转,如果是对的就向下。如果它向下,让它离开,...等等

  6. 从第 4 步开始重复。

这假设所有的单元格都是相连的,并且形成的形状没有被完全包围的孔。