介绍
有关这些的详细信息,请参见以下站点。
- scipy.spatial.Voronoi的正式文档
- scipy.spatial.voronoi_plot_2d的官方文档
- 西皮·沃罗诺伊
但是,由于这些库创建的Voronoi图是在无边界(无边界)空间中计算的,因此无法在Voronoi外侧或Voronoi区域(多边形)上获取信息。
因此,这一次,我将介绍一种将封闭区域划分为Voronoi图的方法。
实作
在提到Voronoi地区受限的部分时,我提到了这篇文章。
总体流程如下。
用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | import numpy as np import matplotlib.pyplot as plt from matplotlib.collections import PolyCollection from scipy.spatial import Voronoi, voronoi_plot_2d from shapely.geometry import Polygon def bounded_voronoi(bnd, pnts): """ 有界なボロノイ図を計算?描画する関数. """ # すべての母点のボロノイ領域を有界にするために,ダミー母点を3個追加 gn_pnts = np.concatenate([pnts, np.array([[100, 100], [100, -100], [-100, 0]])]) # ボロノイ図の計算 vor = Voronoi(gn_pnts) # 分割する領域をPolygonに bnd_poly = Polygon(bnd) # 各ボロノイ領域をしまうリスト vor_polys = [] # ダミー以外の母点についての繰り返し for i in range(len(gn_pnts) - 3): # 閉空間を考慮しないボロノイ領域 vor_poly = [vor.vertices[v] for v in vor.regions[vor.point_region[i]]] # 分割する領域をボロノイ領域の共通部分を計算 i_cell = bnd_poly.intersection(Polygon(vor_poly)) # 閉空間を考慮したボロノイ領域の頂点座標を格納 vor_polys.append(list(i_cell.exterior.coords[:-1])) # ボロノイ図の描画 fig = plt.figure(figsize=(7, 6)) ax = fig.add_subplot(111) # 母点 ax.scatter(pnts[:,0], pnts[:,1]) # ボロノイ領域 poly_vor = PolyCollection(vor_polys, edgecolor="black", facecolors="None", linewidth = 1.0) ax.add_collection(poly_vor) xmin = np.min(bnd[:,0]) xmax = np.max(bnd[:,0]) ymin = np.min(bnd[:,1]) ymax = np.max(bnd[:,1]) ax.set_xlim(xmin-0.1, xmax+0.1) ax.set_ylim(ymin-0.1, ymax+0.1) ax.set_aspect('equal') plt.show() return vor_polys |
划分单位平方
使用上述功能划分单位平方给出以下内容。
1 2 3 4 5 6 7 8 9 10 | # ボロノイ分割する領域 bnd = np.array([[0, 0], [1, 0], [1, 1], [0, 1]]) # 母点の個数 n = 30 # 母点座標 pnts = np.random.rand(n, 2) # ボロノイ図の計算?描画 vor_polys = bounded_voronoi(bnd, pnts) |
划分一般的凸多边形
不是正方形的一般凸多边形可以用相同的方式划分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | from scipy.spatial import ConvexHull def points_in_convex_polygon(bnd, n): """ 凸多角形の内部にn個の点をランダムに発生させる関数. """ #領域の境界を表す行列の作成 bndhull = ConvexHull(bnd) bndTmp = bndhull.equations bndMat = np.matrix(bndTmp) Abnd = np.array(bndMat[:,0:2]) bbnd = np.array(bndMat[:,2]) # 領域を囲む長方形 xmin = np.min(bnd[:,0]) xmax = np.max(bnd[:,0]) ymin = np.min(bnd[:,1]) ymax = np.max(bnd[:,1]) # 繰り返し用 i = 0 pnts = [] while i < n: # 点を生成 pnt = np.random.rand(2) pnt[0] = xmin + (xmax - xmin) * pnt[0] pnt[1] = ymin + (ymax - ymin) * pnt[1] # 点が凸多角形内にあれば if (np.round(np.dot(Abnd,pnt.transpose()),7) <= np.round(-bbnd.transpose(),7)).all(): pnts.append(pnt.tolist()) i += 1 return np.array(pnts) # ボロノイ分割する領域 bnd = np.array([[0.1,0.4],[0.3,0.2],[0.8,0.3],[0.9,0.6],[0.7,0.7],[0.4,0.7],[0.2,0.6]]) # 母点の個数 n = 10 # 母点座標 pnts = points_in_convex_polygon(bnd, n) # ボロノイ図の計算?描画 vor_polys = bounded_voronoi(bnd, pnts) |