基于CGAL的Centroidal Voronoi Tessellation(CVT)算法实现以及可视化

之前我们已经介绍了基于CGAL的Voronoi图实现。链接:https://blog.csdn.net/aliexken/article/details/106462597

今天我们在该项目的基础上,来介绍一下Centroidal Voronoi Tessellation(CVT)算法实现及其可视化。

我们知道,Voronoi图能够按照原始点所在的位置,将空间划分成不同的区域。如果该区域被限制在一个有限的域中(如一个正方形),那么这些划分的区域全部都是封闭区域。与之对应的,我们能够将所有的边求对偶,得到一个三角刨分,如下图所示:

这种对有限区域的划分是按照输入的点的位置进行的,得到的Voronoi面片是不规则的,每个面片的形状与面积都有较大差距,且对应的三角化也不好(钝角三角形过多,不满足空圆条件)。是否可以通过对这些原始点的位置进行优化,来得到一个Voronoi面片更一致,三角化结果更好的结果呢?这就是Centroidal Voronoi Tessellation算法的基本问题。

一个经典的方法是使用Lloyd's Relaxation: https://www.jasondavies.com/lloyd/ (网站有一个直观的动态图片,非常好看)。截取两个图片来说明结果。

左图是一个相对初始的状态,大量的点集中在中心区域,面片的面积由中心向四周呈现扩散的过程。当通过Lloyd迭代计算(800次),可以看到右图的面片更加趋于一致,包括面积和形状。

这个过程可以简单理解为通过重新计算每一个面片的中点来完成对原始点的更新,所以被称作"Centroidal" 。维基百科有非常详尽的解释:https://en.wikipedia.org/wiki/Lloyd's_algorithm

按照更新的方法,我们对第一开始给出的Voronoi图进行CVT计算,得到如下结果:

这里,我们使用一个面片的端点求平均,来更更新原始点,结果发现更新次数超过10次后,就稳定在如上图的状态,不在更新。出现这种错误的原因是,对于每个面片的端点,其权重是不同的,不能通过单纯的求平均来更新,这样结果就会陷入到一个局部最优。

按照Lloyd's Relaxation的具体更新方法,引入三角面积权重与三角中心加权优化,这样得到以下结果:

Iteration 10:

Iteration 100:

将区域放大,得到的结果:

Iteration 10:

Iteration 100:

这里不再给出实现代码,基于之前Voronoi图的代码能够很方便的实现CVT算法。

参考文献:

维基百科,https://en.wikipedia.org/wiki/Lloyd's_algorithm#Convergence

Q. Du et al. Centroidal Voronoi Tessellations: Applications and Algorithms, 1999.

D. Yan et al. Isotropic Remeshing with Fast and Exact Computation of Restricted Voronoi Diagram, 2009

 

Guess you like

Origin blog.csdn.net/aliexken/article/details/106555993