Voronoi图(四):抛物线的妙用
1. 抛物线与海滩线
在上一节,我们已经了解了Voronoi图大致的构造思路:还是基于平面扫描线策略,但是需要引入抛物线来计算Voronoi Edge和Vertex,也就是上一节视频例子中所提到的海滩线(Beach Line,位于扫描线前进方向的后方)。接下来我们就来详解一下如何通过引入抛物线和海滩线,来完成Voronoi图的构建。
首先,先来看看海滩线的构成,它其实是由数条抛物线构成的,而这些抛物线是由Site和扫描线所确定的。什么意思呢?我们知道一个Site和扫描线就能确定一条抛物线,所以我们遵循以下原则:
- 我们规定算法使用的抛物线开口向上,即其方程为:x^2=2py(p>0);Site为抛物线的焦点(Focus),扫描线为抛物线的准线(Directrix)。这也说明算法是从上往下进行扫描;
- 扫描线在Site上方,则该Site确定的抛物线不存在;
- 扫描线刚好落在Site上,我们认为该Site确定的抛物线是一条无限向上的垂直线,并且这条垂直线经过该Site。注意这里严格按照抛物线的定义,这种情况是没有抛物线的,即算不出该条抛物线的方程式。
- 扫描线在Site下方,我们能得到该Site和扫描线所确定的抛物线;
依据上述原则,某个Site所确定的抛物线的变化过程如下图所示:
那么海滩线我们也能很好地理解了:
海滩线就是由数条抛物线(由Site和扫描线所确定的)取并集后,而形成的一条曲线。
还是不能理解的童鞋,可以看看下面的例子:
我们可以看到,三个Site分别对应正下方三条抛物线,把它们取并集之后,我们会得到一条由4条Arc组成的海滩线。并且大家注意下,arc1和arc3属于s2抛物线的一部分,arc2属于s3的抛物线,arc4属于s1的抛物线。而且通过引入海滩线,我们把整个平面分成了三个部分,除了之前定义的固定区域和待处理区域,大家能发现新增加的区域是哪里嘛?
没错,新增加的区域就位于海滩线和扫描线之间,这个区域笔者称之为”待定区域(Area to be determined)“,因为处于该区域的结构会发生改变,即这个区域还可能生成新的Voronoi Vertex。这里就是一般的平面扫描算法和Voronoi图的平面扫描算法的主要区别之一。下图展示了由海滩线和扫描线界定的三个区域:
讲解到这里,不知道大家发现抛物线究竟是如何”描绘“出Voronoi图了么?没错哒!随着扫描线不断向下移动,由不同抛物线之间的交点移动的轨迹就是我们所需要的Voronoi Edge,并且当数条Voronoi Edge汇集到一点时,自然而然地就形成了一个Voronoi Vertex,是不是感觉非常的神奇呀?还是上面的例子:
大家可以看到,arc1与arc2交于C点,arc2与arc3交于B点,arc3与arc4交于A点,并且随着扫描线不断向下移动,C会沿着直线CD向D点移动,B会沿着直线CD的反向移动,而A会沿着直线FA向下方移动,而且最终B和A会交汇于一个Voronoi Vertex,这个Vertex也是三个Site所确定圆的圆心。
那么我们也能大致总结出构造Voronoi图的思路:
- 从上往下依次扫描Site;
- Site和扫描线能确定一条抛物线;
- 数条抛物线取并集会形成一段段的Arcs,这些Arcs所组成的就是海滩线;
- 不同Arcs交点的移动轨迹就确定了Voronoi Edge,这些交点也是相应抛物线的交点;
- 数条Voronoi Edge交汇的地方就是Voronoi Vertex;
那么接下来的问题自然而然地就是:何时需要引入一条新的抛物线?何时数条抛物线的交点会汇集到一点呢?我们把这两个问题的答案留到下一节吧~ 中场休息时间哒~
现在在捣鼓个人网站,暂时没有时间更新Voronoi图的文章,大家有兴趣可以先看看代码:1.1.6 Voronoi Diagrams。有什么问题可以随时联系我哒~
下一节:Voronoi图(五):两个事件
系列汇总:塞尔达和计算几何 | Voronoi图详解文章汇总(含代码)
2. 参考资料
- Computational Geometry: Algorithms and Applications
- 计算几何 ⎯⎯ 算法与应用, 邓俊辉译,清华大学出版社
- 计算几何 | Computational Geometry
3. 免责声明
※ 本文之中如有错误和不准确的地方,欢迎大家指正哒~
※ 此项目仅用于学习交流,请不要用于任何形式的商用用途,谢谢呢;