star-寻路算法

作为一个前端er,想玩一下简单例子的算法 一

A*star寻路算法

估价函数

f(n) = g(n) + h(n)
其中f(n)是起始节点(起始位置)与结束节点(结束位置)的距离,g(n)是当前节点(当前位置)与起始节点(起始位置)的距离,h(n)是当前节点(当前位置)与结束节点(结束位置)的距离,我们可以通过估价函数来判断当前位置的周围位置那个是离结束位置最近的位置来作为我们的下一个位置,从而到达终点!

demo
// f(n) = g(n) + h(n)
// n 表示当前节点
// g 表示起始点到节点的距离
// h 表示节点到目标点的距离

// f(n)
function f(nodeLi) {
    return g(nodeLi) + h(nodeLi)
}

// g(n)
function g(nodeLi) {
    var a = nodeLi.offsetLeft - beginNode[0].offsetLeft
    var b = nodeLi.offsetTop - beginNode[0].offsetTop
    var l = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2))
    return l
}

// h(n) 
function h(nodeLi) {
    var a = nodeLi.offsetLeft - endNode[0].offsetLeft
    var b = nodeLi.offsetTop - endNode[0].offsetTop
    var l = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2))
    return l
}

实现过程

利用两个队列
openArr:排序估价函数
colosArr:排除干扰节点
查询当前节点的周围节点

function findNode(nowNode) {
    var result = []
    for(var i = 0; i < aLi.length; i++) {
        if(filter(aLi[i])) {
            result.push(aLi[i])
        }
    }

    function filter(node) {
        for(var i = 0; i < closeArr.length; i++) {
            if(closeArr[i] == node) {
                return false
            }
        }
        for(var i = 0; i < openArr.length; i++) {
            if(openArr[i] == node) {
                return false
            }
        }
        return true
    }

    for(var i = 0; i < result.length; i++) {
        if((Math.abs(nowNode.offsetLeft - result[i].offsetLeft) <= sizeGird + 1) && (Math.abs(nowNode.offsetTop - result[i].offsetTop) <= sizeGird + 1)) {
            result[i].num = f(result[i])
            result[i].parent = nowNode
            openArr.push(result[i])
        }
    }
}

设置父节点指针作为显示路径使用

function showLine() {
    var result = []
    var num = 0
    var lastNode = closeArr.pop()
    findParent(lastNode)
    function findParent(node) {
        result.unshift(node)
        if(node.parent == beginNode[0]) {
            return
        }
        findParent(node.parent)
    }

    var timer = setInterval(function() {
        result[num].style.background = 'red'
        num++
        if(num == result.length) {
            clearInterval(timer)
        }
    }, 500)
}

你可能感兴趣的:(玩算法)