泛洪填充算法会导致堆栈溢出错误。

4
我正在使用Java编写一个简单的绘图应用程序。我试图使用递归实现的Flood Fill算法作为我的“填充桶”工具,但是无论我使用“填充桶工具”的区域有多小,这总是给我一个StackOverFlowError。
编辑:更改代码以使其更有效。仍然是相同的错误。
以下是代码:
public void floodFill(int x, int y, Color targetColor, Color replacementColor) throws AWTException{

    pixelColor = robot.getPixelColor(x,y);

    g.setColor(replacementColor);
    g.fillRect(x, y, 1, 1);

    if(robot.getPixelColor(x-1, y).equals(targetColor))
        floodFill(x-1, y, targetColor, replacementColor);

    if(robot.getPixelColor(x+1, y).equals(targetColor))
        floodFill(x+1, y, targetColor, replacementColor);

    if(robot.getPixelColor(x, y-1).equals(targetColor))
        floodFill(x, y-1, targetColor, replacementColor);

    if(robot.getPixelColor(x, y+1).equals(targetColor))
        floodFill(x, y+1, targetColor, replacementColor);

}

我想知道是否有一种方法可以在不出现错误的情况下仍然使用递归来实现此算法。
如果没有,那么有哪些可能的非递归实现算法可以在我的程序中使用?

1
看起来所有这些花哨的像素操作都没有什么用,因为fillRect只关注mouseLocation - Kevin
除非您的目标颜色等于替换颜色,否则我无法看到它如何终止。将if语句更改为检查pixelColor是否等于replacementColor。 请注意,这是机器翻译,可能不是完美的中文。 - Jyro117
一个(天真的)解决方案是增加堆栈大小(-Xss)。另一个(超出范围)是用迭代替换递归。您可以通过检查当前像素是否在被淹没的区域内来改进算法。此外,您可以提供包含访问过的像素的二维数组,并将其与当前像素进行比较。最重要的一点是:stackoverflow.com不是错误!;-) - wypieprz
当前的问题是因为您的条件缺少一个情况:if(robot.getPixelColor(x-1, y).equals(targetColor) && !robot.getPixelColor(x-1, y).equals(replacementColor)) - Jyro117
1
你应该始终(尤其是现在)发布一个“最小、完整、可测试和可读”的示例。在你这样做之前,我认为我们无法提供帮助。此外,如果你进行调试,这可能不会太难解决。 - Bernhard Barker
显示剩余4条评论
3个回答

1

在函数开头检查当前位置的颜色。

如果它已经具有替换颜色,则已经访问了该点并可以返回。

public void floodFill(int x, int y, Color targetColor, Color replacementColor) throws AWTException{
{
  if(robot.getPixelColor(x, y).equals(replacementColor))
    return;
...
}

1

此外,您还需要检查已设置的目标颜色,否则会一遍又一遍地覆盖相同的目标颜色。


对不起,我误解了这个。 - Smutje

0
实现桶填充的更好方法是找出包含鼠标点击位置的图形或区域。(例如)如果您在圆形内部单击(没有其他对象),则希望填充圆形。因此,如果您维护某种区域映射,就可以快速确定鼠标点击位置所在的区域,并使用现有方法(来自某些标准Java或外部软件)填充该区域以获得颜色。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接