老师讲的是定义法,但是大部分博客里面都用的是扫描线法。
参考博客:http://www.cnblogs.com/Seiyagoo/p/3339886.html
这篇博客里面已经将的很清楚了,现在大概的小结一些。
首先,对于event队列里面,用到的是一个平衡二叉树的数据结构,这样数据的删除和查找可以在logn的时间内完成。而event里面存放的是两种结点,一个基本点,就是所有的初始点集,称它们为site事件点,第二个是circle事件点,当到达这个点的时候,三条弧会退化成两条,这个点是三个event结点的外接圆的最低y坐标点。所以存放在event里面的key值按照y坐标的优先顺序存放。
对于tree里面,就存放的是抛物线的信息。抛物线表示平面内所有到固定点和扫描线距离相等的点的集合,他们组成了一条抛物线。随着扫描线的变化,他们也是时刻变化的,但是,只有当扫描线在event队列里面扫描,抛物线才会出现实质的变化。当扫到site事件点的时候,会增加新的抛物线,也会增加新的断点。此时,该抛物线实际上是退化成了一条线段,两个断点是重合的,当抛物线继续向下扫描的时候,两个断点会逐渐分开,所以,当到达site事件点的时候,会增加两个断点。
当到达circle事件点的时候,这个circle事件点事三个site点的外接圆的最低y坐标点。此时三条抛物线会汇聚在一个点q,此时q点一定是voronoi图的一个顶点。从tree中删除退化掉的抛物线。
几个细节问题:
1.如何查找那条垂线段相交的弧。
因为弧一定在叶子节点,只要通过查找当前的site节点的横坐标,最后总能够找到一个指定的叶子节点,这个叶子节点就是我们要的弧。
2.如何查找邻接弧三元组。
找出以pi为最左端的三元组,找出pi右面的两个右孩子即可。
找出以pi为最右端的三元组,找出pi左边的两个左孩子即可。