Алгоритм вычисления диаграммы Вороного на сфере?

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

11 ответов


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

или если вы Грок Фортран (бла!) есть этот сайт.


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

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

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

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


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

недавно я написал открытый исходный код 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

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



есть статья из INRIA о триангуляции Делоне (DT) точек, лежащих на сфере: Кароли, Мануэль и др. Надежные и эффективные триангуляции Делоне точек на сфере или вблизи нее. 2009., где они говорят о реализации в CGAL.

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

цитата из статьи:

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

для вычисления выпуклой оболочки в документе говорится:

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

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

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


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

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

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

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


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

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


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

Я думаю, что "точки на поверхности сферы" означает, что вы сначала должны переназначить их в 2D-координаты, создать диаграмму Вороного, а затем переназначить их в координаты поверхности сферы. Являются ли две формулы из Википедия UV mapping статья здесь работать?

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


CGAL работает над пакетом "сферическое ядро", который позволит вычислить именно такие вещи. К сожалению, - это не, но, возможно, это будет в следующем релизе, так как они уже упомянул об этом в Google tech talk в марте


цитата из этой ссылки: http://www.qhull.org/html/qdelaun.htm

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


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