Алгоритм вычисления диаграммы Вороного на сфере? - PullRequest
34 голосов
/ 13 февраля 2009

Я ищу простой (если существует) алгоритм для поиска диаграммы Вороного для набора точек на поверхности сферы. Исходный код был бы великолепен. Я человек Delphi (да, я знаю ...), но я тоже ем C-код.

Ответы [ 11 ]

20 голосов
/ 27 ноября 2014

Обновление в июле 2016 года:

Благодаря ряду добровольцев (особенно Николая Новачика и меня), теперь есть гораздо более надежный / правильный код для обработки диаграмм Вороного на поверхности сферы в Python. Это официально доступно как scipy.spatial.SphericalVoronoi от версии 0.18 scipy и далее. В официальных документах .

есть рабочий пример использования и печати.

Алгоритм следует квадратичной сложности времени. Хотя логлинейный является теоретическим оптимумом для диаграмм Вороного на поверхностях сфер, в настоящее время это лучшее, что мы смогли реализовать. Если вы хотите узнать больше и помочь в разработке, есть некоторые открытые проблемы, связанные с улучшением способа обработки Python сферических диаграмм Вороного и соответствующих структур данных:

Для получения дополнительной информации о теории / разработке / проблемах, связанных с этим кодом Python и связанных с этим работах по вычислительной геометрии, вы также можете ознакомиться с некоторыми докладами Николая и I:


Оригинальный ответ:

На самом деле я недавно написал некоторый открытый код Python для диаграмм Вороного на поверхности сферы: https://github.com/tylerjereddy/py_sphere_Voronoi

Использование, алгоритм и ограничения задокументированы на readthedocs (http://py -sphere-voronoi.readthedocs.org / en / latest / voronoi_utility.html ). Там есть несколько подробных примеров, но я приведу один или два ниже. Модуль также обрабатывает расчет площади поверхности области Вороного, хотя и с некоторыми численными недостатками в текущей версии разработки.

Я не видел много хорошо документированных реализаций с открытым исходным кодом для сферических диаграмм Вороного, но было немного шума по поводу реализации JavaScript на сайте Джейсона Дэвиса (http://www.jasondavies.com/maps/voronoi/). Я не думаю, что его хотя код открыт. Я также видел сообщение в блоге об использовании Python для решения части проблемы (http://jellymatter.com/2014/01/29/voronoi-tessellation-on-the-surface-of-a-sphere-python-code/). Многие первичные литературные источники, процитированные в приведенных выше публикациях, казались очень сложными для реализации (некоторые из них я пробовал) ) но, возможно, некоторые люди сочтут мою реализацию полезной или даже предложат способы ее улучшения.

Примеры:

1) Создание диаграммы Вороного для псевдослучайного набора точек на единичной сфере:

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.colors as colors
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import numpy as np
import scipy as sp
import voronoi_utility
#pin down the pseudo random number generator (prng) object to avoid certain pathological generator sets
prng = np.random.RandomState(117) #otherwise, would need to filter the random data to ensure Voronoi diagram is possible
#produce 1000 random points on the unit sphere using the above seed
random_coordinate_array = voronoi_utility.generate_random_array_spherical_generators(1000,1.0,prng)
#produce the Voronoi diagram data
voronoi_instance = voronoi_utility.Voronoi_Sphere_Surface(random_coordinate_array,1.0)
dictionary_voronoi_polygon_vertices = voronoi_instance.voronoi_region_vertices_spherical_surface()
#plot the Voronoi diagram
fig = plt.figure()
fig.set_size_inches(2,2)
ax = fig.add_subplot(111, projection='3d')
for generator_index, voronoi_region in dictionary_voronoi_polygon_vertices.iteritems():
   random_color = colors.rgb2hex(sp.rand(3))
   #fill in the Voronoi region (polygon) that contains the generator:
   polygon = Poly3DCollection([voronoi_region],alpha=1.0)
   polygon.set_color(random_color)
   ax.add_collection3d(polygon)
ax.set_xlim(-1,1);ax.set_ylim(-1,1);ax.set_zlim(-1,1);
ax.set_xticks([-1,1]);ax.set_yticks([-1,1]);ax.set_zticks([-1,1]); 
plt.tick_params(axis='both', which='major', labelsize=6)

enter image description here

2) Рассчитать площади поверхности полигонов области Вороного и убедиться, что восстановленная площадь поверхности является разумной:

import math
dictionary_voronoi_polygon_surface_areas = voronoi_instance.voronoi_region_surface_areas_spherical_surface()
theoretical_surface_area_unit_sphere = 4 * math.pi
reconstituted_surface_area_Voronoi_regions = sum(dictionary_voronoi_polygon_surface_areas.itervalues())
percent_area_recovery = round((reconstituted_surface_area_Voronoi_regions / theoretical_surface_area_unit_sphere) * 100., 5)
print percent_area_recovery
97.87551 #that seems reasonable for now
11 голосов
/ 13 февраля 2009

Вот статья о сферических диаграммах Вороного .

Или, если вы делаете Фортран (блин!), Есть этот сайт .

8 голосов
/ 20 декабря 2012

Обратите внимание, что триангуляция Делоне на сфере - это просто выпуклая оболочка. Таким образом, вы можете вычислить выпуклый 3D-корпус (например, используя CGAL) и возьми двойное.

3 голосов
/ 23 сентября 2013

Прошло много времени с тех пор, как на вопрос был дан ответ, но я нашел две статьи, в которых реализован алгоритм Фортуны (эффективность O (N lg N), память O (N)) на поверхности сфера. Возможно, будущему зрителю эта информация будет полезна.

  • «Подметание сферы» Диниса и Мамеде, опубликовано в 2010 году на Международном симпозиуме по диаграммам Вороного в науке и технике. Можно купить за http://dx.doi.org/10.1109/ISVD.2010.32
  • «Алгоритм плоской развертки для тесселяции сферы Вороного», Zheng et al. Я не уверен, что он был опубликован из-за первого, но он датирован 13 декабря 2011 года. Он доступен бесплатно по адресу http://www.e -lc.org / tmp / Xiaoyu__Zheng_2011_12_05_14_35_11.pdf

Сейчас я прорабатываю их сам, поэтому не могу объяснить это хорошо. Основная идея заключается в том, что алгоритм Fortune работает на поверхности сферы до тех пор, пока вы правильно рассчитаете ограничивающие параболы точек. Поскольку поверхность сферы обернута, вы также можете использовать круговой список, чтобы содержать линию пляжа и не беспокоиться об обработке ячеек на краю прямоугольного пространства. При этом вы можете пролететь от северного полюса сферы к югу и вернуться назад, пропуская участки, которые вводят новые точки на линию пляжа (добавляя параболу к линии пляжа) или вводя вершины ячейки (удаляя парабола от береговой линии).

Обе статьи ожидают высокого уровня комфорта с линейной алгеброй, чтобы понять концепции, и они оба теряют меня в момент, когда они начинают объяснять сам алгоритм. К сожалению, не предоставляйте исходный код.

3 голосов
/ 21 июня 2013

Существует статья INRIA о триангуляции Делоне (DT) точек, лежащих на сфере: CAROLI, Manuel, et al. Надежные и эффективные триангуляции Делоне для точек на сфере или рядом с ней. 2009. , где они говорят о реализации в CGAL .

В статье рассматриваются различные доступные реализации алгоритмов DT.

Цитата из статьи:

Простой и стандартный ответ заключается в вычислении выпуклой 3D-оболочки из точек, который общеизвестно эквивалентен.

для вычисления выпуклой оболочки, предложенной в статье:

  1. Hull, программа для выпуклых оболочек.
  2. Qhull .
  3. Трехмерные выпуклые корпуса. в Фортране. Трехмерные выпуклые корпуса.
  4. STRIPACK на Фортране.

Класс CGAL DT C ++ имеет метод dual для получения диаграммы Вороного.

Согласно этой записи Моники Тейло (одного из авторов вышеупомянутой статьи) мне кажется, что в ноябре 2012 года реализация еще не была готова.

3 голосов
/ 19 марта 2012
2 голосов
/ 24 июня 2009

Я думаю, что плоскость Вороного для каждой точки может быть построена с использованием неевклидовой геометрии. То, что обычно было линией на 2d плоскости, теперь является «большим кругом» на сфере (см. Википедия: эллиптическая геометрия ). Легко определить, какие точки находятся на неправильной стороне любого большого круга между двумя точками, просто вращая сферу таким образом, что делительный большой круг является экватором, а затем все точки на другом полушарии, чем точка, на которой вы находитесь построение плоскости Вороного для.

Это не полный ответ, но это то, с чего я бы начал ..

1 голос
/ 01 апреля 2013

Цитирование из этой ссылки: http://www.qhull.org/html/qdelaun.htm

Чтобы вычислить триангуляцию Делоне точек на сфере, вычислите их выпуклую оболочку. Если сфера - это единичная сфера в начале координат, нормали фасетов - это вершины Вороного входа.

1 голос
/ 19 июня 2009

CGAL работает над пакетом «сферическое ядро», которое позволит вычислять именно такие вещи. К сожалению, еще не выпущен , но, возможно, это будет в их следующем выпуске, так как они уже упомянули об этом в техническом докладе Google в марте

1 голос
/ 13 февраля 2009

Хорошая программа-пример диаграммы Вороного здесь (включая исходный код для Delphi 5/6).

Я думаю, что «точки на поверхности сферы» означают, что вы должны сначала переназначить их в 2D-координаты, создать диаграмму Вороного, а затем переназначить их в координаты поверхности сферы. Работают ли здесь две формулы из статьи из *1005* Wikipedia UV?

Также обратите внимание, что диаграмма Вороного будет иметь неправильную топологию (она находится внутри прямоугольника и не «обтекает»), здесь это может помочь скопировать все точки из (0,0) - (x, y) в соседние регионы сверху (0, -y * 2) - (x, 0), ниже (0, y) - (x, y * 2), слева (-x, 0) - (0, y) и справа (х, 0) - (х * 2, у). Я надеюсь, вы понимаете, о чем я, не стесняйтесь спрашивать:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...