
上QQ阅读APP看书,第一时间看更新
3.10.2 凸包
所谓凸包是指N维空间中的一个区域,该区域中任意两点之间的线段都完全被包含在该区域之中,二维平面上的凸多边形就是典型的凸包。ConvexHull可以快速计算包含N维空间中点的集合的最小凸包。下面先看一个二维的例子:points2d是一组二维平面上的随机点,ch2d是这些点的凸包对象。ConvexHull.simplices是凸包的每条边线的两个顶点在points2d中的下标,由于它的形状为(5, 2),因此凸包由5条线段构成。对于二维的情况,ConvexHull.vertices是凸多边形的每个顶点在points2d中的下标,按逆时针方向的顺序排列。
np.random.seed(42) points2d = np.random.rand(10, 2) ch2d = spatial.ConvexHull(points2d) ch2d.simplices ch2d.vertices -------------- --------------- [[2, 5], [5, 2, 6, 1, 0] [2, 6], [0, 5], [1, 6], [1, 0]]
使用matplotlib中的Polygon对象可以绘制如图3-59所示的多边形。

图3-59 二维平面上的凸包
poly = pl.Polygon(points2d[ch2d.vertices], fill=None, lw=2, color="r", alpha=0.5) ax = pl.subplot(aspect="equal") pl.plot(points2d[:, 0], points2d[:, 1], "go") for i, pos in enumerate(points2d): pl.text(pos[0], pos[1], str(i), color="blue") ax.add_artist(poly)
三维空间中的凸包是一个凸多面体,每个面都是一个三角形。在下面的例子中,由simplices的形状可知,所得到的凸包由38个三角形面构成:
np.random.seed(42) points3d = np.random.rand(40, 3) ch3d = spatial.ConvexHull(points3d) ch3d.simplices.shape (38, 3)
下面的程序用TVTK直观地显示凸包,图3-60中所有的绿色圆球表示points3d中的点,由红色线段构成的三角形面表示凸多面体上的面。没有和红色线段相连的点就是凸包之内的点:

图3-60 三维空间中的凸包
from scpy2 import vtk_convexhull, vtk_scene, vtk_scene_to_array actors = vtk_convexhull(ch3d) scene = vtk_scene(actors, viewangle=22) %array_image vtk_scene_to_array(scene) scene.close()
如果读者希望采用三维交互界面,可以在Notebook中执行如下代码:
%gui qt from scpy2 import ivtk_scene ivtk_scene(actors)