2013-09-27 3 views
9

Как подключить точки из двух наборов координат с линиями, не пересекая ни одну из пересекающихся линий?Как подключить точки двух типов с линиями без пересечения?

У меня есть два типа точек (a1, a2, ..., an, b1, b2, ..., bn) и их координаты (x,y).

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

Как это можно сделать?

вход (тип, х, у):

a x y b x y a x y b x y 

выход (Ax, Ay, Bx, By):

ax ay bx by ax ay bx, by 

enter image description here

ответ

1

Я не уверен, как это доказать, но он считает правильным, что всегда должна существовать хотя бы одна пара точек (ax1, ay1) -> (bx1, by1), которые определяют линию, которая подразделяет пространство на две отдельные половины. Каждая половина имеет одинаковое количество непарных а и b точек. Я не могу придумать схему точек, для которых это не так.

После того, как это подразделение найдено, две точки отмечены как подключенные, а два полупространства с каждой стороны обрабатываются снова. Это повторяется до тех пор, пока оба полупространства не будут содержать нулевые точки.

Поиск пары разделов не является тривиальным, но это может быть сделано путем исчерпывающего поиска. Надеюсь, кто-то придумает менее интенсивный вычислительный метод, но это должно сработать.

+0

Я согласен с вашей идеей. Моя первая мысль заключалась в том, чтобы удалить линию (по внешней линии) один за другим с помощью выпуклого корпуса. , но если выпуклый корпус имеет тот же тип внешних точек, он потерпит неудачу. посмотрите на этот рисунок «http://s22.postimg.org/ce109t15t/image.png». , а затем, я пробовал, как вы, метод деления и завоевания Однако в результате я не смог найти эффективную точку, которую можно разделить. – user2821655

+0

Нахождение пары разделов может быть выполнено в O (nlogn) на самом деле. – user2782067

4

Проблема евклидова двуполярного соответствия (EBM) в теории графов (Google it) направлена ​​на сопоставление синих и красных точек, чтобы минимизировать сумму всех длин кромок. Его можно решить, используя Hungarian Algorithm. Чтобы увидеть, что это бесплатный график, просто подумайте о своей «плохой» и «хорошей» картине. Сумма длин ребер всегда меньше в «хорошем» изображении. (Здесь a slightly more detailed argument.)

Вот еще SO answer, который дает более подробную информацию.

И вот an interesting article about how EBM is used on Android to track multi-touch.

+0

Это, безусловно, правильный ответ. Лучшая иллюстрация, которую я нашел для того, как/почему она работает, - [здесь] (http://www.youtube.com/watch?v=8gwq40ozFSk). «Основные» элементы в объяснении дают некоторое оправдание изменениям затрат по всему алгоритму. – Speed8ump

+0

@SpeedBump, я не уверен, что это лучший ответ, потому что это «overkill». Я понимаю, что венгерский метод O (n^4) или O (n^3). Мой другой ответ здесь (http://stackoverflow.com/a/19073770/242848) дает то, что, по моему мнению, является более быстрым методом, который дает совпадение, не пытаясь минимизировать общую длину ребра. – brainjam

+0

Все алгоритмы, которые я видел, являются n^3 или хуже, и этот способ имеет оправданную возможность. Мое предложение основывается на постулате о том, что всегда существует множество подразделений, которые могут разделить проблему (что трудно доказать). В вашем другом предложении требуется, чтобы описанный процесс обмена не приводил к циклу повторяющихся свопов (что кажется возможным). Учитывая, что венгерский алгоритм также является O (n^3) и доказуемо правильным, это тот, который я бы взял ... Если бы я не искал, чтобы где-то публиковаться :) – Speed8ump

1

Вот такой подход, который я считаю многообещающим. Создайте сопряжение красных и синих точек (R1, B1), (R2, B2), .. (Rn, Bn). Затем перейдите в список и для каждого (Rj, Bj) проведем прямую Rj - Bj. Если эта линия пересекает любую другую линию Ri-Bi, уже нарисованную, «пересечь» эти строки, заменив их Ri-Bj и Rj-Bi (фактически изменив вашу «плохую» картину на вашу «хорошую» картинку).

Вы должны проверить, пересекаются ли эти новые линии с любыми другими существующими линиями, и в этом случае вы неоднократно выполняете те же «свопы» и «проверку пересечения», пока не будет больше пересекающихся линий. Затем вы затем присоединяетесь к паре после (Rj, Bj) и так далее, пока не закончите.

Как отмечено в my other answer, сопряжение красных и синих точек, которое сводит к минимуму общую длину края, также будет без перекрестков. В подходе, указанном в этом ответе, обратите внимание, что каждый раз, когда вы «пересекаете» края, вы уменьшаете общее количество всех длин кромок. Алгоритм, скорее всего, не достигнет конфигурации сопряжения с минимальной суммой длин ребер. Однако тот факт, что общая длина ребер уменьшается при каждом подкачке, означает, что алгоритм всегда будет заканчиваться (т. Е. Вы не попадете в повторяющуюся последовательность реберных свопов).

+0

Существует потенциальная проблема с этим методом, так как обмен двумя парами точек может создавать больше пересекающихся сегментов – NightRa

+0

@NightRa, алгоритм учитывает это. См. Второй абзац. – brainjam

+0

Справа. Условие завершения не имеет ничего общего с количеством пересечений, но только на расстояниях от ponints в паре, а так как общее расстояние не может идти ниже минимума, оно заканчивается. – NightRa

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