4
6

More than 3 years have passed since last update.

ボロノイ図の面積の求め方

Posted at

はじめに

 ボロノイ図の面積を求めたかったのですが、面積まで求めている記事が見つからず苦労したのでメモ程度に書き残したいと思います。

コード

 早速コードを載せます。


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軸の最大値を入れます。

終わりに

 スポーツの分析などをする際にボロノイ図は多用すると思うので、ぜひ使っていただければと思います。

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6