将单元格组转换为多边形的算法
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
但是,它没有正确地对它们进行排序,如果我遍历每个顶点从它到前一个顶点画一条线,它会产生一团糟
我如何创建一个算法来生成排序的顶点列表以创建多边形?
您可以采用这种方法:
为每个顶点(角)创建节点对象。每个节点都有(唯一的)x、y 坐标和四个对邻居的引用:上、右、下、左。这些中的每一个要么引用另一个节点(指针),要么为空(当该方向上没有边缘时)。例如,如果您有两个相邻的单元格,则此步骤将创建 6 个节点(不是 8 个,因为这些单元格共享 2 个顶点,并且只应为每个唯一顶点创建一个节点)。您将为这些节点创建一个哈希表 (dictionary/map),以它们的 x、y 坐标为键,以避免为同一顶点创建多个节点。
找到最北端的节点。这是起始节点。也将其命名为当前节点。
将当前方向设置为“右”
当当前节点在当前方向有邻居时,做:
- 使那个邻居成为当前节点
- 将(现在)当前节点添加到解决方案
- 改变counter-clockwise旋转的方向,如果对了就补上。如果它是起来的,让它离开,...等等
- 如果当前节点为起始节点,则结束算法
由于当前节点在当前方向上已经没有邻居了,所以改变当前方向顺时针旋转,如果是对的就向下。如果它向下,让它离开,...等等
从第 4 步开始重复。
这假设所有的单元格都是相连的,并且形成的形状没有被完全包围的孔。
假设我目前有一组细胞可以被认为是“开”或“关”,就像这张照片(白色表示关闭,黑色表示打开)
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
但是,它没有正确地对它们进行排序,如果我遍历每个顶点从它到前一个顶点画一条线,它会产生一团糟
我如何创建一个算法来生成排序的顶点列表以创建多边形?
您可以采用这种方法:
为每个顶点(角)创建节点对象。每个节点都有(唯一的)x、y 坐标和四个对邻居的引用:上、右、下、左。这些中的每一个要么引用另一个节点(指针),要么为空(当该方向上没有边缘时)。例如,如果您有两个相邻的单元格,则此步骤将创建 6 个节点(不是 8 个,因为这些单元格共享 2 个顶点,并且只应为每个唯一顶点创建一个节点)。您将为这些节点创建一个哈希表 (dictionary/map),以它们的 x、y 坐标为键,以避免为同一顶点创建多个节点。
找到最北端的节点。这是起始节点。也将其命名为当前节点。
将当前方向设置为“右”
当当前节点在当前方向有邻居时,做:
- 使那个邻居成为当前节点
- 将(现在)当前节点添加到解决方案
- 改变counter-clockwise旋转的方向,如果对了就补上。如果它是起来的,让它离开,...等等
- 如果当前节点为起始节点,则结束算法
由于当前节点在当前方向上已经没有邻居了,所以改变当前方向顺时针旋转,如果是对的就向下。如果它向下,让它离开,...等等
从第 4 步开始重复。
这假设所有的单元格都是相连的,并且形成的形状没有被完全包围的孔。