【问题标题】:Why does this recursive function get me a "Maximum call stack size exceeded" error?为什么这个递归函数会给我一个“超出最大调用堆栈大小”的错误?
【发布时间】:2014-07-04 13:23:20
【问题描述】:

我正在使用 HTML 画布创建一个绘图应用程序,并且我正在尝试实现一个“油漆桶”工具,该工具将检测与单击的像素颜色相同的任何相邻像素,并用新的填充颜色。

我收到“未捕获的 RangeError:超出最大调用堆栈大小”,但我无法弄清楚我的逻辑有什么问题:

function fillTool(){
    theCanvas.mousedown(function(e){
        var baseColor = paintUtilities.getPixelColor(e.offsetX, e.offsetY);
        context.fillStyle = color;
        fillNeighbors(e.offsetX, e.offsetY, baseColor);
    });
}

function fillNeighbors(x, y, baseColor) {
    context.fillRect(x, y, 1, 1);
    if (x > 0 && paintUtilities.getPixelColor(x - 1, y) === baseColor) {
        fillNeighbors(x - 1, y, baseColor);
    }
    if (y > 0 && paintUtilities.getPixelColor(x, y - 1) === baseColor) {
        fillNeighbors(x, y - 1, baseColor);
    }
    if (x < theCanvas.attr("width") - 1 && paintUtilities.getPixelColor(x + 1, y) === baseColor) {
        fillNeighbors(x + 1, y, baseColor);
    }   
    if (y < theCanvas.attr("height") - 1 && paintUtilities.getPixelColor(x, y + 1) === baseColor) {
        fillNeighbors(x, y + 1, baseColor);
    }   

}

【问题讨论】:

  • 显然fillNeighbors 调用自身次数过多。因此,您的条件之一可能不正确。 Learn how to debug JavaScript,添加一些console.log 语句,你会明白的。
  • 因为在某些时候你会得到x 等于width - 一个不存在的坐标。 x 应该只允许上升到width-1yheight 相同。
  • this answer 有什么解释吗?
  • 换句话说,我的逻辑没有任何“错误”,但如果我分别填充每个像素,我的浏览器仍然无法处理这么多的函数调用。如果不是逐个像素地实现此工具,还有其他想法吗?
  • @Noam the Wikipedia article on flood fill 有一些基本构建自己的堆栈的想法。

标签: javascript jquery html canvas


【解决方案1】:

实际上再看一遍,我发现你的代码有问题,它确实有无限递归!

假设你从 x = 1 开始,x 可以从 0 到 2。你首先向左走,然后递归调用函数。那个函数最终会向右走!然后这个循环将永远重复。您需要跟踪您访问过的地方,或者向递归函数传递一个不继续的方向,或者类似的东西。

【讨论】:

  • 除了它还进行颜色检查 - 如果该位置已被绘制,它不会递归到新位置。
  • 一方面,baseColor 和 fillColor 相同。 console.log(x) 可能会告诉你,无论出于何种原因,这已经发生了,即使它们不同。
  • @HamzaKubba,我相信 Pointy 是对的。在 baseColor 和 fillColor 相同的情况下,我将有一个条件不会开始颜色填充
  • @Noam 也许getPixelColor 不能为您提供与填充颜色完全匹配的===,原因可能包括舍入或抗锯齿?您是否尝试过记录一些值?
【解决方案2】:

因为它是一个递归函数,并且在每个 if 语句中你一次又一次地调用它......该函数没有基本情况。

【讨论】:

  • 您确定该声明吗?
  • 我已经多次实现了几乎相同类型的递归函数而没有出现此错误。
  • 好像是这样,但我没有代码来检查它。你有其他解决方案吗?@NiettheDarkAbsol
猜你喜欢
  • 2018-10-28
  • 1970-01-01
  • 2015-02-06
  • 1970-01-01
  • 1970-01-01
  • 2023-02-04
  • 2012-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多