2016-08-09 2 views
0

Мне нужно сравнить точки двух разных путей, чтобы увидеть, похожи ли они.Как сравнить точки двух разных путей (массив точек)

Моя проблема в том, что оба пути имеют разные отправные точки. Эти пути также не являются простыми прямоугольниками, поэтому я не думаю, что могу изменить порядок массива на основе наименьших значений 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; 
} 

Это не похоже на работу. Я знаю, что эти два пути очень похожи и должны только иметь небольшую разницу. Но разница, которую я получаю, выглядит некорректной, поэтому я думаю, что «начальная точка» обоих точечных массивов неверна. Есть идеи ?

Вот JSFiddle с моим текущим кодом: https://jsfiddle.net/thatOneGuy/5b3646zj/

+0

Вы можете попробовать перерасчета оба пути, как если бы они начинались с 0,0 путем вычитания первой точки пути из всех точек пути. Тогда версия JSON.stringify обоих путей должна быть одинаковой, если они имеют ту же самую форму. – Shilly

+0

@Shilly, вы можете представить пример, поскольку я не вижу, как это будет работать, поскольку оба пути имеют разные стартовые точки. – thatOneGuy

+1

Пожалуйста, более точно определите «похожие пути». Вы хотите проверить, является ли путь # 2 точным переводом пути №1? Или вы хотите вычислить какой-то счет сходства? – Arnauld

ответ

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, вы можете четко сказать, что Р1 «после» 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 

Без 2-го критерия, метод .sort() будет случайным образом упорядочить все точки, которые имеют тот же X координат.

(Сравнение X первого и второго Y это просто условность. Делая это наоборот будет работать так же хорошо, до тех пор, как вы используете один и тот же метод для обоих путей.)

+0

Это выглядит великолепно, но я думаю, что в этом есть небольшая проблема. Если вы посмотрите на мою скрипку и на функцию orderPoints. Я получаю индекс наименьшего значения X и использую его для «перестроения» массива путей. Надеюсь, я объясню это хорошо, скажем, что у меня есть массив 1,2,3,4,5, а индекс 3 - это то, на что я хочу начать, я меняю порядок на массив так, чтобы это было так 3,4,5,1,2 как Мне нужно сохранить тот же порядок, чтобы он правильно рисовал путь. Имеет ли это смысл ? Если вы посмотрите на консольные журналы здесь: https://jsfiddle.net/thatOneGuy/b97tvxc1/, последние два пункта нужно поменять местами (я думаю) – thatOneGuy

+0

@thatOneGuy Я только что добавил заметку о сортировке в своем ответе , Пожалуйста, дайте мне знать, если это имеет смысл. – Arnauld

+0

Я думаю, что имеет смысл. Вы говорите, что заказ одинаковый? (т. е. другая начальная точка, но порядок один и тот же), поскольку я не понимаю, как она сохраняется, если это так. – thatOneGuy

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 
+0

Извинения, я думаю, что я объяснил это неправильно. Я думаю, что ваш код проверяет, имеет ли он свою форму, мне нужно это, чтобы увидеть, находится ли она в том же положении – thatOneGuy

+0

Euh, что вы имеете в виду? Позиция - это место, где оно расположено на сетке xy? Два пути имеют только одно и то же положение, если все их точки одинаковы, и если они имеют одинаковую форму. Это действительно проверяет, имеют ли они ту же форму, независимо от того, где они начинаются, если они находятся в одном и том же квадранте сетки xy. (Он не проверяет зеркальные пути) – Shilly

+0

Да, но данные для вашего кода в порядке, т. Е. Первый элемент в path1 соответствует первому в path2 и так далее. Моя неупорядоченная, и мне нужен способ проверить, какие координаты x и y в пути 1 соответствуют тому, что находится в пути2. Поэтому я могу проверить разные значения в точках – thatOneGuy

Смежные вопросы