如何在不经过障碍物的情况下检测从点A到点B的最短路径?

5

我一直在尝试创建一个jQuery代码,它会扫描ID为map

,并选择其中所有的.map元素,并找到从#A#B的最短路径,同时尽可能避开/不碰触#blockings,但我对如何实现后者毫无头绪。

非常感谢任何帮助。

说明: enter image description here

这是我的代码

computeTrack('#a','#b', '#map');

function computeTrack(A, B, MAP){
  
  var bag = [];
  var obstacle = [];
  
  bag = getDistance(A, B);
  obstacle = scanning(A, B, MAP);
  moveAtoB(A, B, MAP, obstacle, bag);
}

function moveAtoB(A, B, MAP, obstacle, bag){
  var clone;
  $(A).append('<div id="clone" style="position:fixed;width:5px; height:5px; background-color:#F00; top:'+$(A).position().top+'; left:'+$(A).position().left+';"></div>');
  
  clone = '#clone';
  generatePath(clone, A, B, MAP, obstacle, bag);
}

function generatePath(clone, A, B, MAP, obstacle, bag){ //Here lies the challenge
  if(bag[1] == 'top left'){    
    /*$(clone).stop().animate({
      top:$(B).offset().top,
      left:$(B).offset().left
    },Math.round(bag[0]*50),'linear');*/
  }else if(bag[1] == 'top right'){
    console.log(bag[1]);
  }else if(bag[1] == 'bottom left'){
    console.log(bag[1]);
  }else if(bag[1] == 'bottom right'){
    console.log(bag[1]);
  }
}

function collided(obj1, obj2) {
  var x1 = $(obj1).offset().left;
  var y1 = $(obj1).offset().top;
  var h1 = $(obj1).outerHeight(true);
  var w1 = $(obj1).outerWidth(true);
  var b1 = y1 + h1;
  var r1 = x1 + w1;
  var x2 = $(obj2).offset().left;
  var y2 = $(obj2).offset().top;
  var h2 = $(obj2).outerHeight(true);
  var w2 = $(obj2).outerWidth(true);
  var b2 = y2 + h2;
  var r2 = x2 + w2;
  
  if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2) return false;
  return true;
}

function scanning(A, B, MAP){
  var allObjects = [];
  
  $(MAP+' > *').map(function(){
    if(('#'+$(this).attr('id')) !== A && ('#'+$(this).attr('id')) !== B){
      allObjects.push(('#'+$(this).attr('id')));
    }
  });
  
  return allObjects;
}

function getDistance(object, target){
  var bag = [];
  var message = '';
  var distance = 0;
  var objectPos = $(object).offset();
  var targetPos = $(target).offset();
  
  if(objectPos.top > targetPos.top){
    message += 'bottom';
  }else if(objectPos.top <= targetPos.top){
    message += 'top';
  }
  if(objectPos.left > targetPos.left){
    message += ' right';
  }else if(objectPos.left <= targetPos.left){
    message += ' left';
  }
  
  if(message == 'top left'){
    distance = Math.sqrt(((targetPos.top - objectPos.top)*(targetPos.top - objectPos.top)) + ((targetPos.left - objectPos.left)*(targetPos.left - objectPos.left)));
  }
  if(message == 'top right'){
    distance = Math.sqrt(((targetPos.top - objectPos.top)*(targetPos.top - objectPos.top)) + ((objectPos.left - targetPos.left)*(objectPos.left - targetPos.left)));
  }
  if(message == 'bottom left'){
    distance = Math.sqrt(((objectPos.top - targetPos.top)*(objectPos.top - targetPos.top)) + ((targetPos.left - objectPos.left)*(targetPos.left - objectPos.left)));
  }
  if(message == 'bottom right'){
    distance = Math.sqrt(((objectPos.top - targetPos.top)*(objectPos.top - targetPos.top)) + ((objectPos.left - targetPos.left)*(objectPos.left - targetPos.left)));
  }
  bag.push(distance, message);
  return bag;
}
<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
    <title>AtoB</title>
    <style>
      #map{
        width: 600px;
        height: 300px;
        border: 1px solid #000;
      }
      #a, #b, #blocking1, #blocking2{
        position: fixed;
      }
      #a{
        width: 1px;
        height: 1px;
        top: 50px;  
        left: 100px;
        background-color: #F00;
      }
      #b{
        width: 1px;
        height: 1px;
        top: 200px;
        left: 400px;
        background-color: #F00;
      }
      #blocking1{
        width: 100px;
        height: 100px;
        top: 150px;
        left: 250px;
        background-color: #000;
        color: #fff;
      }
      #blocking2{
        width: 50px;
        height: 50px;
        top: 50px;
        left: 275px;
        background-color: #000;
        color: #fff;
      }
    </style>
  </head>
  <body>
    <div id="map">
      <div id="a">A</div>
      <div id="b">B</div>
      <div id="blocking1">Blocking1</div>
      <div id="blocking2">Blocking2</div>
    </div>
  </body>
</html>


1
https://en.wikipedia.org/wiki/Shortest_path_problem#Single-source_shortest_paths - Nikos M.
1个回答

5
有适用于网格和图形的最短路径查找方法(见https://en.wikipedia.org/wiki/Shortest_path_problem#Single-source_shortest_pathshttps://en.wikipedia.org/wiki/Euclidean_shortest_path)。为了回答你的问题,你需要将空间离散化为一个网格,并考虑障碍物的位置/形状和尺寸以及物体的形状/尺寸作为约束条件。然后你就有了一个图形,可以使用任何最短路径图形算法。
另一种方法(特别是对于连续空间最短路径路线)是使用物理学来解决计算问题(例如见Physical systems for the solution of hard computational problemsExamples of using physical intuition to solve math problems)。
在这种方法中,人们假定对象和障碍物被磁化(或具有某种“势能”相互作用),即目标点吸引对象而障碍物排斥对象。然后,静态平衡解提供了对象行进的最佳路径(在这种情况下也是最短路径)。
例如,如果没有障碍物,对象将沿直线朝目标移动(吸引它)。有了障碍物,就会将对象从那条直线转移到一个优化路径上,以到达目标并避开障碍物(像排斥目标一样)。
(这种方法往往会产生更平滑(即解析)的路线,不一定符合所提出的例子,尽管这并非必要,人们确实可以模拟更不连续的路线。)
参考文献:
  1. 单源最短路径图算法
  2. 欧几里得最短路径
  3. 平面上欧几里得最短路径的最优算法
  4. 多边形对象之间欧几里得最短路径的高效算法
  5. 在连续空间中衍生出避障最短路径
  6. 视觉引导转向、避障和路径选择的动态模型
  7. 地形导航问题的算法方法
  8. 在多面体障碍物中规划无碰撞路径的算法
  9. 解决最短路径问题:Dijkstra算法
  10. 最短路径:不同方法和实现方式在车辆自动路线规划中的比较

到目前为止非常简洁,还有很多参考资料,非常感谢你的帮助。 - Kyle
欢迎,希望它有用,你可以在参考文献中找到算法。 - Nikos M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接