比较多个点之间的距离

时间:2018-06-15 20:43:23

标签: javascript arrays iterator pythagorean

我正在尝试应用毕达哥拉斯定理来找到一个点阵列之间的距离,因为我遍历数组然后吐出n个最近点。我很困惑如何得到d:迭代点和下一个点之间的距离,以与迭代点的距离和之后的下一个+1点进行比较,依此类推。我从我的一系列观点开始:

 var points = [
   { id: 1, x: 0.0, y: 0.0 },
   { id: 2, x: 10.1, y: -10.1 },
   { id: 3, x: -12.2, y: 12.2 },
   { id: 4, x: 38.3, y: 38.3 },
   { id: 5, x: 79.0, y: 179.0 },
 ];

然后我想迭代它们并使用毕达哥拉斯定理为它与其他点之间的距离的每个点创建一个新数组:

points.forEach((item) => {
  var newArray = [item];
  var pt = null;
  var d = null;
  for (var i = 0; i < points.length; i = i + 1) {
      //compare this point with all of the other points 
      for (var j = i + 1; j < points.length; j = j + 1) {
          //compute distance 
          var curr = Math.sqrt(Math.pow(points[i][0] - points[j][0], 2) + Math.pow(points[i][1] - points[j][1], 2));
      //get the distance between each point and push to a new array  
          if (d === null || curr < d) {                 
            o = points.id[i];     
            pt = points.id[j];
            d = curr; 
          }
       }
     }    
  newArray.push = {
   "id": o,
   "pt": pt,
   "d": d
  };
  console.log(newArray);
});

似乎我在这里有一些逻辑区域不正确,每当我尝试变异时,我会不断出现Cannot read property '0' of undefined个错误。关于我做错的任何建议?

1 个答案:

答案 0 :(得分:2)

您目前正在迭代每个项三次次:您有一个forEach嵌套for和另一个嵌套for。您还尝试在points[i][0]points[j][0]等上进行数学运算,但那些不存在 - 例如points[j]x和{y的对象{1}}属性,而不是带有数字标记的数组。

如果给每个单独的点一个变量,并且使用指数运算符,它会更加清晰:

&#13;
&#13;
var points = [
  { id: 1, x: 0.0, y: 0.0 },
  { id: 2, x: 10.1, y: -10.1 },
  { id: 3, x: -12.2, y: 12.2 },
  { id: 4, x: 38.3, y: 38.3 },
  { id: 5, x: 79.0, y: 179.0 },
];

const pointPairs = [];
for (let i = 0; i < points.length; i = i + 1) {
  const p1 = points[i];
  for (let j = i + 1; j < points.length; j = j + 1) {
    const p2 = points[j];
    const distance = Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
    pointPairs.push({ p1: p1.id, p2: p2.id, distance });
  }
}
pointPairs.sort((a, b) => a.distance - b.distance);
console.log(pointPairs.slice(0, 5));
&#13;
&#13;
&#13;

或者,如果您使用数组方法,它甚至更清晰:

&#13;
&#13;
var points = [
  { id: 1, x: 0.0, y: 0.0 },
  { id: 2, x: 10.1, y: -10.1 },
  { id: 3, x: -12.2, y: 12.2 },
  { id: 4, x: 38.3, y: 38.3 },
  { id: 5, x: 79.0, y: 179.0 },
];

const pointPairs = [];
points.forEach((p1, i) => {
  points.slice(i + 1).forEach(p2 => {
    const distance = Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
    pointPairs.push({ p1: p1.id, p2: p2.id, distance });
  });
});
pointPairs.sort((a, b) => a.distance - b.distance);
console.log(pointPairs.slice(0, 5));
&#13;
&#13;
&#13;