【发布时间】:2015-04-23 10:42:38
【问题描述】:
所以我尝试在 js 中实现floodfill algorithm 并想出了以下内容:
function floodAreaFromPoint(x,y) {
if(typeof pixel[x] == "undefined") pixel[x] = [];
pixel[x][y] = 1; // 1 for alpha
if(!coordsInPixelArray(x + 1,y)) floodAreaFromPoint(x + 1,y);
if(!coordsInPixelArray(x,y + 1)) floodAreaFromPoint(x,y + 1);
if(!coordsInPixelArray(x - 1,y)) floodAreaFromPoint(x - 1,y);
if(!coordsInPixelArray(x,y - 1)) floodAreaFromPoint(x,y - 1);
}
它工作得还不错,但是我在填充更大的区域(10000x10000)时遇到了一些问题,在这些区域中,这个算法会导致错误“超出最大调用堆栈”。我理解这个错误的含义,但我不知道我该如何解决这个问题......
我愿意用更高效的算法替换这个函数,但我认为这个问题的解决方案可能是结束递归(我不知道如何在 js 中正确实现)。
编辑:像素数组包含应填充的像素。当函数被调用时,它已经保存了所有的边框像素。
解决办法:
function flood(x,y) {
var nodes = [];
nodes.push({"x":x,"y":y});
while(nodes.length > 0) {
var p = nodes[nodes.length - 1];
if(coordsInPixelArray(p.x, p.y)) {
nodes.pop();
continue;
}
if(typeof pixel[p.x] == "undefined") pixel[p.x] = [];
pixel[p.x][p.y] = 1; // 1 for alpha
if(!coordsInPixelArray(p.x + 1, p.y)) nodes.push({"x": p.x + 1,"y": p.y});
if(!coordsInPixelArray(p.x - 1, p.y)) nodes.push({"x": p.x - 1,"y": p.y});
if(!coordsInPixelArray(p.x, p.y + 1)) nodes.push({"x": p.x,"y": p.y + 1});
if(!coordsInPixelArray(p.x, p.y - 1)) nodes.push({"x": p.x,"y": p.y - 1});
}
}
【问题讨论】:
-
这会无条件地填充整个矩阵。您不仅应该检查坐标是否有效,还应该检查不应该被淹没的像素。至少,您应该在递归之前检查当前像素是否已经为 1。否则,您将一遍又一遍地访问像素,即使您已经访问过它们。
-
另外:
if(typeof pixel[x] == "undefined") pixel[x] = [];你是在创建矩阵吗? -
忘了指出我之前用边框像素填充了像素数组。因此,如果我击中一个已经设置的像素,我知道它会被填充,我可以停在那里。
-
但是边界像素是什么?您的代码缺少检查条件。
-
函数 coordsInPixelArray 检查是否已经在矩阵中设置了像素。如果是这样,它是边框像素还是填充像素都没有关系,因为我不需要填充它或在它的方向上进一步操作。
标签: javascript algorithm recursion graphics rendering