0

我不仅试图找到最近的点,还试图在 5 个对象点的数组中找到 3 个最近的点。我已经尝试了几个实验,每个点只使用一个距离(d)变量。但我不知道如何遍历每个点,使用勾股定理/距离公式将其与其他点进行比较,然后找到最接近的 3。如果数组有 5 个点,我猜我需要存储结果数组中的每次迭代都有一个距离 ( d) 值,按距离值排序,然后删除新数组中的最后一项。这是数组:

 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 },
 ]; 

我有一个函数可以根据d距离的键值找到最近的 3 个点:

 function closest(n, { id, d }) {
    return points
      .filter(o => o.id !== id)
      .sort((a, b) => Math.abs(a.d - d) - Math.abs(b.d - d))
      .slice(0, n);
 };

而且我有一种方法可以应用此功能并控制台记录结果,以便打印“ID:1stClosest,2ndClosest,3rdClosest”:

 result = points.map(o => 
   Object.assign({}, o, { closest: closest(3, o) }));

 result.forEach((item) => {
   console.log(item.id + ': ' + item.closest[0].id + ', ' + item.closest[1].id + ', ' + item.closest[2].id);}); 

现在,我只是试图遍历每个点,应用距离公式来获取每个点比较的 d: 值,将其推送到一个新数组,我假设然后应用上述部分(resultclosest函数)。我怎样才能做到这一点?这是我到目前为止所拥有的:

 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);
});
4

1 回答 1

1

如果我理解正确,这类似于最近的一对点问题。一种(直观,但可能效率低下)的方法是简单地暴力破解集合中的项目。也就是说,对于两个点,您使用两个 for 循环。那么,对于三点,您可以使用三个嵌套循环。然后,您会找到最大的“亲密度”。我不确定你想如何定义接近度,但我认为从 A 到 B、B 到 C 和 C 到 A 的距离之和会很好。测试每个点分组的最小“距离”枚举将导致最接近的配对。

所以,我不确定你的其他功能会在哪里发挥作用。更大的问题是找到如何确定“最接近”的方法,因此调用函数来解决更大问题的子问题不会被检查出来。

如果您以某种方式想要最接近的三点,那么您需要跟踪每个配对的距离并确定您希望如何使它们彼此区分开来。即,您是否要允许同一点在另一组点中?

于 2018-06-16T02:16:55.367 回答