计算几何 : 凸包学习笔记 --- Graham 扫描法

 凸包

(只针对二维平面内的凸包)

一、定义

简单的说,在一个二维平面内有n个点的集合S,现在要你选择一个点集C,C中的点构成一个凸多边形G,使得S集合的所有点要么在G内,要么在G上,并且保证这个凸多边形的面积最小,我们要求的就是这个C集合。

计算几何 : 凸包学习笔记 ---  Graham 扫描法计算几何 : 凸包学习笔记 ---  Graham 扫描法

二、算法

求凸包的算法很多,常用的有两种:

1.  Graham扫描法,运行时间为O(nlgn)

2.  Jarvis步进法,运行时间为O(nh),h为凸包中的顶点数。

这里主要讨论第一种算法:Graham扫描法

Graham扫描法

基本思想:使用一个栈来对所有点逐一判断,把不符合条件的点筛出去。

操作:输入集合Q中的每一个点都被压入栈一次,非CH(Q)(表示Q的凸包)中的顶点的点最终将被弹出堆栈,当算法终止时,堆栈S中仅包含CH(Q)中的顶点,其顺序为个各顶点在边界上出现的逆时针方向排列的顺序。

首先,找一个凸包上的点,把这个点放到第一个点的位置P0。然后把P1~Pm 按照P0Pi的方向排序,可以用矢量积(叉积)判定。

判定过程:

计算几何 : 凸包学习笔记 ---  Graham 扫描法计算几何 : 凸包学习笔记 ---  Graham 扫描法

做好了预处理后开始对堆栈中的点<p3,p4,...,pm>中的每一个点进行迭代,在第7到8行的while循环把发现不是凸包中的顶点的点从堆栈中移去。(原理:沿逆时针方向通过凸包时,在每个顶点处应该向左转。因此,while循环每次发现在一个顶点处没有向左转时,就把该顶点从堆栈中弹出。)当算法向点pi推进、在已经弹出所有非左转的顶点后,就把pi压入堆栈中。

整个算法过程如图所示:

计算几何 : 凸包学习笔记 ---  Graham 扫描法

计算几何 : 凸包学习笔记 ---  Graham 扫描法

 

上一篇:使用Areas分离ASP.NET MVC项目


下一篇:Java8 CompletableFuture 编程