From d0c8e2dbeeb59fdb37ead20613962d066edaf826 Mon Sep 17 00:00:00 2001 From: rei Date: Sun, 26 May 2013 01:11:01 +0400 Subject: [PATCH 1/3] avoid staircase for A* --- lib/pathfinding-browser.js | 17 +++++++++++++++-- visual/index.html | 2 ++ visual/js/panel.js | 5 ++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/pathfinding-browser.js b/lib/pathfinding-browser.js index de1a371b..1e125084 100644 --- a/lib/pathfinding-browser.js +++ b/lib/pathfinding-browser.js @@ -1208,6 +1208,7 @@ function AStarFinder(opt) { this.dontCrossCorners = opt.dontCrossCorners; this.heuristic = opt.heuristic || Heuristic.manhattan; this.weight = opt.weight || 1; + this.avoidStaircase = opt.avoidStaircase; } /** @@ -1224,6 +1225,7 @@ AStarFinder.prototype.findPath = function(startX, startY, endX, endY, grid) { heuristic = this.heuristic, allowDiagonal = this.allowDiagonal, dontCrossCorners = this.dontCrossCorners, + avoidStaircase = this.avoidStaircase, weight = this.weight, abs = Math.abs, SQRT2 = Math.SQRT2, node, neighbors, neighbor, i, l, x, y, ng; @@ -1236,6 +1238,10 @@ AStarFinder.prototype.findPath = function(startX, startY, endX, endY, grid) { openList.push(startNode); startNode.opened = true; + // to avoid staircase + var turnPenalty = 1; + var lastDirection = undefined; + // while the open list is not empty while (!openList.empty()) { // pop the position of node which has the minimum `f` value. @@ -1261,7 +1267,14 @@ AStarFinder.prototype.findPath = function(startX, startY, endX, endY, grid) { // get the distance between current node and the neighbor // and calculate the next g score - ng = node.g + ((x - node.x === 0 || y - node.y === 0) ? 1 : SQRT2); + ng = node.g + ((x - node.x === 0 || y - node.y === 0) ? 1 : SQRT2); + + if (avoidStaircase) + { + lastDirection = node.parent == undefined? undefined : { x : node.x - node.parent.x, y : node.y - node.parent.y }; + var turned = lastDirection == undefined? 0 : lastDirection.x != x - node.x || lastDirection.y != y - node.y; + ng += turnPenalty * turned; + } // check if the neighbor has not been inspected yet, or // can be reached with smaller cost from the current node @@ -2006,4 +2019,4 @@ require.define("/PathFinding.js", function (require, module, exports, __dirname, }); require("/PathFinding.js"); -return require("/PathFinding");})(); \ No newline at end of file +return require("/PathFinding");})(); diff --git a/visual/index.html b/visual/index.html index b5c36615..e7a408c8 100644 --- a/visual/index.html +++ b/visual/index.html @@ -70,6 +70,8 @@

Options



+ +

diff --git a/visual/js/panel.js b/visual/js/panel.js index 3f6846b5..297c2f55 100644 --- a/visual/js/panel.js +++ b/visual/js/panel.js @@ -41,6 +41,8 @@ var Panel = { '.bi-directional:checked').val() !=='undefined'; dontCrossCorners = typeof $('#astar_section ' + '.dont_cross_corners:checked').val() !=='undefined'; + avoidStaircase = typeof $('#astar_section ' + + '.avoid_staircase:checked').val() !=='undefined'; /* parseInt returns NaN (which is falsy) if the string can't be parsed */ weight = parseInt($('#astar_section .spinner').val()) || 1; @@ -59,7 +61,8 @@ var Panel = { allowDiagonal: allowDiagonal, dontCrossCorners: dontCrossCorners, heuristic: PF.Heuristic[heuristic], - weight: weight + weight: weight, + avoidStaircase: avoidStaircase }); } break; From 92abd255d703f45b5641e22989cfe2073e6c7ff4 Mon Sep 17 00:00:00 2001 From: rei mai Date: Sun, 26 May 2013 18:47:38 +0400 Subject: [PATCH 2/3] tabs -> spaces --- lib/pathfinding-browser.js | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/lib/pathfinding-browser.js b/lib/pathfinding-browser.js index 1e125084..9170fa66 100644 --- a/lib/pathfinding-browser.js +++ b/lib/pathfinding-browser.js @@ -1208,7 +1208,7 @@ function AStarFinder(opt) { this.dontCrossCorners = opt.dontCrossCorners; this.heuristic = opt.heuristic || Heuristic.manhattan; this.weight = opt.weight || 1; - this.avoidStaircase = opt.avoidStaircase; + this.avoidStaircase = opt.avoidStaircase; } /** @@ -1225,9 +1225,10 @@ AStarFinder.prototype.findPath = function(startX, startY, endX, endY, grid) { heuristic = this.heuristic, allowDiagonal = this.allowDiagonal, dontCrossCorners = this.dontCrossCorners, - avoidStaircase = this.avoidStaircase, + avoidStaircase = this.avoidStaircase, weight = this.weight, abs = Math.abs, SQRT2 = Math.SQRT2, + turnPenalty = 1, lastDirection = undefined, node, neighbors, neighbor, i, l, x, y, ng; // set the `g` and `f` value of the start node to be 0 @@ -1238,10 +1239,6 @@ AStarFinder.prototype.findPath = function(startX, startY, endX, endY, grid) { openList.push(startNode); startNode.opened = true; - // to avoid staircase - var turnPenalty = 1; - var lastDirection = undefined; - // while the open list is not empty while (!openList.empty()) { // pop the position of node which has the minimum `f` value. @@ -1267,14 +1264,15 @@ AStarFinder.prototype.findPath = function(startX, startY, endX, endY, grid) { // get the distance between current node and the neighbor // and calculate the next g score - ng = node.g + ((x - node.x === 0 || y - node.y === 0) ? 1 : SQRT2); - - if (avoidStaircase) - { - lastDirection = node.parent == undefined? undefined : { x : node.x - node.parent.x, y : node.y - node.parent.y }; - var turned = lastDirection == undefined? 0 : lastDirection.x != x - node.x || lastDirection.y != y - node.y; - ng += turnPenalty * turned; - } + ng = node.g + ((x - node.x === 0 || y - node.y === 0) ? 1 : SQRT2); + + + if (avoidStaircase) { + // add additional cost if neighbor creates a turn + lastDirection = node.parent == undefined? undefined : { x : node.x - node.parent.x, y : node.y - node.parent.y }; + var turned = lastDirection == undefined? 0 : lastDirection.x != x - node.x || lastDirection.y != y - node.y; + ng += turnPenalty * turned; + } // check if the neighbor has not been inspected yet, or // can be reached with smaller cost from the current node From 3aad91fb65d9ec98ef8ddde80a59ee826d33341f Mon Sep 17 00:00:00 2001 From: rei mai Date: Sun, 26 May 2013 18:51:01 +0400 Subject: [PATCH 3/3] tabs -> spaces --- visual/js/panel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visual/js/panel.js b/visual/js/panel.js index 297c2f55..49e6565d 100644 --- a/visual/js/panel.js +++ b/visual/js/panel.js @@ -62,7 +62,7 @@ var Panel = { dontCrossCorners: dontCrossCorners, heuristic: PF.Heuristic[heuristic], weight: weight, - avoidStaircase: avoidStaircase + avoidStaircase: avoidStaircase }); } break;