和二维情形类似,给定三维空间的一些点,包含它们的最小凸多面体称为这些点的凸包。三维凸包的求法有很多,常用的有暴力法,卷包裹法和增量法。
暴力法。枚举每三个点组成的有向三角形(实际对应一个半空间),判断是否所有点都在这个三角形的同侧(即半空间的内部)。如果是,则这个三角形是凸包中的一个面。否则就不是。判断一个点在三角形的那一侧需要一次叉积和一次点积(也可以理解为一次混合积),因此一共需要O(n^4)次叉积和点积。
卷包裹法。该算法的思想是先找到一条肯定在凸包上的边PiPj(比如,投影在平面上的凸包的边),然后想象一张纸紧贴这条边向左(这里是指向量PiPj的左边)旋转,直到碰到一个点Pk,然后以PkPj和PiPk为轴继续旋转。
尽管看上去简单,卷包裹法在实现上仍有一些需要注意的地方。首先是初始边的选择。一般先把点投影到z=0平面,求出二维凸包,然后把二维凸包上的一条边作为三维凸包卷包裹的初始边。根据二维凸包的性质,不必真的左投影和找凸包,而只需找一个y坐标最小的点作为起点,到它极角最小的点作为第二点。看上去很简单,请注意,当y最小和极角最小的选择不止一个时很容易出问题,读者不妨仔细思考(可能选择的边穿过了多面体)。另外,在卷包裹的过程中,多点共面也是比较麻烦的问题(可能会出现找不到下一个顶点的情况,因为可能多次访问)。卷包裹的实现需要十分小心。
增量法。该算法的基本思想是把点依次加到凸包中。初始时随机选两个点p1和p2,然后找一个不和这两个点共线的点p3,再找一个不和它们共面的蒂娜p4