|
|
Строка 67: |
Строка 67: |
| === Наивный алгоритм === | | === Наивный алгоритм === |
| Будем пересекать полуплоскости по по [[#intersect|свойству ячейки диаграммы]]. Необходимо <tex>n</tex> раз пересечь <tex>n - 1</tex> плоскость, что суммарно делается за <tex>O(n^2 \log n)</tex>. | | Будем пересекать полуплоскости по по [[#intersect|свойству ячейки диаграммы]]. Необходимо <tex>n</tex> раз пересечь <tex>n - 1</tex> плоскость, что суммарно делается за <tex>O(n^2 \log n)</tex>. |
− |
| |
− | ==Обозначения и определения==
| |
− | '''Сайт''' (''site'') {{---}} общее название для точки <tex>p</tex> или замкнутого отрезка <tex>t</tex>.
| |
− |
| |
− | <tex>t^\circ</tex> {{---}} внутренняя часть отрезка. Внутренность точки {{---}} пустое множество.
| |
− |
| |
− | Два замкнутых пересекающихся сайта '''слабо пересекаются''' (''weakly intersect''), если точка их пересечения не принадлежит их внутренностям, то есть они касаются концами.
| |
− |
| |
− | Два сайта '''сильно пересекаются''' (''strongly intersect''), если точка их пересечения принадлежит внутренности хотя бы одного из данных сайтов.
| |
− |
| |
− | Расстояние от точки <tex>x \in \mathbb{E}^2</tex> до замкнутого сайта <tex>S_i</tex>: <tex>\delta(x, S_i) = \min{\{||x - y|| : y \in S_i\}}</tex>.
| |
− |
| |
− | Пусть <tex>H_{ij} = \{x \in \mathbb{E}^2 : \delta(x, S_i) \le \delta(x, S_j)\}</tex>. '''Ячейка Вороного''' (''Voronoi cell'') <tex>V(S_i, \Sigma)</tex> {{---}} множество точек, которые находятся ближе к <tex>S_i</tex>, чем к любому другому сайту, то есть <tex>V(S_i, \Sigma) = \cap_{i \ne j}H_{ij}</tex>.
| |
− |
| |
− | '''Ребро Вороного''' (''Voronoi edge'') {{---}} связное множество точек, принадлежащих пересечению ровно двух ячеек Вороного.
| |
− |
| |
− | '''Вершина Вороного''' (''Voronoi vertex'') {{---}} точка, которая принадлежит хотя бы трём ячейкам Вороного.
| |
− |
| |
− | '''Диаграмма Вороного''' (''Voronoi diagram'') <tex>V(\Sigma)</tex> множества сайтов <tex>\Sigma</tex> {{---}} разбиение плоскости на вершины, рёбра и ячейки Вороного.
| |
− |
| |
− | '''1-каркас''' (''1-skeleton'') <tex>V_1(\Sigma)</tex> {{---}} набор вершин и рёбер Вороного.
| |
− |
| |
− | В процессе работы алгоритма множество сайтов, которые подаются на вход, может измениться. Чтобы различать начальное и конечное множество сайтов, будем обозначать входное множество через <tex>\Sigma_I</tex>, а множество сайтов, которые присутствуют на результирующей диаграмме Вороного, через <tex>\Sigma</tex>. <tex>\Sigma_I</tex> всегда состоит из замкнутых сайтов, а <tex>\Sigma</tex> {{---}} из точек и открытых отрезков.
| |
− |
| |
− | Пусть сайты <tex>S_i</tex> и <tex>S_j</tex> слабо пересекаются. Тогда '''битангентная окружность Вороного''' (''bitangent Voronoi circle'') <tex>C_{ij}</tex> {{---}} окружность, касающаяся одновременно <tex>S_i</tex> и <tex>S_j</tex>. При рассмотрении трёх сайтов <tex>S_i</tex>, <tex>S_j</tex> и <tex>S_k</tex>, окружность, касающаяся всех трёх сайтов, называется '''тритангентной окружностью Вороного''' (''tritangent Voronoi circle''). Точки, принадлежащие рёбрам Вороного, являются центрами битангентных окружностей, а вершины {{---}} тритангентных.
| |
− |
| |
− | Рассмотрим <tex>S \notin \Sigma_I</tex>. Будем говорить, что <tex>S</tex> '''конфликтует''' с окружностью Вороного <tex>C</tex>, если <tex>S</tex> пересекается с кругом, ограниченным <tex>C</tex>. Также <tex>S</tex> конфликтует с ребром <tex>e \in V(S, \Sigma)</tex>, если он пересекается с кругом, ограниченным одной из окружностей Вороного с центром в точке, принадлежащей <tex>e</tex>. '''Область конфликтов''' (''conflict region'') <tex>R_\Sigma(S)</tex> {{---}} множество точек 1-каркаса <tex>V_1(\Sigma)</tex>, соответствующих окружностям Вороного, которые конфликтуют с <tex>S</tex>.
| |
− |
| |
− | ==Алгоритм==
| |
− | Рассмотрим сначала алгоритм для слабо пересекающихся сайтов, а потом обобщим его для случая сильно пересекающихся сайтов.
| |
− |
| |
− | ===Случай слабо пересекающихся сайтов===
| |
− | Пусть мы уже построили диаграмму Вороного для некоторого множества <tex>\Sigma</tex>. Рассмотрим процедуру вставки нового сайта <tex>S</tex>.
| |
− |
| |
− | Алгоритм состоит из четырёх шагов:
| |
− |
| |
− | '''1'''. Найти первый конфликт сайта <tex>S</tex> с каркасом <tex>V_1(\Sigma)</tex>.
| |
− |
| |
− | '''2'''. Найти всю область конфликтов сайта <tex>S</tex> c каркасом <tex>V_1(\Sigma)</tex>.
| |
− |
| |
− | '''3'''. Построить диаграмму Вороного для <tex>\Sigma \cup \{S\} </tex>.
| |
− |
| |
− | '''4'''. Обновить локализационную структуру.
| |
− |
| |
− | {{Лемма
| |
− | |statement=
| |
− | <tex>\Sigma</tex> {{---}} слабо пересекающееся между собой множество сайтов. Тогда <tex>\forall s \in \Sigma</tex> ячейки Вороного <tex>V(s, \Sigma)</tex> {{---}} односвязные множества.
| |
− | |proof=
| |
− | Для начала докажем, что ячейки связны. Пусть это не так и у ячейки <tex>V(s, \Sigma)</tex> несколько компонент связности. Рассмотрим <tex>\varepsilon</tex> {{---}} одну из тех, которая не содержит в себе <tex>s</tex>. Начнём идти по кратчайшему пути <tex>P</tex> от любой точки <tex>p \in \varepsilon</tex> до <tex>s</tex>. Так как <tex>p</tex> и <tex>s</tex> лежат в разных компонентах связности, найдётся <tex>s' \in \Sigma</tex>, такой что путь <tex>P</tex> проходит через <tex>V(s', \Sigma)</tex>. Значит существует путь от <tex>p</tex> до <tex>s'</tex>, который короче, чем <tex>P</tex>, следовательно и <tex>\delta(p, s') < \delta(p, s) = |P|</tex>. Противоречие.
| |
− |
| |
− | Теперь допустим, что <tex>V(s, \Sigma)</tex> содержит разрыв в виде другой ячейки <tex>V(s', \Sigma)</tex>. Проведём прямую, которая соответствует кратчайшему расстоянию между <tex>s</tex> и <tex>s'</tex> и рассмотрим точку <tex>p</tex>, которая лежит на её продолжении за <tex>s'</tex> и принадлежит <tex>V(s, \Sigma)</tex>. Такая точка будет существовать, т.к. <tex>V(s', \Sigma)</tex> лежит внутри <tex>V(s, \Sigma)</tex>. Получаем, что кратчайший путь от <tex>p</tex> до <tex>s</tex> проходит через <tex>s'</tex>. Опять противоречие.
| |
− | }}
| |
− |
| |
− | {|border="0" width="100%"
| |
− | |{{Теорема
| |
− | |statement=
| |
− | Пусть <tex>\Sigma</tex> {{---}} множество слабо пересекающихся сайтов, <tex>s</tex> {{---}} сайт, <tex>s \notin \Sigma</tex>. Тогда <tex>R_\Sigma(s)</tex> {{---}} связное непустое множество.
| |
− | |proof=
| |
− | Пусть <tex>C = V(s, \Sigma \cup \{s\})</tex>, <tex>R_\Sigma(s) = \varepsilon</tex>.
| |
− |
| |
− | Заметим, что <tex>\varepsilon = V_1(\Sigma) \cap C</tex>. Если бы область конфликтов <tex>\varepsilon</tex> была пустой, то было бы верно <tex>C \subset V(q, \Sigma \cup \{p\})</tex> для некоторого <tex>q \in \Sigma</tex> и <tex>V(q, \Sigma \cup s)</tex> не было бы односвязным.
| |
− |
| |
− | Пусть <tex>\varepsilon_1, \varepsilon_2, ... , \varepsilon_k</tex> {{---}} связные компоненты <tex>\varepsilon</tex> для некоторого <tex>k</tex>.
| |
− |
| |
− | Предположим, что <tex>k \ge 2</tex>. Тогда cуществует путь <tex>P \subseteq C \setminus \varepsilon</tex>, соединяющий две точки <tex>x</tex> и <tex>y</tex> на границе <tex>C</tex> и отделяющий <tex>\varepsilon_1</tex> от <tex>\varepsilon_2</tex>(см. рисунок). <tex>P \cap \varepsilon = \varnothing \Rightarrow P \cap V_1(\Sigma) = \varnothing \Rightarrow P \subseteq intV(q, \Sigma)</tex> для некоторого <tex>q \in \Sigma</tex>. <tex>x, y \in P \Rightarrow</tex> все достаточно малые окрестности <tex>U(x)</tex>, <tex>U(y)</tex> полностью содержатся в <tex>V(q, \Sigma)</tex>. Значит, точки пересечения этих окрестностей с дополнением <tex>C</tex> лежат в <tex>V(q, \Sigma \cup s)</tex> и могут быть соединены путём <tex>L \subseteq V(q, \Sigma \cup \{s\}) \subseteq V(q, \Sigma)</tex>. Следовательно, цикл <tex>P \circ L</tex> полностью содержится в <tex>V(q, \Sigma)</tex> и содержит <tex>\varepsilon_1</tex> или <tex>\varepsilon_2</tex> в своей внутренней части. Это противоречит тому, что <tex>V(q, \Sigma)</tex> {{---}} односвязное множество, следовательно <tex>k = 1</tex>.
| |
− | }}
| |
− | |[[Файл:path.png|250px|thumb|right]]
| |
− | |}
| |
− |
| |
− | Таким образом, для нахождения области конфликтов, можно найти одно конфликтующее ребро, а затем, при помощи DFS, найти все остальные.
| |
− |
| |
− | Пусть сайт <tex>S</tex> {{---}} это точка <tex>p</tex>.
| |
− |
| |
− | Первый шаг алгоритма начинается с поиска ближайшего соседа <tex>N_\Sigma(p)</tex> точки p среди сайтов <tex>\Sigma</tex> (если есть несколько ближайших, то подойдёт любой из них). Будем хранить нашу диаграмму в скип-листе для того, чтобы можно было быстро выполнять эти запросы. Либо <tex>N_\Sigma(p)</tex> и <tex>p</tex> {{---}} это одна и та же точка, и ничего делать не нужно, либо <tex>p</tex> конфликтует хотя бы с одним ребром, принадлежащим границе ячейки <tex>V(N_\Sigma(p))</tex>. Тогда первый шаг завершается рассмотрением границы <tex>V(N_\Sigma(p))</tex> и возвращением одного из рёбер, конфликтующих с <tex>p</tex>. Как было сказано раньше, второй шаг {{---}} DFS по рёбрам <tex>V_1(\Sigma)</tex> с целью найти все рёбра, конфликтующие с точкой <tex>p</tex>. Теперь, зная <tex>R_\Sigma(p)</tex>, можно создать новую ячейку Вороного <tex>V(S, \Sigma \cup \{S\})</tex> (а как это сделать, я не очень понимаю).
| |
− |
| |
− | Если же <tex>S</tex> {{---}} это замкнутый отрезок <tex>t</tex>, то сначала вставляем конечные точки <tex>p'_t</tex> и <tex>p''_t</tex>, используя процедуру, описанную выше. Остаётся вставить открытый отрезок <tex>t^\circ</tex>. Так как <tex>p'_t</tex> и <tex>p''_t</tex> {{---}} соседи <tex>t^\circ</tex> в диаграмме <tex>V(\Sigma \cup \{p'_t, p''_t, t^\circ\})</tex>, <tex>t^\circ</tex> обязан конфликтовать с каким-нибудь ребром ячейки, соответствующей <tex>p'_t</tex> или <tex>p''_t</tex>. Таким образом, первый конфликт <tex>t^\circ</tex> с <tex>V_1(\Sigma \cup \{p'_t, p''_t\})</tex> можно найти, просматривая рёбра ячейки <tex>V(p'_t, \Sigma \cup \{p'_t, p''_t\})</tex> или <tex>V(p''_t, \Sigma \cup \{p'_t, p''_t\})</tex>, то есть, можно опустить шаг поиска ближайшего соседа. Остаётся найти всю область конфликтов, как и в случае с точкой.
| |
− |
| |
− | ===Случай сильно пересекающихся сайтов===
| |
− | {|border="0" width="100%"
| |
− | |Пусть <tex>p</tex> {{---}} точка, которая сильно пересекается с отрезком <tex>t_i</tex>, т.е. <tex>p \in t^\circ</tex>. Понятно, что <tex>t^\circ</tex> будет ближайшим соседом <tex>p</tex> в <tex>\Sigma</tex>. Пусть <tex>e'_i(p)</tex> и <tex>e''_i(p)</tex> {{---}} два ребра <tex>V(t^\circ, \Sigma)</tex>, которые пересекаются с нормалями к <tex>t</tex>, проведёнными из точки <tex>p</tex> (см. рисунок). Пусть <tex>v'_i(p)</tex> и <tex>v''_i(p)</tex> {{---}} точки пересечения нормалей с рёбрами <tex>e'_i(p)</tex> и <tex>e''_i(p)</tex> соответственно. Тогда алгоритм вставки точки <tex>p</tex> в диаграмму <tex>V(\Sigma)</tex> будет выглядеть следующим образом:
| |
− |
| |
− | Начинаем с поиска ближайшего соседа <tex>N_\Sigma(p)</tex>. Если <tex>N_\Sigma(p) = p</tex>, то ничего не делаем. Если <tex>N_\Sigma(p)</tex> {{---}} точка, или отрезок, с которым <tex>p</tex> не пересекается, то запускается процедура вставки, которая была описана выше. Иначе <tex>N_\Sigma(p) = t_i^\circ</tex> {{---}} отрезок, пересекающийся с <tex>p</tex>. Сначала добавляем <tex>p</tex> в <tex>\Sigma</tex> и заменяем <tex>t_i^\circ</tex> двумя отрезками <tex>p'_ip</tex> и <tex>pp''_i</tex>, где <tex>p'_i</tex> и <tex>p''_i</tex> {{---}} конечные точки <tex>t_i</tex>. Затем ищем рёбра <tex>e'_i(p)</tex> и <tex>e''_i(p)</tex>, разбиваем их в точках <tex>v'_i(p)</tex> и <tex>v''_i(p)</tex> и добавляем отрезки <tex>v'_i(p)p</tex> и <tex>v''_i(p)p</tex> в диаграмму.
| |
− | ||[[Файл:strongly_intersect.png|300px|thumb|right]]
| |
− | |}
| |
− |
| |
− | Если же мы хотим вставить в диаграмму отрезок <tex>t</tex>, то вставляем сначала его крайние точки <tex>p'_t</tex> и <tex>p''_t</tex>. Затем, начиная с <tex>p'_t</tex>, ищем первый конфликт <tex>t^\circ</tex> с текущей диаграммой Вороного и ищем всю область конфликтов. Во время этого поиска, прежде чем тестировать ребро Вороного <tex>e</tex> существующей диаграммы на потенциальный конфликт, мы проверяем, не пересекается ли <tex>t^\circ</tex> с одним из сайтов, связанных с <tex>e</tex>. Если такой сайт <tex>S_i</tex> найден, то поиск останавливается. Если <tex>S_i</tex> {{---}} точка, <tex>p_i</tex>, то вставляем отрезки <tex>p'_tp_i</tex> и <tex>p_ip''_t</tex> рекурсивно. Если <tex>S_i</tex> {{---}} отрезок <tex>t^\circ_i</tex>, то сначала проверяем, не принадлежит ли один из <tex>t^\circ</tex>, <tex>t^\circ_i</tex> другому. Если так и есть, то прекращаем работу, иначе вычисляем точку пересечения <tex>p_+</tex> отрезков <tex>t^\circ</tex> и <tex>t^\circ_i</tex>, вставляем её в диаграмму, а затем рекурсивно вставляем отрезки <tex>p'_tp_+</tex> и <tex>p_+p''_t</tex>.
| |
− |
| |
− | Время работы данного алгоритма составляет <tex>O((n + m)\log^2m)</tex>, где <tex>n</tex> {{---}} количество элементов во входном множестве <tex>\Sigma_I</tex>, а <tex>m</tex> {{---}} количество пар сильно пересекающихся сайтов.
| |
− |
| |
− | ==Ссылки==
| |
− | * [http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.112.8990&rep=rep1&type=pdf ''Menalaos I. Karavelas'' A robust and efficient implementation for the segment Voronoi diagram.]
| |
− | * [http://www.sciencedirect.com/science/article/pii/0925772193900333/pdf?md5=ce44776db4922c6579a191a7c7ada933&pid=1-s2.0-0925772193900333-main.pdf ''Rolf Klein'' Randomized incremental construction of abstract Voronoi diagrams.]
| |
| | | |
| [[Категория: Вычислительная геометрия]] | | [[Категория: Вычислительная геометрия]] |
Эта статья находится в разработке!
Определения
Неформальное определение
Пример диаграммы Вороного
Есть множество точек [math]P[/math] на плоскости. Для всех точек [math]q \notin P[/math] этой плоскости узнаем ближайшую к [math]q[/math] точку из [math]P[/math]. Таким образом получим разбиение плоскости на кусочки, в каждом из которых содержится одна точка [math]p_i[/math] из [math]P[/math] и все точки [math]q[/math], для которых [math]p_i[/math] — ближайшая среди точек из [math]P[/math].
Формальное определение
[math]P = \{ p_1, p_2, ..., p_n\}[/math] — множество точек на плоскости. Назовём их сайтами (site).
Определение: |
Диаграмма Вороного (Voronoi diagram, [math]Vor(P)[/math]) для сайтов [math]P = \{ p_1, p_2, ..., p_n\}[/math] на плоскости — это разбиение плоскости на [math]n[/math] ячеек (ячейка Вороного, Voronoi cell, [math]\mathcal{V}(p_i)[/math]), по одной для каждого сайта, которые обладают свойством: [math]\rho(q, p_i) \lt \rho(q, p_j)[/math] для всех [math]p_j \in P, \ j \neq i[/math]. |
В зависимости от контекста будем называть диаграммой Вороного как разбиение на ячейки, так и составляющие эти ячейки вершины и рёбра.
Свойства
Количество вершин и рёбер в ячейке
Возьмём две точки плоскости: [math]p[/math] и [math]q[/math]. Проведём серединный перпендикуляр к отрезку [math]pq[/math]; полученную полуплоскость, которая содержит в себе [math]p[/math], обозначим [math]h(p, q)[/math], другую — [math]h(q, p)[/math]. Заметим, что [math]r \in h(p, q)[/math] тогда и только тогда, когда [math]\rho(r, p) \lt \rho(r, q)[/math]. Отсюда вытекает следующее:
Утверждение: |
[math]\mathcal{V}(p_i) = \cap_{1 \leqslant j \leqslant n, j \neq i} h(p_i, p_j)[/math] |
Отсюда получаем, что что ячейка Вороного — это пересечение [math]n - 1[/math] полуплоскостей, и поэтому представляет собой (возможно, неограниченную) открытую выпуклую область с не более чем [math]n - 1[/math] вершинами и [math]n - 1[/math] рёбрами.
Отсутствие прямых в общем случае
Теорема: |
Пусть [math]P[/math] — множество из [math]n[/math] сайтов. Если они все лежат на одной прямой, то [math]Vor(P)[/math] представляет собой [math]n - 1[/math] параллельную прямую. Иначе [math]Vor(P)[/math] связная и все её рёбра — либо отрезки, либо лучи. |
Доказательство: |
[math]\triangleright[/math] |
В случае, если все сайты лежат на одной прямой, каждая пара соседних сайтов порождает серединный перпендикуляр к отрезку, содержащему их, и, соответственно, к прямой, которая содержит все сайты. Так получаются [math]n - 1[/math] прямая, каждая из которых перпендикулярна прямой, содержащей сайты, а значит, эти прямые параллельны.
Рассмотрим теперь случай, когда сайты не лежат на одной прямой. Покажем, что рёбра — это отрезки или лучи, от противного. Предположим, что есть ребро [math]e[/math], являющееся прямой. Пусть оно — граница ячеек [math]\mathcal{V}(p_i)[/math] и [math]\mathcal{V}(p_j)[/math]. Пусть точка [math]p_k \in P[/math] не лежит на прямой [math]p_i p_j[/math] (по условию такая точка существует). Тогда серединный перпендикуляр к [math]p_j p_k[/math] не параллелен [math]e[/math], и, значит, он его пересекает. Но тогда та часть [math]e[/math], что лежит в [math]h(p_k, p_j)[/math], не может быть границей [math]\mathcal{V}(p_j)[/math], потому что она ближе к [math]p_k[/math], чем к [math]p_j[/math]. Пришли к противоречию.
Докажем теперь, что диаграмма связна. Предположим, что это не так. Тогда на её рёбрах найдутся две точки [math]s[/math] и [math]t[/math], между которыми нет пути по рёбрам диаграммы. Рассмотрим отрезок [math]st[/math]. Он пересекает некоторое количество ячеек диаграммы, и, раз пути по рёбрам нет, какая-то из них несвязная. Это возможно, только если какая-то ячейка представляет собой полосу, ограниченную двумя параллельными прямыми. Но в нашем случае в диаграмме не может быть прямых, пришли к противоречию. |
[math]\triangleleft[/math] |
Линейность
Теорема: |
Для [math]n \geqslant 3[/math] сайтов диаграмма Вороного содержит не больше [math]2n - 5[/math] вершин и [math] 3n - 6[/math] рёбер. |
Доказательство: |
[math]\triangleright[/math] |
Для случая сайтов, лежащих на одной прямой, утверждение напрямую следует из вида диаграммы для этого случая, поэтому рассмотрим общий случай. По формуле Эйлера [math]v - e + f = 2[/math], где [math]v[/math] — число вершин, [math]e[/math] — число рёбер и [math]f[/math] — число граней связного планарного графа. Мы не можем сразу применить эту формулу к [math]Vor(P)[/math], потому что в этом графе есть полубесконечные рёбра. Поэтому добавим вершину [math]n_\infty[/math], и все полубесконечные рёбра мы превратим в рёбра, инцидентные ей. Таким образом мы увеличили число вершин на одну, а число рёбер не изменилось. Число граней равно [math]n[/math] по определению диаграммы Вороного. Тогда по формуле Эйлера получаем [math](v + 1) - e + n = 2[/math].
Сумма степеней всех вершин полученного графа равна [math]2e[/math], так как у каждого ребра есть ровно два конца (нет петель). Также у из каждой вершины исходят как минимум три ребра. Отсюда получаем [math]2e \geqslant 3 (n + 1)[/math].
Домножим равенство на два и вычтем из него полученную нижнюю границу для [math]2 \cdot e[/math], в результате получим [math] v \leqslant 2n - 5[/math]. Далее подставим этот результат в равенство и получим [math]e \leqslant 3n - 6[/math], что и требовалось доказать. |
[math]\triangleleft[/math] |
Связь с триангуляцией Делоне
Определение: |
Наибольшая пустая окружность точки [math]q[/math] по отношению к [math]P[/math] ([math]C_P(q)[/math]) — наибольшая окружность с центром в [math]q[/math] такая, что во внутренности соответствующего ей круга не лежит ни одного сайта из [math]P[/math]. |
Лемма: |
Точка [math]q[/math] — вершина диаграммы Вороного в том и только в том случае, когда [math]C_P(q)[/math] содержит три и более сайтов на своей границе. |
Доказательство: |
[math]\triangleright[/math] |
Предположим, что [math]q[/math] существует, а [math]p_i, \ p_j, \ p_k[/math] — соответствующие точки. Так как внутри [math]C_P(q)[/math] нет других сайтов, [math]q[/math] должна быть на границе [math]\mathcal{V}(p_i), \ \mathcal{V}(p_j), \ \mathcal{V}(p_k)[/math] одновременно, то есть вершиной диаграмму.
Докажем в другую сторону: каждая вершина [math]q[/math] диаграммы инцидентна минимум трём рёбрам, и, поэтому, как минимум трём ячейкам [math]\mathcal{V}(p_i), \ \mathcal{V}(p_j), \ \mathcal{V}(p_k)[/math]. Тогда [math]q[/math] лежит на равном расстоянии от [math]p_i, \ p_j, \ p_k[/math] и не может быть другого сайта ближе к [math]q[/math], так как иначе [math]\mathcal{V}(p_i), \ \mathcal{V}(p_j), \ \mathcal{V}(p_k)[/math] не сойдутся в [math]q[/math]. Поэтому можно построить окружность с центром в [math]q[/math] и [math]p_i, \ p_j, \ p_k[/math] на границе так, что внутри не будет других сайтов. |
[math]\triangleleft[/math] |
Лемма: |
Серединный перпендикуляр к отрезку [math]p_i p_j[/math] образует ребро диаграммы Вороного в том и только в том случае, если на нём есть точка [math]q[/math] такая, что [math]C_P(q)[/math] содержит на своей границе только сайты [math]p_i, \ p_j[/math]. |
Доказательство: |
[math]\triangleright[/math] |
Предположим, что [math]q[/math] существует. Тогда, так как [math]C_P(q)[/math] не содержит в себе сайтов и содержит [math]p_i, \ p_j[/math] на границе, [math] \rho(q, p_i) = \rho(q, p_j) \leqslant \rho(q, p_k), \ 1 \leqslant k \leqslant n[/math]. Отсюда выходит, что [math]q[/math] лежит — вершина [math]Vor(P)[/math] или лежит на ребре диаграммы. Но по предыдущей лемме выходит, что [math]q[/math] не может быть вершиной диаграммы. Значит, она лежит на ребре, заданном серединным перпендикуляром к [math]p_i p_j[/math].
Докажем в другую сторону: пусть серединный перпендикуляр к [math]p_i p_j[/math] задаёт ребро диаграммы. Наибольшая пустая окружность любой точки [math]q[/math] на этом ребре должна содержать на границе [math]p_i[/math] и [math]p_j[/math], и никаких других сайтов внутри. |
[math]\triangleleft[/math] |
Теорема: |
Если соединить все сайты, соответствующие смежным ячейкам диаграммы Вороного, получится триангуляция Делоне для этого множества точек. |
Доказательство: |
[math]\triangleright[/math] |
Если ячейки, соответствующие сайтам [math]p_i, \ p_j[/math], смежны, то серединный перпендикуляр к отрезку [math]p_i p_j[/math] образует ребро диаграммы Вороного, то есть к нему применима предыдущая лемма и можно построить окружность с [math]p_i[/math] и [math]p_j[/math] на границе, внутри которой не будет других сайтов. Вспомним, что триангуляции Делоне принадлежат те и только те рёбра (с поправкой на точки, лежащие на одной окружности), на которых можно построить такую окружность, что внутри неё не будет лежать никаких точек. Тогда ребро [math]p_i p_j[/math] является ребром триангуляции Делоне. За счёт равносильности в обеих используемых леммах мы добавим все рёбра и не построим лишних. |
[math]\triangleleft[/math] |
Построение
Наивный алгоритм
Будем пересекать полуплоскости по по свойству ячейки диаграммы. Необходимо [math]n[/math] раз пересечь [math]n - 1[/math] плоскость, что суммарно делается за [math]O(n^2 \log n)[/math].