Как создать модифицированный алгоритм Вороного для случайных точек с физическим ограничением

Алгоритм Вороного, без сомнения, предоставил гибкий подход к разделению плоскости на области на основе расстояния до точек в определенном подмножестве плоскости. Такая диаграмма Вороного для набора точек двойственна своей триангуляции Делоне. Эта цель теперь может быть достигнута напрямую, используя модуль scipy как

import scipy.spatial

point_coordinate_array = np.array(point_coordinates)
delaunay_mesh = scipy.spatial.Delaunay(point_coordinate_array)
voronoi_diagram = scipy.spatial.Voronoi(point_coordinate_array)

# plot(delaunay_mesh and voronoi_diagram using matplotlib)

когда данные баллы заранее. Результаты могут быть показаны на рис. 1,

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

До сих пор все кажется совершенным. Но для реального применения все точки могут иметь собственное физическое значение. (Например, эти точки могут иметь переменные «радиусы», когда они представляют естественные частицы). И общий алгоритм Вороного, описанный выше, должен быть более или менее неподходящим для такого случая, в котором может быть рассмотрено сложное физическое ограничение. Как показано на рис. 2, гребни ячейки Вороного могут пересекать границу частицы. Он больше не может соответствовать физическим требованиям.

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

введите описание изображения здесь

Все требования к пункту:

1. numpy-1.13.3 + mkl-cp36-cp36m-win_amd64.whl

2. scipy-0.19.1-cp36-cp36m-win_amd64.whl

3. matplotlib-2.1.0-cp36-cp36m-win_amd64.whl

и все они могут быть непосредственно загружены со страницы http://www.lfd.uci.edu/~gohlke/pythonlibs/

Мои коды обновлены для лучшей модификации, они как

import numpy as np
import scipy.spatial
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib.collections import PatchCollection

# give the point-coordinate array for contribute the tri-network.
point_coordinate_array = np.array([[0,0.5],[8**0.5,8**0.5+0.5],[0,-3.5],[-np.sqrt(15),1.5]])

# give the physical restriction (radius array) here.
point_radius_array = np.array([2.5,1.0,1.0,1.0])

# create the delaunay tri-mesh and voronoi diagram for the given points here.
point_trimesh = scipy.spatial.Delaunay(point_coordinate_array)
point_voronoi = scipy.spatial.Voronoi(point_coordinate_array)

# show the results using matplotlib.
# do the matplotlib setting here.
fig_width = 8.0; fig_length = 8.0
mpl.rc('figure', figsize=((fig_width * 0.3937), (fig_length * 0.3937)), dpi=300)
mpl.rc('axes', linewidth=0.0, edgecolor='red', labelsize=7.5, labelcolor='black', grid=0)
mpl.rc('xtick.major', size=0.0, width=0.0, pad=0)
mpl.rc('xtick.minor', size=0.0, width=0.0, pad=0)
mpl.rc('ytick.major', size=0.0, width=0.0, pad=0)
mpl.rc('ytick.minor', size=0.0, width=0.0, pad=0)
mpl.rc('figure.subplot', left=0.0, right=1.0, bottom=0.065, top=0.995)
mpl.rc('savefig', dpi=300)
ax_1 = plt.figure().add_subplot(1, 1, 1)
plt.gca().set_aspect('equal')
ax_1.set_xlim(-5.5, 8.5)
ax_1.set_ylim(-4.5, 7.5)
ax_1.set_xticklabels([])
ax_1.set_yticklabels([])

# plot all the given points and vertices here.
ax_1.scatter(point_coordinate_array[:,0],point_coordinate_array[:,1],
             s=7.0,c='black')
ax_1.scatter(point_voronoi.vertices[:,0],point_voronoi.vertices[:,1],
             s=7.0,c='blue')

# plot the delaunay tri-mesh here.
ax_1.triplot(point_trimesh.points[:,0],point_trimesh.points[:,1],
             point_trimesh.vertices,
             linestyle='--',dashes=[2.0]*4,color='green',lw=0.5)

# plot the voronoi cell here.(only the closed one)
ax_1.plot(point_voronoi.vertices[:,0],point_voronoi.vertices[:,1],
          lw=1.0,color='blue')
ax_1.plot([point_voronoi.vertices[-1][0],point_voronoi.vertices[0][0]],
          [point_voronoi.vertices[-1][1],point_voronoi.vertices[0][1]],
          lw=1.0,color='blue')

# plot all the particles here.(point+radius)
patches1 = [Circle(point_coordinate_array[i], point_radius_array[i]) 
            for i in range(len(point_radius_array))]
ax_1.add_collection(PatchCollection(patches1, linewidths=1.0, 
                    edgecolor='black', facecolors='none', alpha=1.0))
# save the .png file.
plt.savefig('Fig_a.png',dpi=300)
plt.close()

person zgfu1985    schedule 19.10.2017    source источник
comment
Это классный вопрос, у меня алгоритм записан. Не могли бы вы опубликовать требования к пункту и функцию графика, чтобы я мог попытаться воспроизвести ваши диаграммы.   -  person Stefan Collier    schedule 19.10.2017
comment
Я думаю, что первым шагом было бы создание триангуляции Делоне, тогда ваша первая граница была бы линией, перпендикулярной линии, соединяющей центры окружностей и проходящей через точку, которая была посередине между окружностями двух окружностей. Интересная проблема.   -  person DrBwts    schedule 19.10.2017
comment
Это похоже на взвешенную диаграмму Вороного или, точнее, на диаграмму мощности.   -  person kazemakase    schedule 19.10.2017
comment
@Splatmistro Спасибо за ответ. Требования к пункту и обновленные коды приведены в отредактированной версии моего вопроса.   -  person zgfu1985    schedule 20.10.2017
comment
Хотя я действительно думаю, что это может быть интересная и полезная проблема, у меня проблемы с пониманием того, каким должен быть желаемый результат. Фиг3 - желаемый результат? Думаю, нет? Но тогда что представляет собой ограничение?   -  person ImportanceOfBeingErnest    schedule 20.10.2017
comment
Если вы определяете границы ячеек диаграммы Вороного в вашем случае как набор точек, для которых два ближайших круга равноудалены, то я считаю, что диаграмма не построена из линий. Вы можете увидеть это для точки и круга, например. Так что уже упомянутые диаграммы мощности (с использованием не расстояния до окружности, а длины касательной и с прямыми границами ячеек) могут быть действительно эксклюзивным вариантом.   -  person Sergey Bankevich    schedule 20.10.2017
comment
Это может быть решено с помощью диаграммы мощности. Вы можете посмотреть на этот вопрос, который дает код для сборки Диаграмма мощности в 2D.   -  person Alessandro Benedetto    schedule 06.06.2020


Ответы (1)


Это должно быть решено с помощью подхода Power Diagram. Вы можете найти алгоритмы для 2D диаграмм мощности:

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

Диаграмма мощности имеет прямые края ячеек. Кажется, это соответствует вопросу. Взвешенные диаграммы Вороного также существуют, но могут иметь в качестве ребер дуги окружности.

person Alessandro Benedetto    schedule 06.06.2020