三。其他:
1.矢量的概念:
如果一条线段的端点是有次序之分的,我们把这种线段成为有向线段(directed
segment)。如果有向线段p1p2的起点p1在坐标原点,我们可以把它称为矢量(vector)p2。
2.矢量加减法:
设二维矢量P = ( x1, y1 ),Q = ( x2 , y2 ),则矢量加法定义为: P + Q = ( x1 + x2 , y1 + y2 ),同样的,
矢量减法定义为: P - Q = ( x1 - x2 , y1 - y2 )。
显然有性质 P + Q = Q + P,P - Q = - ( Q - P )。
3.矢量叉积:
计算矢量叉积是与直线和线段相关算法的核心部分。设矢量P = ( x1, y1 ),Q = ( x2, y2 ),
则矢量叉积定义为由(0,0)、p1、p2和p1+p2所组成的平行四边形的带符号的面
积,即:P × Q = x1*y2 - x2*y1,其结果是一个标量。显然有性质 P × Q = - ( Q × P ) 和
P × ( - Q ) = - ( P × Q )。一般在不加说明的情况下,本文下述算法中
所有的点都看作矢量,两点的加减法就是矢量相加减,而点的乘法则看作矢量叉积。
叉积的一个非常重要性质是可以通过它的符号判断两矢量相互之间的顺逆时针关系:
若 P × Q > 0 , 则P在Q的顺时针方向。
若 P × Q < 0 , 则P在Q的逆时针方向。
若 P × Q = 0 , 则P与Q共线,但可能同向也可能反向。
30. 凸包的概念:
点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上
或者在其内。下图中由红色线段表示的多边形就是点集Q={p0,p1,...p12}的凸包。
31. 凸包的求法:
现在已经证明了凸包算法的时间复杂度下界是O(n*logn),但是当凸包的顶点数h也被
考虑进去的话,Krikpatrick和Seidel的剪枝搜索算法可以达到O(n*logh),在渐进意义下
达到最优。最常用的凸包算法是Graham扫描法和Jarvis步进法。本文只简单介绍一下
Graham扫描法,其正确性的证明和Jarvis步进法的过程大家可以参考《算法导论》。
对于一个有三个或以上点的点集Q,Graham扫描法的过程如下:
令p0为Q中Y-X坐标排序下最小的点
设<p1,p2,...pm>为对其余点按以p0为中心的极角逆时针排序所得的点集(如果有多
个点有相同的极角,除了距p0最远的点外全部移除
压p0进栈S
压p1进栈S
压p2进栈S
for i ← 3 to m
do while 由S的栈顶元素的下一个元素、S的栈顶元素以及pi构成的折线段不拐向
左侧
对S弹栈
压pi进栈S
return S;
此过程执行后,栈S由底至顶的元素就是Q的凸包顶点按逆时针排列的点序列。需要注
意的是,我们对点按极角逆时针排序时,并不需要真正求出极角,只需要求出任意两点的
次序就可以了。而这个步骤可以用前述的矢量叉积性质实现。
四、结语
尽管人类对几何学的研究从古代起便没有中断过,但是具体到借助计算机来解决几何
问题的研究,还只是停留在一个初级阶段,无论从应用领域还是发展前景来看,计算几何
学都值得我们认真学习、加以运用,希望这篇文章能带你走进这个丰富多彩的世界。