Voronoi图Word文件下载.docx
- 文档编号:16424252
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:15
- 大小:1.16MB
Voronoi图Word文件下载.docx
《Voronoi图Word文件下载.docx》由会员分享,可在线阅读,更多相关《Voronoi图Word文件下载.docx(15页珍藏版)》请在冰豆网上搜索。
h(p,q)当且仅当dist(r,p)<
dist(r,q)。
据此,可以得出如下观察结论:
V(pi)
=
∩
h(pi,pj),
1≤j≤n,j≠i
也就是说,V(pi)是(n-1)张半平面的公共交集;
它也是一个(不见得有界的)开的凸多边形(convexpolygon)子区域.
很显然,Voronoi顶点到相邻的三个site距离相等;
Voronoi边上任意一点到相邻的两个site距离相等;
对于任何点q,我们将以q为中心、内部不含P中任何基点的最大圆,称作q关于P的最大空圆(largest
emptycircle),记作Cp(q)。
以下定理指出了Voronoi图的顶点及边所具有的特征:
对于任一点集P所对应的Voronoi图Vor(P),下列命题成立:
1)点q是Vor(P)的一个顶点,当且仅当在其最大空圆Cp(q)的边界上,至少有三个基点;
(Voronoi顶点是三个site的外接圆的圆心)
2)pi和pj之间的平分线确定了Vor(P)的一条边,当且仅当在这条线上存在一个点q,Cp(q)的边界经过pi和pj,但不经过其它站点。
构造Voronoi图
构造Voronoi图有四种算法:
定义法(IntersectofHalfplanes)、增量(incremental)算法、分治法、planesweep算法;
1、planesweep(平面扫描)算法又名Fortune算法,它主要由两部分组成:
sweepline(扫描线)和beachline(海滩线);
Fortune算法建立在点、线之间的距离关系上,如下图所示,平面上任意一点到一个点p的距离与到一条直线l的距离相等,这样的点有很多,它们构成的轨迹就是抛物线,点p就是抛物线的焦点,直线l就是抛物线的准线;
2、回到Fortune算法,这个固定点p就是一个site,l就是sweepline;
sweepline自上而下扫描,平面区域任何点到site与sweepline距离相等的点构成一条抛物线(site就是抛物线的焦点),则n个site的抛物线相交的若干段抛物线弧构成beachline,如下图的蓝色抛物线弧集合;
抛物线之间的交点称为断点(breakpoint),每个断点都落在某条Voronoi边上。
这并非巧合,随着扫描线自上而下扫过整个平面,所有断点的轨迹合起来恰好就是待构造的Voronoi图;
(几何证明:
断点到相邻的两个site距离总是相等,这个关系随着sweepline的扫描一直不变,则断点的运动轨迹就是这两个site的垂直平分线,也即Voronoi边,两条Voronoi边相交又产生Voronoi顶点)
beachline上方的Voronoi顶点和Voronoi边已确定,将不会再变化。
beachline(曲线)和它上方的直线构成当前的Voronoi边,最后随着sweepline的移动而beachline也在不断下移,变为最终的Voronoi边;
(海滩线沿x方向单调——即,它与任一垂线相交而且仅相交于一点。
)
beachline属性
1、随着sweepline下降,breakpoints跟踪Voronoi边;
一个新的breakpoint(新弧形成或者两个breakpoint融合为一体)产生一条新的边;
2、两个breakpoint相遇产生voronoi顶点
3、为了确定Voronoi边和Voronoi顶点,我们需要维护beachline这个结构,但是随着l的运动它会持续不断地更新。
那么,应该如何表示beachline结构呢?
所谓beachline的组合结构发生变化,指的是其上出现了新的抛物线弧,或原有的某段抛物线弧收缩成一个点并进而消失。
在这个算法中,产生新弧,称为siteevent;
旧弧消失,称为circleevent。
两类事件siteevent和circleevent:
1)、siteevent
sweepline扫到某个site,设为p,在此瞬间,站点p对应于一条宽度为零的退化抛物线——亦即,将该新站点p与扫描线l联接起来的垂直线段。
随着扫描线继续下移,这个宽度为0的抛物线将逐渐伸展开来。
siteevent发生后引起的变化:
因为沿海滩线上各个断点的运动轨迹,就勾勒出了Voronoi图的各边。
所以每发生一次site事件,就会生成两个新的断点,此后它们会逐渐地勾勒出同一条新边。
那为什么是同一条新边呢?
实际上,在刚刚诞生的那一瞬间,这两个断点相互重合,然后才会各自朝相反的方向运动,而且它们所勾勒的都是同一条边(同breakpoint定义处的几何证明)。
在一开始,这条边与Voronoi图位于扫描线之上的其它部分并不相联。
随着这条边的不断生长,直到后来它们与其它边相遇,此时它才会与Voronoi图的其它部分联接起来。
定理:
只有在发生某个site事件时,海滩线上才会有新的弧出现。
2)、circleevent
发生于原有的某段弧收缩为一点并即将消失时,假设三段连续的弧α、α'
和α'
'
,这三段弧必然分别对应于三个不同基点pi、pj和pk,就在α'
即将消失的那一刻,这三个基点所对应的抛物线将相交于同一点q。
此时点q到扫描线l与到这三个基点等距离。
亦即,存在一个以q为中心、穿过pi、pj和pk的圆,且该圆在最低点处与l相切。
该圆的内部不可能有任何基点——否则,q到该基点将比到l更近,而这却与“q位于海滩线上”的事实不合。
因此,点q必是Voronoi图的一个顶点。
若海滩线上有某段弧消失,并因而有两段弧汇合起来,则相应地在Voronoi图中肯定也会有两条边汇合起来(成为一条新的边)。
海滩线上依次首尾相联的任何三段弧,其对应的三个基点都会确定一个外接圆;
当扫描线触及某个这类外接圆的最低点时,也就发生了一次圆事件(circleevent)
海滩线上已有的弧,只有在经过某次圆事件之后,才有可能消失。
简单点说,siteevent发生时,beachline会产生一条新弧,同时就会有一条新边出现并朝两端生长,慢慢形成新的Voronoi边;
circleevent发生时,会有两条正在生长的Voronoi边汇合起来,并在接合处形成一个Voronoi顶点,同时中间的旧弧消失。
4、异常情况
afalsealarm:
Wemayhavestoredacircleeventintheeventlist,butitmay
bethatitneverhappens
Therearetworeasonsforfalsealarms:
siteeventsandother
circleevents
我们存储了circleevent,但它可能永远不会发生,真是一个美丽的错误...在siteevent和circleevent发生时,都会有可能误报情况。
1)、siteevent:
circleevent发生时产生的最大空心圆内部还有其他site。
如下面三个图例,p2、p3、p4组成的外接圆,确定了一个circleevent,外接圆y坐标最小的点(图中最低的小红点)将进入PQ,但是在sweepline碰到它之前,先扫描到了sitep7,这样一来将产生新弧,破坏了原来的<
p2,p3,p4>
三元组。
发生circleevent时,并不知道这是一个falsealarm,所以直到碰到该外接圆内部存在site。
这时需要把这个circleevent去掉,也即删除原先进入PQ中的最低点。
也说明了这个外接圆的圆心不是Voronoi顶点,属于误报。
2)、circleevent:
该事件还没有来得及真正发生,这一邻接弧三元组就已经消失了。
如下面三个图例,<
三元组先产生外接圆,第一个小红点进入PQ,当sweepline扫描到p1时,<
p1,p2,p3>
三元组也产生外接圆,第二个小红点进入PQ;
但是,当sweepline扫描到第一个小红点时,它从PQ出队,随着sweepline下移,α3消失,<
α2,α3,α4>
合并为<
α2,α4>
破坏了原来的三元组,则<
无法形成Voronoi顶点,也即这个circleevent属于误报。
需要删除PQ中第二个小红点。
图像说明:
bayanbox.ir/id/3367913281004602743?
download
http:
//www.cise.ufl.edu/~sitharam/COURSES/CG/kreveldmorevoronoi.pdf
相关数据结构
构建Voronoi图需要三个数据结构,分别是平衡二叉树AVL,优先队列PQ和双向边链表DCEL。
1、beachline数据结构AVL:
记录beachline的状态,包括breakpoints,andthearcscurrentlyonbeachline
一个叶子结点表示一段弧,因为每个弧都一一对应一个site,所以用sitenumber来存储;
非叶子结点则表示两条弧的交点即断点,用两条弧对应的site对存储;
因为弧和断点都是不断变化的,所以都用固定的sitenumber来表示。
此例中AVL中的p1、p2表示原图的sitep1和sitep2对应的弧,<
p1,p2>
表示两弧的交点即断点,其实AVL树就是site和breakpoint的中序遍历。
若按照这样的方式来表示beachline,每遇到一个新的site,都可以在O(logn)时间内,沿beachline找出位于该site上方的那段弧:
在查找过程中,在每个内部节点处,只要将其对应断点的x坐标,与新site的x坐标做一比较。
为了处理falsealarm的第二种情况,T的一片叶子若对应于某段弧α,则为它配备一个指针,指向PQ中的一个(事件)节点——具体说,就是(在将来可能)导致α消失的那个圆事件所对应的节点。
若没有导致α消失的圆事件,或者还没有发现这样一个事件,则该指针被置为nil。
最后,每个内部节点v也配有一个指针,指向与当前Voronoi图对应的双向链接边表DCEL中的某条半边(half-edge)——更确切地说,此时与v相对应的断点,正在勾勒出的一条Voronoi边,而v的指针就指向这条边所对应的那条半边。
处理:
新的site产生一条新弧,对应的旧弧被删除(DS中对应AVL某叶子节点被删除);
同时,该旧弧指向的event也将被删除(DS对应PQ中删除一个元素);
添加弧操作:
replacingtheleafwithasub-tree
删除弧操作:
deletingaleaffromthetree
2、事件队列PQ:
Eventqueue(ondecreasingy-coordinate)
记录扫描线当前状态的结构。
存储已确定即将发生的events。
对于siteevent,在sweepline开始扫描之前就可以全部送入PQ;
对于circleevent,
不仅要记录该外接圆的最低点(外接圆与sweepline的切点),还要设置一个指针指向AVL中的某片叶子——这片叶子所对应的,就是在该事件发生时即将随之消失的那段弧。
如果某三个site形成的外接圆,该圆对应的纵坐标最小的点(即未来的切点)在sweepline的下面,则为circleevent;
并将该点入优先队列;
并且这三个连续的sites与该切点互相链接对方。
对于falsealarm的第一种情况还需处理。
sweepline扫描到切点,三条弧变成两条弧,形成Voronoi顶点;
删除三条弧中间的那条,对应DS则为删除叶子节点,并在PQ中删除该节点指向的event(若有,即为一个falsealarm),同时将合并后的两条弧分别与原先三条弧的左右两侧各一条弧结合,形成两个新的三元组,将两新三元组对应的两切点加入PQ,并做指针链接;
3、双向边链表(DCEL):
记录Voronoi状态,包含half-edges,edges(一对half-edge),verticesandcell
records(Achainofcounter-clockwise
half-edges)
Attheleavesofthetree,apointertothecircleeventisstored,ifthearcdefinesacircleevent.Ifnot,pointerissettoNULL.Bymaintainingthispointer,wedonothavetoperformanysearchafterencounteringfalseevents.
算法伪码
算法VORONOIDIAGRAM(P)
输入:
平面点集P:
={p1,…,pn)
输出:
以双向链接边表D表示的(限制在一个足够大的包围框之内的)Voronoi图Vor(P)
1.初始化事件队列Q:
将所有的基点事件插入其中
初始化状态结构T:
将其置空
初始化双向链接边表D:
2.
while(Q非空)
3.
do将y-坐标最大的事件从Q中取出
4.
if
(这是一个发生于基点pi处的基点事件)
5.
thenHANDLESITEEVENT(pi)
6.
elseHANDLECIRCLEEVENT(γ)
(*这里的γ是T的一匹叶子,它对应于那段即将消失的弧*)
7.(*仍然存在于T中的那些内部节点,对应于Voronoi图的单向无穷边*)
计算出一个包围框,其尺寸之大,应足以容下Voronoi图中的所有顶点
通过对双向链接边表的适当调整,将这些单向无穷边都联接到这个包围框上
8.遍历双向链接边表中的所有半边增加相应的单元记录
设置好指向这些单元的指针,以及由这些单元发出的(指向对应各边的)指针
处理两类事件的子程序分别如下:
算法HANDLESITEEVENT(pi)
算法HANDLECIRCLEEVENT(γ)
1.将(对应于即将消失的弧α的那匹)叶子γ,从T删除掉
检查相关的内部节点,更新其中表示有关断点的基点对信息
若有必要,须对T做调整,以使之重新平衡
在Q中,删除所有与α相关的圆事件
(*在T中,γ的前驱与后继节点配有相应的指针*)
(*借助这些指针,就可以找出这些事件*)
(α在其中居中的那个圆事件,此刻正在接受处理,并已经从Q被删除掉了)
2.更新存储当前Voronoi图的双向链接边表D:
对应于该事件的圆心生成一个Voronoi顶点记录,并将该记录插入双向链接边表;
对应于海滩线上新生出的断点,并生成两个半边记录,正确地设置好它们相互之间的指针;
将这三个新记录,与同样终止于该Voronoi顶点的其它半边链接起来
3.(*此前与α紧邻于左侧的那段弧,现可能在某个新的邻接弧三元组中居中*)
检查该邻接弧三元组所对应的两个断点是否汇合为一点
果真如此,则
将对应的圆事件插入到事件队列Q中,并
在Q中该节点和T中与之对应的节点之间设置指针,使它们相互指向对方
(*
此前与α紧邻于右侧的那段弧,现也可能在某个新的邻接弧三元组中居中*)
对该弧,做类似的处理。
算法复杂度
给定由平面上任意n个基点构成的一个集合,其对应的Voronoi图可以采用扫描线算法,在O(nlogn)时间内、使用O(n)空间构造出来。
因为Voronoi图可以归约为n个实数的排序问题,则最好时间复杂度为O(nlogn),即sweepline算法是最优的。
定义法:
O(n^2logn),增量算法:
O(n^2),分治法:
O(nlogn),sweepline算法:
O(nlogn)。
参考
sweepline作者主页:
//ect.bell-
数据结构说明:
//www.cescg.org/CESCG99/RCuk/
可视化界面演示:
//www.in.tum.de/fileadmin/user_upload/Lehrstuehle/Lehrstuhl_XV/Teaching/Applets/applets/vis/voronoi/Fortune.html
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Voronoi