Пересечение многоугольников (PSLG overlaying)
Постановка задачи
Определим пересечение двух ППЛГ и как ППЛГ , такой, что в нем существует грань тогда и только тогда, когда существуют грани в и в такие, что является наибольшим связным подмножеством . Иначе говоря, пересечение двух ППЛГ — это разбиение плоскости с помощью ребер из и . Необходимо построить РСДС для , имея РСДС для и . Кроме того, для каждой грани из будем хранить ссылки на грани из и , содержащие ее.
<картинка>
Алгоритм
Для начала, скопируем ППЛГ
и в новый РСДС. Далее необходимо преобразовать полученный РСДС, чтобы он соответствовал . Отдельно рассмотрим преобразования вершин, полуребер и граней.Вершины и полуребра
Алгоритм базируется на заметающей прямой, определяющей пересечения отрезков. Запускаем алгоритм на множестве отрезков, представляющих собой ребра из и . Напомним, что алгоритм поддерживает очередь событий и текущий статус заметающей прямой. Также будем поддерживать ссылки между ребрами статуса и соответствующими полуребрами из РСДС. Поддерживаемый инвариант: над заметающей прямой корректный РСДС.
<картинка>
Обработка точки события происходит следующим образом: сначала обновляем
и (как в алгоритме пересечения отрезков). Если оба ребра события принадлежат одному ППЛГ, переходим к следующему событию. В противном случае, необходимо модифицировать РСДС. Возможны следующие варианты событий (см. рисунок ниже):<картинка>
Рассмотрим один из случаев, остальные обрабатываются аналогично. Пусть ребро
из пересекает вершину из . Ребро заменяем двумя ребрами и . Два полуребра, соответствующих , заменяются четырьмя полуребрами: два существующих полуребра будут исходить из концов , а два новых полуребра — из (см. рисунок). Устанавливаем ссылки на близнецов для ребер и . Обновим ссылки на следующие полуребра для и , пусть это будут и , соответственно. Не забудем установить полуребра и в качестве предыдущих полуребер у и . Теперь обновим ссылки на полуребра, инцидентные вершине . Для этого сначала при помощи порядка обхода определим, между какими полуребрами находится . Рассмотрим полуребро : свяжем его с первым полуребром, видимым из при обходе по часовой стрелке и исходящем из . Полуребро должно быть связано с первым полуребром, идущим в , при обходе против часовой стрелки. Аналогично обработаем .