Алгоритм Вороного, без сомнения, предоставил гибкий подход к разделению плоскости на области на основе расстояния до точек в определенном подмножестве плоскости. Такая диаграмма Вороного для набора точек двойственна своей триангуляции Делоне. Эта цель теперь может быть достигнута напрямую, используя модуль 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()