几何算法详解与例题分析

前言

画乃我思所欲,非我见所得。

几何算法常常出现在计算机图形学,大规模集成电路设计等方面,常常需要分析平面内点、线段、直线的关系,而其算法呢大多用到了归纳,分治等算法的思想。

几何算法举例

1.判断点是否在多边形内部

判断p是否在多边形内部?

从p连一条到多边形外部的点的直线

看与所有多边形的边相交几次

若为奇数

则在内部

如何找外部的点?

找一个点x值比多边形的所有点x值都大

 

2.构造多边形

平面内给n个点,怎么构造一个多边形

(1)

造一个圆包含多边形的所有点

然后从圆心绕一圈按顺序连接所有点

这就是个多边形

(2)

选择多边形x,y都最小的那个点

然后整个图就在1,2象限了

这样从角度的小到大连接所有点,就是多边形

 

3.凸包算法

寻找n个点的凸包

(1)

归纳

假设我们可以找到n-1个点的凸包

加入第n点

要么在凸包中,不用操作,

检测是否在凸包中

前面判断点是否在多边形中

O(n)

要么不在凸包中

要拓展凸包

删去原来在边上,现在在里面的点

遍历

支撑线:vn 与 vi  vj 的直线分别于x轴角度是最大和最小

然后删点

T(n) = T(n - 1) + O(n)

O(n*n)

(2)

优化

礼物包裹算法

从一个点一个一个往过包

就像纸包红薯

先折一次,再折

就是第一个点,第二个点

第三个点

1,2向量与2,3向量角度最小

就是凸包

每个点需要与所有点计算角度

O(n * n)

(3)

优化

Graham扫描算法

选最右下角的点a

排序-每个点与a直线与x轴角度大小

从一个点往下找

排序后1,2点入栈

新加入3的与栈顶两元素比较

若向量旋转方向逆

就入栈

若顺

就栈顶元素出栈

循环

3 与栈顶两元素再比

这样排序O(nlogn)

每个点回溯

总回溯不会超过O(n)

总O(nlogn)

 

4.找最近点对

给出平面内的n个点,找出距离最小的点

(1)

暴力搜索

n个点两两计算距离

N*(n-1)/2

(2)

分治

归纳

将原n个点找到x座标最中间的一个,以这个点的竖线分两堆

假设我们已知n/2个点堆中的最小距离

推广的n

左边最小值d1, 右边最小值d2

D= min(d1, d2)

计算竖线两边+-d范围内的点两两最小值

因为外面的不可能有跨界还小于d的

最坏情况

n个点都在中间区域内

。。。

Tn = 2T(n/2) + O(n^2)

还O(n^2)

 

优化

其实每个点找对面界中的点时

只用找[y - d, y + d]的点

有对面界的最小距离为d

将中间区域的点按y排序(O(nlogn))

每个点只会与对面界的最多6个点检查一遍

所以检查时间为常数O(n)

Tn = 2T(n/2) + O(nlogn)

O(n(logn)^2)

 

再优化

增强归纳

我们不但知道n/2堆的最小距离,我们还知道其中点y值的排序

这样求中间的时候就可以直接合并

类似于归并排序

Tn = 2T(n/2) + O(n)

O(nlogn)

 

 

5.求水平线与竖直线的交点

平面内有n条水平线,m条竖直线,求交点

 

(1)

暴力

两两求O(mn)

 

(2)

将所有线端点x值排序

O((m+n)log(m+n))

扫描线

设置一条竖线从平面左边到平面右边

 

(1)是左端点,就入队,表示这条线有产生交点的希望

(2)是右端点,就这条直线出队

(3)是竖线,就与队列中的水平线比较,是否产生交点

 

扫描

检查M+n个点

竖直线的话要检查所有水平点

最坏(m+n)n

优化

维护有希望的水平线以y值排序的堆

这样判断是否相交就用竖直线的两个端点二分查找

O(m+n)logn

 

总结

几何算法的问题我们常常会说这肉眼看看不就出来了吗,但几何算法就是这样,它是让计算机解的方法。设计几何算法时,要注意不要被脑子里的惯式图形所误导,要考虑特殊情况。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章