【问题标题】:I want Flood Fill without stack and without recursion我想要没有堆栈且没有递归的洪水填充
【发布时间】:2011-04-29 12:11:00
【问题描述】:

我想知道如何在数组上应用洪水填充,我的数组是二维的,其中包含 times new roman 字体类型字母边界。 边界线包含 1 和内部和外部全 0。 我想只在里面填写所有 1 而不是 0。 但我需要一个不需要更多内存的逻辑。 所以避免递归和堆栈或队列

【问题讨论】:

  • 你能添加一个你的数组beforeafter的例子吗?
  • 你打算如何指定一个绝对在轮廓内部(或外部)的点? (想象一个网格作为输入——哪些方块被填充,哪些不被填充?)这对于断开连接的字形(如“:”)和任何轮廓与边界接触的字形都是必需的。
  • 你的数组中包含什么类型? (巧妙地询问 {0,1} 还有多少值可供使用。)

标签: graphics recursion stack flood-fill


【解决方案1】:

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

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;
}

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

【讨论】:

  • 你先生,太棒了。 :)
【解决方案2】:

你的任务没有多大意义。如果你有一个字体,你不想用泛色填充来填充它,而是直接将它渲染为填充多边形。如果不能可靠地给出良好的结果,则确定哪些部分进出字体,尤其是对于衬线字体。

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

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

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

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

结果:

00011110001111000

这也适用于位图,但如果您实际上总是有两个边界用于开始和停止。

【讨论】:

    【解决方案3】:
    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
    

    关键是您必须能够判断一个像素已被填充(用未使用的颜色填充它)。而且,这会非常慢。

    【讨论】:

    • RegularFloodFill 是 LowMemFloodFill 就像 QuickSort 是 BubbleSort。
    【解决方案4】:

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

    【讨论】:

    • 我不使用单独的数组,a[][]是图片数组。
    • @Oli Charlesworth:很聪明,但是为了防止这种情况偏离轨道,您需要防止您的足迹与所使用的颜色相邻。据推测,您假设负数不能出现在图像中。如果是这样,这意味着分配给图像的位比正在使用的位多...
    猜你喜欢
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多