我想要没有堆栈和没有递归的Flood Fill

时间:2010-10-23 06:54:17

标签: graphics recursion stack flood-fill

我想知道如何在数组上应用泛洪填充,我的数组是二维的,其中包含新罗马字体类型字母边界的时间。 边界线包含1个,内部和外部都是0。 我想在内部填充所有1而不是0。 但我需要一个不需要更多内存的逻辑。 所以避免递归和堆栈或队列

4 个答案:

答案 0 :(得分:4)

我通常不会为其他人做作业,但我喜欢这个挑战:

int c = -1;
while (c < 0)
{    
    /* Store breadcrumb trail, look to carry on */
    a[x][y] = c--;
    if (!hunt(0))
    {
        /* Nowhere to go, so back-track by looking for breadcrumb */
        a[x][y] = 1;
        c += 2;
        hunt(c);
    }
}

bool_t hunt(int v)
{
    if (a[x-1][y] == v)  { x--; return TRUE; }
    if (a[x+1][y] == v)  { x++; return TRUE; }
    if (a[x][y-1] == v)  { y--; return TRUE; }
    if (a[x][y+1] == v)  { y++; return TRUE; }
    return FALSE;
}

请注意,这不会检查是否碰到了数组的边缘。此外,它假设您的数组元素是例如int,并且您只在图片中使用了值01

答案 1 :(得分:1)

你的任务没有多大意义。如果您有字体,则不希望用填充填充它,而是直接将其渲染为填充多边形。确定哪些部件进出字体,特别是对于衬线字体,如果不能可靠地给出良好的结果。

填充多边形的典型示意图算法是这样的(不需要堆栈或递归),并且它也可以在某些条件下应用于位图(我将会这样做):

对于每一行(或列,更适合您的数据结构),在您跟随的虚拟线和所有多边形线(边界)的每个交叉点处切换填充。

假设这个(可能是O字符的中间行):

00010010001001000
   ^  ^   ^  ^
   |  |   |  stop
   |  |   start
   |  stop
   start

结果:

00011110001111000

这也适用于位图,但如果你实际上总是有两个启动和停止边界,那么只能

答案 2 :(得分:0)

function LowMemFloodFill(pixel)
  FillPixel(pixel)
  Do
    didFill = false
    For each pixel
      If current pixel has been filled
        For each adjacent pixel
          If adjacent has not been filled
            FillPixel(adjacent)
            didFill = true
          End
        End
      End
    End
  While didFill
End

问题在于你必须能够分辨出一个像素已被填充(用未使用的颜色填充)。此外,这将非常缓慢。

答案 3 :(得分:-1)

你基本上不能。您必须在某处存储此信息,因为在完成当前部分后,您必须知道在哪里开始填充。递归允许您隐式执行。保持自己的堆栈可以让您明确地执行它,可能会节省一些。 Oli Charlesworth通过保持与图片大小相同的数组来做一件可爱的事情,但它使用的内存比递归或保留一堆位置更多。