如何比较两个不同路径(点数组)的点

时间:2016-08-09 14:14:17

标签: javascript arrays

我必须比较两个不同路径的点,看它们是否相似。

我的问题是,两条路径都有不同的起点。这些路径也不是简单的矩形,所以我不认为我可以根据最小的x和y值重新排序数组。

我试过这个:

function orderPoints(points) {
  var smallestX;
  var smallestY;
  var smallestIndex;

  for (var i = 0; i < points.length; i++) { 
    if (!smallestX) { 
      smallestX = points[i].x;
      smallestIndex = i;
      smallestY = points[i].y;
    } else {
      if (points[i].x < smallestX && points[i].y < smallestY) { 
        smallestX = points[i].x;
        smallestY = points[i].y;
        smallestIndex = i;
      }
    }
  }

  //reorder array
  var newArray = [];
  for (var i = smallestIndex; i < points.length; i++) {
    newArray.push(points[i])
  }

  for (var i = 0; i < smallestIndex; i++) {
    newArray.push(points[i])
  }
  //console.log(newArray)   
  return newArray;
}

这似乎不起作用。我知道这两条路径非常相似,最终应该只有很小的差异。但我得到的差异看起来不正确,所以我认为起点&#39;两个点数组都是错误的。有什么想法吗?

这是一个带有我当前代码的JSFiddle:https://jsfiddle.net/thatOneGuy/5b3646zj/

2 个答案:

答案 0 :(得分:2)

只是一个例子,说明如何比较具有不同起点的相同路径。

var path1 = [
        {'x' : 5, 'y' : 10},
        {'x' : 3, 'y' : 8},
        {'x' : 9, 'y' : 14},
        {'x' : 7, 'y' : 25}
    ],
    path2 = [
        {'x' : 11, 'y' : 16},
        {'x' : 9, 'y' : 14},
        {'x' : 15, 'y' : 20},
        {'x' : 13, 'y' : 31}        
    ],
    normalize = function normalize( path ) {
        var centerX = path[0].x,
            centerY = path[0].y;
        return path.map(function( point ) {
            point.x -= centerX;
            point.y -= centerY;
            return point;
        });
    },
    normalizedPath1 = normalize(path1), // [{"x":0,"y":0},{"x":-2,"y":-2},{"x":4,"y":4},{"x":2,"y":15}]
    normalizedPath2 = normalize(path2); // [{"x":0,"y":0},{"x":-2,"y":-2},{"x":4,"y":4},{"x":2,"y":15}]
console.log(JSON.stringify(normalizedPath1) === JSON.stringify(normalizedPath2)); // true

答案 1 :(得分:2)

考虑到您的最新评论,我认为这就是您所需要的:

var path1 = [
  { "x": 1.0265, "y": 2.4715 }, { "x": 5.4865, "y": 2.4715 },
  { "x": 5.5615, "y": 2.3965 }, { "x": 5.5615, "y": 0.2965 },
  { "x": 5.4865, "y": 0.2215 }, { "x": 1.0265, "y": 0.2215 },
  { "x": 0.9515, "y": 0.2965 }, { "x": 0.9515, "y": 2.3965 }
];
var path2 = [
  { "x": 5.5615, "y": 0.2965 }, { "x": 5.5615, "y": 2.3965 },
  { "x": 5.4865, "y": 2.4715 }, { "x": 1.0265, "y": 2.4715 },
  { "x": 0.9515, "y": 2.3965 }, { "x": 0.9515, "y": 0.2965 },
  { "x": 1.0265, "y": 0.2215 }, { "x": 5.4865, "y": 0.2215 }
];

function pathDifference(p1, p2) {
  // abort early if the paths have different lengths
  if(p1.length != p2.length) {
    return false;
  }

  // sort points in each path
  [ p1, p2 ].forEach(function(p) {
    p.sort(function(a, b) {
      return a.x < b.x || (a.x == b.x && a.y < b.y) ? -1 : 1;
    });
  });

  // build array of {dx, dy} differences between the 2 paths
  return p1.map(function(p, i) {
    return { dx: p2[i].x - p.x, dy: p2[i].y - p.y };
  });
}

console.log(pathDifference(path1, path2));

有关排序的说明

您无法通过仅比较X(或仅Y)来对点进行排序。让我们考虑以下示例:

P0 = (7, 9), P1 = (12, 3), P2 = (7, 5)

通过比较X坐标,您可以清楚地看出P1在P0和P2之后。但是当两个X坐标相同时,您需要第二个确定性排序规则,以便您可以决定P2是在P0之前还是之后。

例如:

if X0 < X1 then P0 is before P1
if X0 > X1 then P0 is after P1
if X0 == X1 AND Y0 < Y1 then P0 is before P1
if X0 == X1 AND Y0 > Y1 then P0 is after P1

如果没有第二个标准,.sort()方法会随机排序所有具有相同X坐标的点。

(首先比较X和Y秒只是一个惯例。只要你对两个路径使用相同的方法,反过来也可以这样做。)