Пересечение многоугольников (PSLG overlaying) — различия между версиями
Tiss93 (обсуждение | вклад) |
Tiss93 (обсуждение | вклад) |
||
Строка 24: | Строка 24: | ||
В другом случае, мы поддерживаем то, что в любое время в течение развертки, часть выше линии развертки наложения будет считаться правильной. Теперь что мы должны делать, когда мы достигнем точки событий. Прежде всего, мы обновляем <tex>T</tex> и <tex>Q</tex>, как и в алгоритме заметающей прямой. Если событие включает в себя только ребра из одного из двух подграфов, это все, точка событие является вершиной, которые могут быть использованы повторно. Если событие включает края с двух подграфов, мы должны сделать локальные изменения в <tex>D</tex> -- связать doubly connected edge list двух оригинальных подграфов в точке пересечения. | В другом случае, мы поддерживаем то, что в любое время в течение развертки, часть выше линии развертки наложения будет считаться правильной. Теперь что мы должны делать, когда мы достигнем точки событий. Прежде всего, мы обновляем <tex>T</tex> и <tex>Q</tex>, как и в алгоритме заметающей прямой. Если событие включает в себя только ребра из одного из двух подграфов, это все, точка событие является вершиной, которые могут быть использованы повторно. Если событие включает края с двух подграфов, мы должны сделать локальные изменения в <tex>D</tex> -- связать doubly connected edge list двух оригинальных подграфов в точке пересечения. | ||
− | Рассмотри один из 2 возможных случаев, а именно, когда edge <tex> | + | Рассмотри один из 2 возможных случаев, а именно, когда edge <tex>e</tex> из <tex>S1</tex> проходит через вершину <tex>V</tex> <tex>S2</tex>, (см. Рисунок) edge e должно быть заменено двумя edges обозначим <tex>e'</tex> и <tex>e''</tex>. В <tex>DCEL</tex>, два <tex>half-edge</tex> для е должны превратиться в четыре. Мы создаем два новых <tex>half-edge</tex>, с <tex>V</tex> в нуле. Два существующих <tex>half-edge</tex> для е содержат конечные точки <tex>e</tex>, как их происхождения. Тогда мы объединяем попарно существующие <tex>half-edges</tex> с новыми <tex>half-edges</tex>, устанавливая их указатели twin'ов. Так <tex>e'</tex> представлен одним новым и одним существующим частично edge, и то же самое для <tex>e''</tex>. Теперь мы должны установить ряд <tex>Prev</tex> и <tex>Next</tex>. <tex>Next</tex> двух новых <tex>half-edges</tex> являются копией <tex>Next</tex> старого <tex>half-edge</tex>, не имеющего пары. В <tex>half-edges</tex>, в которые эти указатели точки должны обновлять свои <tex>Prev</tex> и установливать его на новых <tex>half-edges</tex>. Далее мы должны установить <tex>Next</tex> и <tex>Prev</tex> четырех <tex>half-edges</tex> представляющих <tex>e'</tex> и <tex>e''</tex>, и из четырех <tex>half-edges</tex> инциденого <tex>S2</tex> <tex>v</tex>. Мы размещаем эти четыре <tex>half-edges</tex> от <tex>S2</tex>, проверяя, где <tex>e'</tex> и <tex>e''</tex> должны быть в циклическом порядке вершин вокруг вершины <tex>v</tex>. Есть четыре пары <tex>half-edges</tex>, которые связанны между собой <tex>Next</tex> с одним и <tex>Prev</tex> с другим. <tex>e'</tex> должен быть привязан к первому <tex>half-edge</tex> по часовой стрелке с началом в <tex>v.</tex> <tex>half-edge</tex> для <tex>e'</tex> с началом в <tex>v</tex> должен быть связан с первым против часовой стрелки <tex>half-edge</tex> с окончанием в <tex>v</tex>. Точно также и для <tex>e''</tex>. |
====Время работы объединения==== | ====Время работы объединения==== |
Версия 22:29, 28 марта 2014
Содержание
Постановка задачи
Даны два ППЛГ, требуется построить их объединение в виде РСДС. При этом создав новые и обновив старые.
Формально
Определим объединение двух pslg
и , чтобы получился граф , такой, что существует f в , тогда и только тогда есть f1 и f2 в и соответственно, что является максимально связанным подмножеством . Требуется чтобы каждый в был отмечен с помощью label of the в и , который содержит их. Таким образом мы получаем доступ к информации хранящейся на этих .Алгоритм
Первоначальное слияние
Для начала посмотрим, как можно больше информации от doubly connected edge lists для
и мы можем повторно использовать в doubly connected edge lists для . Рассмотрим сеть ребер и вершин S1. Эта сеть разделена на кусочки краями . Эти кусочки в большинстве своем могут использоваться повторно, все, за исключением тех, которые отделены краями . Такие нужно обновлять. Если ориентация изменится, нам придется менять информацию в этих записях. Половинки ребра ориентированы таким образом, что , которым они связаны лежит слева; форма может изменяться в наложении, но он будет оставаться в той же стороне . Следовательно, мы можем повторно использовать records, соответствующие краям, которые не пересекаются ребра из другой карты. Иными словами, есть только records в для , которые мы не можем заимствовать из или , ими являются те, которые попадают на пересечение между краями из разных карт. Это предлагает следующие подходы. Во-первых, скопировать doublyconnected edge lists и в один новый . Новый не является допустимым , т.к. он еще не представляет собой плоский подграф.Объединения графов
Это задача алгоритма заметающей прямой: он должен трансформировать
в допустимый для путем вычисления пересечения между двумя сетями ребер, и связывая воедино соответствующие части из двух . Мы применяем этот алгоритм на множестве сегментов, что является объединением множеств ребер двух подграфов и . Напомним, что алгоритм поддерживается двумя структурами данных: очереди событий , в котором хранятся точки событий, и структура состояния , которой является бинарное дерево храненящее сегменты, пересекающие линии развертки, расположенные слева направо. Мы теперь также должны поддерживать . Первоначально содержит копию для и для . В плоскости развертки преобразуем к правильному для . Мы держим перекрестные указатели между ребер в структуре состояния и половина текущих записей в , которые соответствуют им. Таким образом мы можем получить доступ к части , которая должна быть изменена, когда мы сталкиваемся с точкой пересечения.В другом случае, мы поддерживаем то, что в любое время в течение развертки, часть выше линии развертки наложения будет считаться правильной. Теперь что мы должны делать, когда мы достигнем точки событий. Прежде всего, мы обновляем
и , как и в алгоритме заметающей прямой. Если событие включает в себя только ребра из одного из двух подграфов, это все, точка событие является вершиной, которые могут быть использованы повторно. Если событие включает края с двух подграфов, мы должны сделать локальные изменения в -- связать doubly connected edge list двух оригинальных подграфов в точке пересечения.Рассмотри один из 2 возможных случаев, а именно, когда edge
из проходит через вершину , (см. Рисунок) edge e должно быть заменено двумя edges обозначим и . В , два для е должны превратиться в четыре. Мы создаем два новых , с в нуле. Два существующих для е содержат конечные точки , как их происхождения. Тогда мы объединяем попарно существующие с новыми , устанавливая их указатели twin'ов. Так представлен одним новым и одним существующим частично edge, и то же самое для . Теперь мы должны установить ряд и . двух новых являются копией старого , не имеющего пары. В , в которые эти указатели точки должны обновлять свои и установливать его на новых . Далее мы должны установить и четырех представляющих и , и из четырех инциденого . Мы размещаем эти четыре от , проверяя, где и должны быть в циклическом порядке вершин вокруг вершины . Есть четыре пары , которые связанны между собой с одним и с другим. должен быть привязан к первому по часовой стрелке с началом в для с началом в должен быть связан с первым против часовой стрелки с окончанием в . Точно также и для .Время работы объединения
Большинство из шагов в приведенном выше описании принимать только константное время. Есть случаи на которые потребуется дополнительное время, О(M), где Mчисло ребер, точки событий. Это означает, что обновление
не увеличивает время работы алгоритма заметащей прямой асимптотически. Любое пересечение, которое мы находим является вершиной наложения. Из этого следует, что вершина record и record doubly connected edge list для можно вычислить в время, где обозначает сумму сложностей и , а k является сложностью наложения.Воссоздание
После того, как все сделано, осталось вычислить информацию о
в . Точнее, мы должны создать record для каждого е в , мы должны сделать ( ) указывают на на внешней границе , и мы должны сделать список ( ) из указателей на на связанных областях пробелов внутри . Кроме того, мы должны установить () поля времени на границе так, что они указывают на лицевые записи . Наконец, каждый из новых должны быть помечены именами в старых подграфах, которые содержат его. Рассмотрим два цикла, свойственных . Т.к. мы знаем, что incident лежит слева, мы можем вычислить угол который эти два образуют внутри . Если этот угол f меньше, чем 180◦ то циклом является внешняя граница, и в противном случае это граница дыры. Это свойство имеет место для левой вершины цикла, но не обязательно для других вершин этого цикла.Лемма (К предыдущему вопросу): |
Каждая компонента графа отвечает за множество циклов инцидентных одному . |
Доказательство: |
Рассмотрим цикл | , который ограничивает дыру в . Поскольку локально лежит левее самой левой вершины из , то должен быть соединен с другим циклом, который тоже ограничивает . отсюда следует, что циклы есть компонента связности в графе, описывающая один и тот-же . Для того, что бы закончить доказательство, покажем, что каждый цикл ограничивающий дыру в есть в той же компоненте связности, что и внешняя граница . Предположим, что есть цикл, для которого это не так. Пусть — самый левый такой цикл, то есть тот, чья самая левая вершина самая левая (шляпа). По определению есть ребро между и неким , который лежит слева от самой левой вершины . Следовательно в той же компоненте связности, что и , который не в той же компоненте, что внешняя граница . Противоречие.
Напомним, что в алгоритме развертки плоскости для отрезка пересечения мы всегда искали сегменты сразу слева от точки событий. (Они должны были быть проверены на пересечении с крайнего левого края через точку событий.) Таким образом, информация, при помощи которой мы должны построить
определяется в плоскости развертки. Таким образом, чтобы построить , мы сначала делаем узел для каждого цикла. Чтобы найти дуги , рассмотрим левую вершину для каждого цикла, ограничивающую отверстие. Если сразу же выходит из , то мы добавляем дугу между двумя узлами в , представляющих цикл, содержащий е и цикл у которого является самой левой вершиной. Чтобы найти эти узлы в мы должны указатели от каждого записать в узел , представляющего цикл этот. Так информация o в doublyconnected edge list может быть установлена в времени, после плоскости развертки. Каждая грань в наложении должна быть помечена с именами в старых графах, которые содержали его. Чтобы найти эти , надо рассмотреть произвольную вершину в . Если является пересечением от и от , то мы можем решить, какие из и содержат , глядя на указатель соответствующих соответствующих и . Если не пересечение, но вершина, скажем, S1, то мы знаем только S1, содержащей . Чтобы найти , содержащий , мы должны определить , которое содержит . Другими словами, если бы мы знали для каждой вершины , в котором находился, и наоборот, то мы могли бы обозначить правильно.Итог
MapOverlay (
, )1. Копируем
и в граф .2. Находим все пересечения ребер из
с ребрами из с помощью заметающей прямой.2.1 Когда находим точки пересечения, то обновляем РСДС.
, то есть строим из него3. Теперь РСДС, но без информации о 'ах.
это нормальный4. Находим boundary cycles в
. То есть обновляем этот граф. Пока только добавляя в него ребра ( 'ы соответственно).5. Создаем граф
(о нем ниже), в котором узлы будут отвечать за boundary cycles и в котором ребра будут соединять только те узлы, один из которых будет являться границей дыры ( , это внутренний цикл 'a), а другой будет находиться слева от самой левой точки первого. (В случае, если это самая внешняя граница, то для нее пусть будет мнимая гигантская граница, с которой мы ее и соединим).5.1. Для каждой компоненты графа:
Пусть
будет уникальная наружная граница цикла в компоненте, а будет означать face ограниченный этим циклом. Создадим face для . Запишем в какой-нибудь из . И создадим список , состоящий из указателей на какой-нибудь из каждого цикла. А так же пусть в каждом будут обновлены на .
Литература и источники
- Вычислительная геометрия. Алгоритмы и приложения, де Берг Марк и другие. Глава 2.3