在javascript

时间:2018-02-11 20:57:15

标签: algorithm path-finding flood-fill

假设我在javascript中有一个网格表示如下:**注意这只是一个很小的网格作为例子。



{
    "width": 5,
    "height": 5,
    "nodes": [
        [{
            "x": 0,
            "y": 0,
            "walkable": true
        }, {
            "x": 1,
            "y": 0,
            "walkable": true
        }, {
            "x": 2,
            "y": 0,
            "walkable": true
        }, {
            "x": 3,
            "y": 0,
            "walkable": true
        }, {
            "x": 4,
            "y": 0,
            "walkable": true
        }],
        [{
            "x": 0,
            "y": 1,
            "walkable": true
        }, {
            "x": 1,
            "y": 1,
            "walkable": true
        }, {
            "x": 2,
            "y": 1,
            "walkable": true
        }, {
            "x": 3,
            "y": 1,
            "walkable": true
        }, {
            "x": 4,
            "y": 1,
            "walkable": true
        }],
        [{
            "x": 0,
            "y": 2,
            "walkable": true
        }, {
            "x": 1,
            "y": 2,
            "walkable": true
        }, {
            "x": 2,
            "y": 2,
            "walkable": true
        }, {
            "x": 3,
            "y": 2,
            "walkable": true
        }, {
            "x": 4,
            "y": 2,
            "walkable": true
        }],
        [{
            "x": 0,
            "y": 3,
            "walkable": true
        }, {
            "x": 1,
            "y": 3,
            "walkable": true
        }, {
            "x": 2,
            "y": 3,
            "walkable": true
        }, {
            "x": 3,
            "y": 3,
            "walkable": true
        }, {
            "x": 4,
            "y": 3,
            "walkable": true
        }],
        [{
            "x": 0,
            "y": 4,
            "walkable": true
        }, {
            "x": 1,
            "y": 4,
            "walkable": true
        }, {
            "x": 2,
            "y": 4,
            "walkable": true
        }, {
            "x": 3,
            "y": 4,
            "walkable": true
        }, {
            "x": 4,
            "y": 4,
            "walkable": true
        }]
    ]
}




" walkable" boolean将确定哪些区域被阻止可以这么说。

我如何挖掘这个网格以标记孤立区域?在上面的示例中,泛洪填充将使用单一颜色填充整个网格,因为所有区域都是可步行的。但假设电网有一些区域无法从其他区域(基于可步行的布尔),我如何标记不同的区域?我基本上想为每个节点设置一个颜色属性。如果节点与另一个节点的颜色不同,那么我知道它不能从该节点到达。

编辑:

这是我到目前为止所拥有的。无法在节点上运行此操作而不会出现最大调用堆栈错误:



function floodFill(node, grid) {

    if (node.walkable == false) {
        return;
    }
    if ((node.floodColor != undefined) && (node.floodColor == 'red')) {
        return;
    }

    node.floodColor = 'red';

    if ((grid.nodes[node.y + 1] != undefined) && (grid.nodes[node.y + 1][node.x] != undefined)) {
        floodFill(grid.nodes[node.y + 1][node.x], grid);
    }
    if ((grid.nodes[node.y - 1] != undefined) && (grid.nodes[node.y - 1][node.x] != undefined)) {
        floodFill(grid.nodes[node.y - 1][node.x], grid);
    }

    if ((grid.nodes[node.y] != undefined) && (grid.nodes[node.y][node.x + 1] != undefined)) {

        floodFill(grid.nodes[node.y][node.x + 1], grid);

    }

    if ((grid.nodes[node.y] != undefined) && (grid.nodes[node.y][node.x - 1] != undefined)) {

        floodFill(grid.nodes[node.y][node.x - 1], grid);

    }

}




对于那些做出回答的人,以上就是我要找的东西。关于做什么的描述对我没有帮助,因为我已经阅读了很多关于该怎么做的描述。明确代码:p

2 个答案:

答案 0 :(得分:0)

只需从许多不同的位置重复填充洪水。只要确保不填充相同的区域两次,并且您的算法仍将在线性时间内工作,假设邻域的合理表示(例如矩阵)。

n_colors = 0;
for field in grid:
    if field has no color assigned yet:
        floodFill(fromField: field, color: n_colors)
        n_colors = n_colors + 1

答案 1 :(得分:0)

我会试试这个:

  • 首先创建一个resultMap,它是当前网格的副本,带有逐个颜色属性,将所有walkable === false点设置为color: black

    const floodMap = yourData.nodes
       .map(n => n.map(p => {...p, {color: p.walkable ? 'black': undefined ));
    
  • 创建一个函数flood(x, y, color),它在输入中占据一席之地。如果此点已经着色,则不执行任何操作(并返回false),否则应用color根据您的规则获取(4或8)连接点(如果它们没有着色),并运行{{1在他们身上(并返回true)。

    flood(x', y', color)
  • 通过每次前一次调用返回true时更改颜色,为矩阵的每个点应用此函数。

    function flood(x, y, color) {
        if(!floodMap[y][x].color) {
          floodMap(x + 1, y, color);
          floodMap(x - 1, y, color);
          floodMap(x, y + 1, color);
          floodMap(x, y - 1, color);
          return true;
        }
        return false;
    }