соединить линию между двумя коробками, избегая прохождения других - PullRequest
2 голосов
/ 04 сентября 2011

У меня есть несколько блоков (x, y, ширина, высота), разбросанных случайным образом, и некоторые из них необходимо связать от точки (x1, y1) в box1 до точки (x2, y2) в box2, нарисовав линию,Я пытаюсь найти способ, как заставить такую ​​линию избегать прохождения через любые другие блоки (кроме box1 и box2), рисуя несколько прямых взаимосвязанных линий, чтобы обойти любой блок на этом пути (если невозможно пройти с одной прямой линией).Проблема в том, что я не знаю алгоритм для такой вещи (не говоря уже о техническом / общем названии для этого).Буду признателен за любую помощь в виде алгоритма или выраженных идей.

Спасибо

Ответы [ 2 ]

1 голос
/ 04 сентября 2011

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

Просто создайте график, содержащий одну вершину для каждой точки (x, y) и для каждой точки ребра:

((x,y),(x+1,y))    ((x,y),(x-1,y))     ((x,y),(x,y+1))     ((x,y),(x,y-1))

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

Теперь просто сделайте простую BFS из точки (x1, y1) в (x2, y2)

Очень просто получить и диагональные линии таким же образом, но вам понадобится 8 ребер для каждой вершины, то есть, в дополнение к предыдущим 4:

((x,y),(x-1,y+1))    ((x,y),(x-1,y-1))     ((x,y),(x+1,y-1))     ((x,y),(x+1,y+1))

Тем не менее, каждое ребро должно присутствовать толькоесли он не перекрывает прямоугольник.

РЕДАКТИРОВАТЬ

Если вы не можете рассмотреть пространство, разделенное на сетку, вот еще одна возможность, но она не даст вам самый короткий путь, хотя.

Создайте граф, в котором каждый прямоугольник является вершиной и имеет ребро для любого другого прямоугольника, в который можно попасть без линии, перекрывающей третий прямоугольник.Теперь найдите кратчайший путь, используя dijkstra между box1 и box2, содержащий две точки.

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

1 голос
/ 04 сентября 2011
  1. Поместите все (x, y) координаты углов коробок в наборе V

  2. Добавьте начальную и конечную координаты к V .

  3. Создайте набор ребер E , соединяющих каждый угол, который не пересекает ни одно из полейсо стороны (кроме диагоналей в клетках).

    Как проверить, пересекает ли линия сторону коробки, можно с помощью этого алгоритма

  4. Теперь используйте алгоритм поиска пути по вашему выбору, чтобы найти путь в графе (V, E) .

    Если вам нужен простой алгоритм, который находит кратчайший путь,просто используйте BFS.

(Это создаст путь, проходящий по сторонам некоторых блоков. Если это нежелательно, на шаге 1 вы могли бы поместить точки на некотором расстоянии дельтаот фактических углов.)


Если края могут быть не диагональными:

  1. Создать большую сетку линий, которая проходит междукоробки.

  2. Отбросьте ребра сетки, пересекающие боксы.

  3. Найдите путь в сетке, используя выбранный вами алгоритм поиска пути.
...