Threejs路径规划_基于A*算法案例完整版

        上节利用了A*实现了基础的路径规划,这节把整个功能完善好,A*算法一方面是基于当前点找到可以到达的点,计算从出发点到此点,以及此点到目的地的总成本,比较出最小的那个,再用最小成本的点继续找到它可以到达的点,直到目的地,同时会创建两个集合,一个叫open集合,一个叫close集合,open是用于存放到达过且没有继续探索的点,close集合是存放到达过且继续探索的点,简单的说A*算法会一边探索的同时会把新探索到的点放到open集合中,一边把探索过的点加入到close集合中。这样可以防止重复探索之前的点,如果探测到的点包含目标点。则探索结束。下面我们用图例的方式演示整个过程

        如图在网格中有出发点和目的地,分别在网格的两侧,如果要从出发点到达目的地,A*算法会先获取到Start可以到达的四个点,将四个点放到open集合中,然后选出四个点中到达End成本做小的,

        此时可以明显的看出右侧的格子到End点的成本最小,这里的成本包括已经花费的成本和到End点预估的成本,

得到了成本最小的点后,再继续基于这个点继续探索周围的点,同时会将探索过的Start点放到close集合中,经过探索,仍然是右侧点成本最低,然后将探索到的点放到open中,探索过的点放到close中,继续探索,依此类推,直到探索到End点。

然后我们按照上述方式将方法改造如下:

buildPath() {
      // 选择的起始点和目标点
      if (this.beginPoint.x > 30 || this.beginPoint.y > 30 || this.endPoint.x > 30 || this.endPoint.y > 30) {
        this.$message.error('超出地图范围')
        return
      }
      const begin = (parseInt(this.beginPoint.x) - 1) + '.' + (this.beginPoint.y - 1)
      const end = (parseInt(this.endPoint.x) - 1) + '.' + (this.endPoint.y - 1)
      this.removeOnce() // 移除上一次规划的内容
      this.drawPoint(begin) // 将出发点绘制到地图上
      this.openPoint.push({ point: begin, distance: 0 })
      let current = { point: begin, path: [begin], distance: 0 }
      while (current.point !== end) {
        const result = this.recursion(current, end)
        current = result
      }
      this.pathRoad = current.path.split('_')
      for (let i = 0; i < this.pathRoad.length; i++) {
        this.drawPoint(this.pathRoad[i])
      }
    },
    calcDistance(start, end) {
      const beginX = start.split('.')[0]
      const beginY = start.split('.')[1]
      const endX = end.split('.')[0]
      const endY = end.split('.')[1]
      // 获取到达的点与目的地的曼哈顿距离
      const distance = Math.abs(parseInt(endX - beginX)) + Math.abs(parseInt(endY - beginY))
      return distance
    },
    recursion(current, end) {
      const tempPoints = [] // 当前点可以连接的路线
      // 获取到这个点能到达的所有点的路线
      for (let i = 0; i < this.roadList.length; i++) {
        if (this.roadList[i].begin === current.point) {
          tempPoints.push(this.roadList[i].end)
        }
      }

      for (let i = 0; i < tempPoints.length; i++) {
        const hadSpend = parseInt(current.distance) + 1 // 已经花费的成本,也就是起点到当前点的成本(是上一个点+1得到)
        const remainingEstimated = this.calcDistance(tempPoints[i], end) // 下一个点到目标点的成本,也就是剩余预估成本
        const totalCost = parseInt(hadSpend) + parseInt(remainingEstimated)
        const path = current.path + '_' + tempPoints[i]

        // 如果点已经在close中了就不加入openList中
        let havaClose = false
        for (let j = 0; j < this.closePoint.length; j++) {
          if (this.closePoint[j].point === tempPoints[i]) {
            havaClose = true
          }
        }
        if (!havaClose) {
          this.openPoint.push({ point: tempPoints[i], haveCost: hadSpend, path: path, remainingCost: remainingEstimated, distance: totalCost })
        }
      }
      // 从开放点中去掉已经走过的点,并加入到close点集合中
      for (let i = 0; i < this.openPoint.length; i++) {
        if (this.openPoint[i].point === current.point) {
          this.openPoint.splice(i, 1)
          this.closePoint.push(current)
          i--
        }
      }
      // 比较openList中哪个distance的成本最小就用此继续递归
      let result = { point: this.openPoint[0].point, distance: this.openPoint[0].distance }
      // 获取到目的地最近的点并返回
      for (let i = 0; i < this.openPoint.length; i++) {
        if (this.openPoint[i].distance <= result.distance) {
          result = { point: this.openPoint[i].point, haveCost: this.openPoint[i].haveCost, path: this.openPoint[i].path, distance: this.openPoint[i].distance }
        }
      }
      const data = { point: result.point, path: result.path, distance: result.haveCost }
      return data
    },

效果如下:

        此时输入出发点和目标点后会直接算出路径,并把路径绘制在网格上,但是我们是基于threejs的,可以再增加点动画效果,在计算出路径后,通过threejs的动画每隔一定的时间绘制出一个点,就时间了动画效果,代码如下:

      roadIndex: 0,
      pathRoad: [],
      times: 0 
initAnimate() {
      requestAnimationFrame(this.initAnimate)
      this.renderer.render(this.scene, this.camera)
      if (this.pathRoad.length > 0 && this.roadIndex < this.pathRoad.length - 1) {
        this.times += 0.1
        if (this.times > 1) {
          this.times = 0
          this.roadIndex += 1
          this.drawPoint(this.pathRoad[this.roadIndex])
        }
      }
    },

演示地址:贝壳智能制造

效果如下:

基于A*算法的Threejs动画

如果觉得不错,给我点个赞吧,需要源码可以关注微信公众号“贝壳智能制造”获取,或者可以给我留言。

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 无人机路径规划是指在给定的三维环境中寻找一条最优路径,使得无人机从起始点到目标点之间能够避开障碍物,并满足其他约束条件。而A*算法是一种广泛应用于路径规划问题的启发式搜索算法,通过综合考虑每个节点的实际代价和预估代价,来寻找最优路径。 A*算法的具体步骤如下: 1. 初始化一个open列表和一个closed列表,将起始点加入到open列表中; 2. 重复以下步骤直到找到目标点或者open列表为空: a. 在open列表中选择代价最小的节点,将其标记为当前节点,并将其从open列表中移除; b. 将当前节点加入到closed列表中; c. 对当前节点的相邻节点进行遍历,计算它们的实际代价和预估代价(通常使用欧氏距离等启发式函数),并更新它们的父节点; d. 如果相邻节点已经存在于closed列表中,则忽略该节点; e. 如果相邻节点已经存在于open列表中并且新的路径更好(代价更小),则更新该节点的代价和父节点; f. 如果相邻节点不存在于open列表中,则将其加入open列表中; 3. 如果open列表为空,则无法找到路径;否则,从目标点逆向遍历父节点,得到路径。 在无人机三维路径规划中,A*算法需要进行适当的修改以考虑高度或者三维坐标的变化。我们可以使用三维欧氏距离或其他适当的启发式函数来估计节点之间的距离。此外,对于无人机飞行的特殊限制条件,例如最小转弯半径、最大爬升速度等,也需要在评估节点时进行考虑。 总之,基于A*算法的无人机路径规划方法能够通过综合考虑实际代价和预估代价,找到无人机三维环境中的最优路径,有效避开障碍物并满足其他飞行约束条件。 ### 回答2: 无人机路径规划是指根据特定的起点和终点,通过选择合适的路径来实现无人机从起点到终点的导航操作。在三维空间中,无人机的路径规划问题更为复杂,需要考虑高度、避障等因素。 A*算法是一种常用的启发式搜索算法,可以用于无人机三维路径规划。它将搜索空间划分为一个个小区域,每个区域都有一个启发式评估函数来估计该区域到目标的代价。在搜索过程中,根据当前位置和目标位置的启发式评估值,选择代价最小的邻近节点进行扩展,直到找到最优路径。 对于无人机路径规划,A*算法可以按照以下步骤进行求解: 1. 确定无人机的起点和终点,并初始化起点的搜索开销为0。 2. 创建一个开放列表和一个闭合列表。开放列表用于存储待扩展的节点,闭合列表用于存储已经扩展过的节点。 3. 将起点添加到开放列表中,并开始循环搜索。 4. 从开放列表中选取代价最小的节点,作为当前节点。 5. 如果当前节点是终点,则路径规划完成,返回路径。 6. 否则,将当前节点加入闭合列表,并对其邻近节点进行检查。 7. 对于每个邻近节点,计算其到起点的实际代价,并计算到终点的启发式评估值。 8. 如果该邻近节点在闭合列表中,则忽略它。如果不在开放列表中,则将其加入开放列表,并更新其启发式评估值。 9. 如果该邻近节点已经在开放列表中,比较其当前的实际代价,如果新的代价更小,则更新该节点的实际代价和父节点,并重新计算其启发式评估值。 10. 返回步骤4,直到找到最优路径或开放列表为空。 通过以上步骤,A*算法可以找到最优的三维路径规划,实现无人机从起点到终点的导航操作。同时,可以根据具体应用场景的需求,针对性地对A*算法进行改进和优化,提高路径规划的效率和准确性。 ### 回答3: 无人机三维路径规划是指根据目标点和环境条件,找到无人机从起点到目标点的最优路径。A*算法是一种常用的启发式搜索算法,结合了广度优先搜索和迪杰斯特拉算法的特点,适用于解决此类问题。 在使用A*算法进行无人机路径规划时,首先需要定义节点的表示和评估函数。以三维空间中的坐标为节点表示,节点的评估函数一般由两部分组成:启发函数和路径成本函数。 启发函数用于评估当前节点到目标节点的估计距离,可以使用曼哈顿距离、欧几里得距离等方法。路径成本函数用于评估节点到起点的实际路径成本,可根据实际情况定义。 接着,使用一个优先队列来保存待扩展的节点。首先将起点加入队列,并初始化节点的评估值。然后,从队列中取出评估值最小的节点进行扩展,并更新其相邻节点的评估值和路径成本。重复此过程,直到找到目标节点或优先队列为空。 在扩展节点时,需要考虑节点的合法性和可行性。对于无人机来说,需要考虑避开障碍物、避免碰撞等特殊情况。可以使用碰撞检测算法或避障策略来避免不必要的风险。 最后,当找到目标节点时,可以回溯路径,得到无人机从起点到目标点的最优路径。 总之,通过使用A*算法进行无人机三维路径规划,可以高效地找到起点到目标点的最优路径,提高无人机的自主导航能力和任务执行效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

baker_zhuang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值