效果图
BestFirstFinder
JumpPointFinder
支持跳跃
写在前面
最近突然有了兴趣研究路径规划算法,在网上找到了pathFinding路径规划算法库,用法也非常简单拿出来分享下,在此基础上改造可以实现简单的船舶避障
,贪吃蛇
,简单的路径规划
等等
git地址 www.npmjs.com/package/pat...
看这个文章前要知道的
- svg基础,会使用svg的path标签绘制路径
- 了解vue3语法
首先会绘制二维数组
js
const boxs = ref(Array.from({ length: 10 }, () => new Array(10).fill(0)))
然后渲染,结果就是这样从0-0到9-9,因为PF也是基于二维数组
PF算法的核心要点
- 需要起点和重点目标
- 设置障碍物,也就是需要绕过的地方
设置起点坐标,我这块处理的时候按照坐标点显示对应的文案
js
const START_COORDINATE = [9, 4] // 起点坐标
const END_COORDINAT = [0, 5] // 终点坐标
onBeforeMount(() => {
// 设置初始起点终点
const [x1, y1] = START_COORDINATE
const [x2, y2] = END_COORDINAT
boxs.value[x1][y1] = -1
boxs.value[x2][y2] = -2
})
其中 empty表示空也就表示没有障碍物,block表示有障碍物,success表示对的路径我会在这个类名的样式中添加脚印
绘制路径代码
js
const drawPath = async () => {
clearPath()
// 利用PF实现坐标路径规划
const Grid = new PF.Grid(10, 10)
const finder = new PF[unref(way)]()
boxs.value.forEach((e, i1) => {
e.forEach((e, i2) => {
if (e === 1) {
Grid.setWalkableAt(i1, i2)
}
})
})
const path = finder.findPath(
START_COORDINATE[0],
START_COORDINATE[1],
END_COORDINAT[0],
END_COORDINAT[1],
Grid
)
if (path.length === 0) {
ElMessage.warning("走不到对岸了")
return
}
// 坐标系转换
const pathString = path
.map((e) => `${e[1] * 50 + 25},${e[0] * 50 + 25}`)
.join("L")
svgPath.value = `M${pathString}`
ElNotification({
title: "提示",
message: `【${way.value}】路径规划完成,共计${path.length}步`,
duration: 0
})
for (let i = 0; i < path.length; i++) {
await new Promise((resolve) => {
setTimeout(() => {
resolve()
}, 200)
})
const [x, y] = path[i]
boxs.value[x][y] = 2
}
}
其中注意点就是svg的path绘制路径的时候,path是以屏幕坐标系为起点计算,但是路径给我们的相当于是三角函数坐标系
,这里要做转换。