Участник:D.Polykovskiy/Алгоритм Бойера-Ватсона: различия между версиями

Материал из Алговики
Перейти к навигации Перейти к поиску
Строка 32: Строка 32:
 
==Вычислительное ядро алгоритма==
 
==Вычислительное ядро алгоритма==
 
Большая часть времени работы алгоритма приходится на поиск поврежденных треугольников. В простейшей реализации это делается за ''O(|S|)'', однако эта сложность может быть в среднем уменьшена до ''O(log|S|)''  при структурировании  пространства (нпр., KD-деревом). Тем не менее в худшем случае поиск все равно будет требовать  ''O(|S|)'' действий.  
 
Большая часть времени работы алгоритма приходится на поиск поврежденных треугольников. В простейшей реализации это делается за ''O(|S|)'', однако эта сложность может быть в среднем уменьшена до ''O(log|S|)''  при структурировании  пространства (нпр., KD-деревом). Тем не менее в худшем случае поиск все равно будет требовать  ''O(|S|)'' действий.  
 
В среднем число поврежденных треугольников оказывается малым, поэтому все действия кроме поиска выполняются в среднем за ''O(1)''.
 
 
Учитывая итерации по объектам, в худшем случае вне зависимости от использования структурирования пространства получается сложность ''O(|S|<sup>2</sup>)''. Однако средняя оценка при структурировании снижается до  ''O(|S| log|S|)''.
 
  
 
==Макроструктура алгоритма==
 
==Макроструктура алгоритма==
 
===Проверка на вхождение в описанную окружность===
 
===Проверка на вхождение в описанную окружность===
Для работы алгоритма требуется уметь проверять точку D на принадлежность описанной окружности треугольника ABC. Для двумерного случая это может быть сделано при помощи перехода в 3D пространство по схеме ''(x, y) -> (x, y, x<sup>2</sup>+y<sup>2</sup>)''<ref>{{cite journal
+
Для работы алгоритма требуется уметь проверять точку D на принадлежность описанной окружности треугольника ABC. Для двумерного случая это может быть сделано при помощи перехода в 3D пространство по схеме ''(x, y) -> (x, y, x<sup>2</sup>+y<sup>2</sup>)''<ref>Leonidas J. Guibas, Jorge Stolfi Primitives for the manipulation of general subdivisions and the computation of Voronoi, ACM Transactions on Graphics </ref>
  | last1 = Guibas
+
В новом пространстве точке расположены на параболоиде. Утверждается, что четыре точки коцикличны в ''(x, y)'' тогда и только тогда, когда они компланарны в пространстве ''(x, y, x<sup>2</sup>+y<sup>2</sup>)''. Пользуясь выпуклостью парабалоида, можно сформулировать критерий принадлежности точки описанной окружности: достаточно проверить неотрицательность определителя матрицы (предполагается, что точки расположены против часовой стрелки)
  | first1 = Leonidas
 
  | authorlink1 = Leonidas J. Guibas
 
  | last2 = Stolfi
 
  | first2 = Jorge
 
  | authorlink2 = Jorge Stolfi
 
  | title = Primitives for the manipulation of general subdivisions and the computation of Voronoi
 
  | journal = [[ACM Transactions on Graphics]]
 
  | volume = 4
 
  | pages = 74–123
 
  | year = 1985
 
  | doi = 10.1145/282918.282923
 
  | issue = 2
 
  | url = http://portal.acm.org/citation.cfm?id=282923 }}
 
</ref>. В новом пространстве точке расположены на параболоиде. Утверждается, что четыре точки коцикличны в ''(x, y)'' тогда и только тогда, когда они компланарны в пространстве ''(x, y, x<sup>2</sup>+y<sup>2</sup>)''. Пользуясь выпуклостью парабалоида, можно сформулировать критерий принадлежности точки описанной окружности: достаточно проверить неотрицательность определителя матрицы (предполагается, что точки расположены против часовой стрелки)
 
  
 
: <math>\begin{vmatrix}
 
: <math>\begin{vmatrix}
Строка 70: Строка 52:
 
===Построение super-triangle===
 
===Построение super-triangle===
 
Построить super-triangle можно множеством способов. Например, можно найти разброс (''max-min'') значений координат точек вдоль каждой из осей. Затем можно вычислить максимальное среди этих значений, обозначив его за ''w''. После этого можно взять центр масс точек ''S'' и отступить от него вверх на ''2w'' (точка A), вниз на 2w и влево на 2w (точка B) и, наконец, вниз на 2w и вправо на 2w (точка C). Треугольник ABC будет заведомо содержать все точки из ''S''.
 
Построить super-triangle можно множеством способов. Например, можно найти разброс (''max-min'') значений координат точек вдоль каждой из осей. Затем можно вычислить максимальное среди этих значений, обозначив его за ''w''. После этого можно взять центр масс точек ''S'' и отступить от него вверх на ''2w'' (точка A), вниз на 2w и влево на 2w (точка B) и, наконец, вниз на 2w и вправо на 2w (точка C). Треугольник ABC будет заведомо содержать все точки из ''S''.
 +
 +
===Поиск границы объединения треугольников===
 +
Эту задачу требуется решить только для связного множества треугольников. Поэтому достаточно взять все ребра треугольников и выкинуть дублирующиеся. Оставшиеся ребра будут образовывать искомый многоугольник.
  
 
==Схема реализации последовательного алгоритма==
 
==Схема реализации последовательного алгоритма==
Строка 99: Строка 84:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==Pseudocode==
+
==Последовательная сложность алгоритма==
The following [[pseudocode]] describes a basic implementation of the Bowyer-Watson algorithm. Efficiency can be improved in a number of ways. For example, the triangle connectivity can be used to locate the triangles which contain the new point in their circumcircle, without having to check all of the triangles. Pre-computing the circumcircles can save time at the expense of additional memory usage. And if the points are uniformly distributed, sorting them along a space filling [[Hilbert curve]] prior to insertion can also speed point location.<ref>Liu, Yuanxin, and Jack Snoeyink. "A comparison of five implementations of 3D Delaunay tessellation." Combinatorial and Computational Geometry 52 (2005): 439-458.</ref>
+
В среднем число поврежденных треугольников оказывается малым, поэтому все действия кроме поиска выполняются в среднем за ''O(1)''.  
 
 
  <syntaxhighlight lang="javascript">
 
  function BowyerWatson (pointList)
 
      // pointList is a set of coordinates defining the points to be triangulated
 
      triangulation := empty triangle mesh data structure
 
      add super-triangle to triangulation // must be large enough to completely contain all the points in pointList
 
      for each point in pointList do // add all the points one at a time to the triangulation
 
        badTriangles := empty set
 
        for each triangle in triangulation do // first find all the triangles that are no longer valid due to the insertion
 
            if point is inside circumcircle of triangle
 
              add triangle to badTriangles
 
        polygon := empty set
 
        for each triangle in badTriangles do // find the boundary of the polygonal hole
 
            for each edge in triangle do
 
              if edge is not shared by any other triangles in badTriangles
 
                  add edge to polygon
 
        for each triangle in badTriangles do // remove them from the data structure
 
            remove triangle from triangulation
 
        for each edge in polygon do // re-triangulate the polygonal hole
 
            newTri := form a triangle from edge to point
 
            add newTri to triangulation
 
      for each triangle in triangulation // done inserting points, now clean up
 
        if triangle contains a vertex from original super-triangle
 
            remove triangle from triangulation
 
      return triangulation
 
</syntaxhighlight>
 
 
 
== See also ==
 
* [[Fortune's algorithm]]
 
* [[Delaunay triangulation]]
 
* [[Computational geometry]]
 
 
 
==References==
 
{{reflist}}
 
*{{Cite journal | last1 = Bowyer | first1 = Adrian |author1-link=Adrian Bowyer| title = Computing Dirichlet tessellations | doi = 10.1093/comjnl/24.2.162 | journal = [[The Computer Journal|Comput. J.]] | volume = 24 | issue = 2 | pages = 162–166 | year = 1981 | pmid =  | pmc = }}
 
*{{Cite journal | last1 = Watson | first1 = David F. | authorlink1 = | title = Computing the ''n''-dimensional Delaunay tessellation with application to Voronoi polytopes | doi = 10.1093/comjnl/24.2.167 | journal = [[The Computer Journal|Comput. J.]] | volume = 24 | issue = 2 | pages = 167–172 | year = 1981 | pmid =  | pmc = }}
 
* [http://paulbourke.net/papers/triangulate/ Efficient Triangulation Algorithm Suitable for Terrain Modelling] generic explanations with source code examples in several languages.
 
  
{{DEFAULTSORT:Bowyer-Watson algorithm}}
+
В худшем случае вне зависимости от использования структурирования пространства получается сложность ''O(|S|<sup>2</sup>)''. Однако средняя оценка при структурировании снижается до  ''O(|S| log|S|)''.
[[Category:Geometric algorithms]]
 

Версия 01:36, 13 ноября 2016

Алгоритм Бойера–Ватсона --- метод, позволяющий построить триангуляцию Делоне конечного множества точек в пространстве любой размерности. Как следствие, алгоритм позволяет получить диаграму Вороного.

1 Свойства и структура алгоритма

1.1 Общее описание алгоритма

Алгоритм Бойера–Ватсона позволяет построить триангуляцию Деолне конечного множества точек в пространстве любой размерности. Он относится к семейству инкрементальных, т.е. проводит построение путем поочередного добавления точек, получая при этом на каждом шаге корректную триангуляцию Делоне текущего подмножества точек.

1.2 Математическое описание алгоритма

Триангуля́ция Делоне́ — триангуляция заданного множества точек S на плоскости (или в пространстве большей размерности), при которой для любого треугольника все точки из S за исключением точек, являющихся его вершинами, лежат вне окружности, описанной вокруг треугольника. На многомерный случай алгоритм обобщается путем замены треугольников на многомерные симплексы.

Итерации алгоритма строятся следующим образом: На нулевой итерации строится треугольник (super-triangle), покрывающий все точки множества (таким образом множество S пополняется тремя вспомогательными точками). Начальное множество треугольников состоит только из этого треугольника. Далее итеративно выполняются следующие действия:

  1. Добавляется новая точка
  2. Из множества треугольников выкидываются все треугольники, в описанную окружность в которых попадает новая точка. Таким образом в триангуляции образуется дырка в форме многоугольника.
  3. Эта дырка заполняется треугольниками, содержащими новую точку в качестве одной вершины и ребрами дырки в качестве противолежащей стороны.

Доказано, что после завершения каждой итерации будет получена корректная триангуляция Делоне.

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

1.3 Вычислительное ядро алгоритма

Большая часть времени работы алгоритма приходится на поиск поврежденных треугольников. В простейшей реализации это делается за O(|S|), однако эта сложность может быть в среднем уменьшена до O(log|S|) при структурировании пространства (нпр., KD-деревом). Тем не менее в худшем случае поиск все равно будет требовать O(|S|) действий.

1.4 Макроструктура алгоритма

1.4.1 Проверка на вхождение в описанную окружность

Для работы алгоритма требуется уметь проверять точку D на принадлежность описанной окружности треугольника ABC. Для двумерного случая это может быть сделано при помощи перехода в 3D пространство по схеме (x, y) -> (x, y, x2+y2)[1] В новом пространстве точке расположены на параболоиде. Утверждается, что четыре точки коцикличны в (x, y) тогда и только тогда, когда они компланарны в пространстве (x, y, x2+y2). Пользуясь выпуклостью парабалоида, можно сформулировать критерий принадлежности точки описанной окружности: достаточно проверить неотрицательность определителя матрицы (предполагается, что точки расположены против часовой стрелки)

[math]\begin{vmatrix} A_x & A_y & A_x^2 + A_y^2 & 1\\ B_x & B_y & B_x^2 + B_y^2 & 1\\ C_x & C_y & C_x^2 + C_y^2 & 1\\ D_x & D_y & D_x^2 + D_y^2 & 1 \end{vmatrix} = \begin{vmatrix} A_x - D_x & A_y - D_y & (A_x^2 - D_x^2) + (A_y^2 - D_y^2) \\ B_x - D_x & B_y - D_y & (B_x^2 - D_x^2) + (B_y^2 - D_y^2) \\ C_x - D_x & C_y - D_y & (C_x^2 - D_x^2) + (C_y^2 - D_y^2) \end{vmatrix} \gt 0 [/math]

1.4.2 Построение super-triangle

Построить super-triangle можно множеством способов. Например, можно найти разброс (max-min) значений координат точек вдоль каждой из осей. Затем можно вычислить максимальное среди этих значений, обозначив его за w. После этого можно взять центр масс точек S и отступить от него вверх на 2w (точка A), вниз на 2w и влево на 2w (точка B) и, наконец, вниз на 2w и вправо на 2w (точка C). Треугольник ABC будет заведомо содержать все точки из S.

1.4.3 Поиск границы объединения треугольников

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

1.5 Схема реализации последовательного алгоритма

   function BowyerWatson (pointList)
      // pointList - множество точек для триангуляции
      triangulation := пустое множество треугольников
      Добавляем super-triangle в триангуляцию
      for each point in pointList do // последовательно добавляем точки
         badTriangles := empty set
         for each triangle in triangulation do // находим поврежденные треугольники
            if point is inside circumcircle of triangle
               add triangle to badTriangles
         polygon := empty set
         for each triangle in badTriangles do // находим границу дырки
            for each edge in triangle do
               if edge is not shared by any other triangles in badTriangles
                  add edge to polygon
         for each triangle in badTriangles do // удаляем поврежденные треугольники
            remove triangle from triangulation
         for each edge in polygon do // заполняем дырку
            newTri := form a triangle from edge to point
            add newTri to triangulation
      for each triangle in triangulation // убираем вершины super-triangle
         if triangle contains a vertex from original super-triangle
            remove triangle from triangulation
      return triangulation

1.6 Последовательная сложность алгоритма

В среднем число поврежденных треугольников оказывается малым, поэтому все действия кроме поиска выполняются в среднем за O(1).

В худшем случае вне зависимости от использования структурирования пространства получается сложность O(|S|2). Однако средняя оценка при структурировании снижается до O(|S| log|S|).

  1. Leonidas J. Guibas, Jorge Stolfi Primitives for the manipulation of general subdivisions and the computation of Voronoi, ACM Transactions on Graphics