#はじめに
ボロノイ図の面積を求めたかったのですが、面積まで求めている記事が見つからず苦労したのでメモ程度に書き残したいと思います。
コード
早速コードを載せます。
def voronoi_area(points):
v = Voronoi(points)
vol = np.zeros(v.npoints)
for i, reg_num in enumerate(v.point_region):
indices = v.regions[reg_num]
if -1 in indices:
vol[i] = np.inf
else:
vol[i] = ConvexHull(v.vertices[indices]).volume
return vol
sample_points = [[-2, 6], [ 3, -8], [ 5, 9], [ 4, 5], [-7, 2], [ 3, 4]]
voronoi_area(sample_points)
# >>> [inf, inf, inf, 205.92126984, inf, 52.62380952]
ボロノイ図の面積ではどうしても無限大になってしまう部分があるので、そこはnp.infと出力するようにしています。無限大になってしまうのを防ぎたい場合はミラーリングをすると良いと思います。スポーツ選手のボロノイ図の面積を求める時などに必要だと思うので以下に載せます。
def voronoi_volumes(points, x_max, y_max):
points_len = np.shape(points)[0]
points1 = points.copy()
points1[:,1] = - points[:,1]
points2 = points.copy()
points2[:,1] = 2 * y_max - points[:,1]
points3 = points.copy()
points3[:,0] = - points[:,0]
points4 = points.copy()
points4[:,0] = 2 * x_max - points[:,0]
points = np.concatenate((points, points1, points2, points3, points4), axis=0)
v = Voronoi(points)
vol = np.zeros(v.npoints)
for i, reg_num in enumerate(v.point_region):
indices = v.regions[reg_num]
vol[i] = ConvexHull(v.vertices[indices]).volume
return vol[:points_len]
x_maxにはX軸の最大値を、y_maxにはY軸の最大値を入れます。
終わりに
スポーツの分析などをする際にボロノイ図は多用すると思うので、ぜひ使っていただければと思います。