Pythonで点のセットの凸包を見つける1つの方法は、でDelaunay
三角測量関数を使用することscipy.spatial
です。ポイントのセットが与えられると、属性を持つオブジェクトを返します。これconvex_hull
は、ポリゴンのエッジに対応する元のポイントのセットへのインデックスのペアで構成される配列です。厄介なことに、これらは順序付けられていないため、これらのポイントを含むポリゴンを再構築する必要があります(たとえば、次のように)。
import numpy as np
import matplotlib.nxutils
import scipy.spatial
def find_convex_hull(points):
triangulation = scipy.spatial.Delaunay(points)
unordered = list(triangulation.convex_hull)
ordered = list(unordered.pop(0))
while len(unordered) > 0:
next = (i for i, seg in enumerate(unordered) if ordered[-1] in seg).next()
ordered += [point for point in unordered.pop(next) if point != ordered[-1]]
return points[ordered]
@ user1443118で提案されているように、のpoints_inside_poly
関数をmatplotlib.nxutils
使用して、凸包に対応する結果のポリゴンに点が存在するかどうかをテストできます。これにより、交差度を計算するための次の関数が得られます。
def inclusion(points_a, points_b):
ch_a = find_convex_hull(points_a)
return (1.0 * matplotlib.nxutils.points_inside_poly(points_b, ch_a)).mean()
したがって、以下に示すように、いくつかのポイントのセット(元の例のようなプロパティを使用)が与えられます。
A = np.random.randn(100, 2)
B = np.array([2,0]) + 0.5 * np.random.randn(100, 2)
C = 0.5 * np.random.randn(100, 2)
D = np.array([5,0]) + 0.5 * np.random.randn(100, 2)
包含度は次のように計算できます。
>>> inclusion(A, B)
0.44
>>> inclusion(A, C)
1.0
>>> inclusion(A, D)
0.0
points_in_poly
ただし、最後に、関数が必ずしもポリゴン境界上のポイントを内側にあるとは限らないことに注意してください(基になる関数がこのように動作する理由については、ここを参照してください)。このため、元の例のセットCは、点(1,5)がAの凸包上にあり、カウントされないため、部分的にのみ含まれます。