CGAL使用心得

 

CGAL使用心得

作者:李浩

转载自:http://hi.baidu.com/lihao102/blog/item/a817a1cad3a9a78dc9176810.html

 

首先我说说我研究CGAL的背景,由于,早一阵子,有一个需求,需要求出在一堆二维线中(包括直线和弧线),找出所有的最小区域和最大外包。如下图所示。



在这两个图形中,要快速的找到每一个最小的封闭区域和一个由这些最小封闭区域组成的一个最大封装区域。这样的算法,有,像最常见的建构多边形TOPO,然后用雷达扫描法,可以求出来。但是,这么多的算法开源库,让我下了使用开源库来解决这个问题的决心,很快我就锁定了CGAL这个强大的图形算法库。

很快的我发现,CGAL里的ARRANGEMENT能够实现类似需求的功能,就这样,我开始慢慢的对ARRANGEMENT进行研究。但研究CGAL的应用,不可能不学习CGAL的基本结构。CGAL是一个基于C++模版的算法库(好像很多的C++开源算法库,都是基于模版的)。学习其基础对C++泛型编程的知识有一定的要求。如果你看过候捷的《STL源码剖析》一书,你会更容易的看懂CGAL的代码。

CGAL中的重要基本名词包括核心、域数据类型、TRAITS特性;

核心中的数据存储是用到了域数据类型,而核心中的数据与基本几何数据的提取是通过TRAITS来的。

ARRANGEMENT中定义了点、面、边的概念,每一个最小区域在它里面被描述成面,而组成最小区域的线被描述成边,所有线的交点被描述成点。这样,需求上的概念与ARRANGEMENT中的概念可以匹配上,就证明,可以用这个算法来实现需求。

在慢慢的学习过程中,我发现CGAL是一个对精度要求比效率要求更高的库(这一度让我想放弃CGAL,但后来,发现再差的效率,都比一般的算法求解出来的速度要快),而我们能够提供的数据,精度是达不到的。就拿MF_FLOAT域数据类型来说,它里面真正保存数据是一个std::vector,这样的精度是DOUBLE型不能比的。到现在,我还没有能够非常完美的解决这个问题。精度不够,特别表现在构建弧线时,CGAL preCondition就会通不过,报异常。这样让我很头大。发现是,我们提供的数据,在构建CGAL的弧时,弧的终点不在其支持圆上。想了很多的办法。最后网上有一位牛人告诉我,要重写CGAL的一个DCEL也许能够解决这个问题。DCELdoubly-connected edge list data-structure,这种数据结构的最基本的观点是,将被共边的边,看作是一对方向互逆的边(注意,在这个数据结构中,每条边都是有方向,组成的一个环就是一个面)。我又开始学习CGAL中这一部分的内容 Arr_default_dcel,并且学习着,里面对顶点、面、边、孤点等几何对象的定义。发现,如果真正需要解决精度问题,不仅仅是重写DCEL能够解决的。对核心的部分内容也需要重写,这个工作量太大,代价也大。目前公司肯定是不允许的。更要命的是,公司的需求是,能够在传进去的线段上附加信息,出来后,其线段上的信息要不丢失。一开始,我想,有这个需求,不重写DCEL是不行了。于是,我开始跟踪CGAL构建ARRANGEMENT的过程,发现CGAL中,大部分的赋值操作,都是直接的内存拷贝。并且,不管怎么样,CGAL中真正处理的线类型只可能是X_monotone_curve_2,所以,就算你在开始构建的线段上能够附加上信息,当CGAL内部通过这个线段构建X_monotone_curve_2时,你的信息也会丢失。慢慢的,我发现,出来之后的线段也是X_monotone_curve_2,也就是说,只要你能在构建X_monotone_curve_2时能够将你的信息附加上去,你的信息,就有可能在计算出来之后的结果上,还存在。CGAL将核心中定义的CURVE转换成X_monotone_curve_2的过程是由make_x_objects完成的,所以,我在这里进行了改动,在转换过程中,将附加的值的信息给考虑上了。最终完成了这个需求。现在,又回到了,精度的问题了,把附加信息的问题解决了之后,重写这条路更加是不允许走了,通过CURVE构建的过程,我决定,将原来的构造方法改变,改成三点构造法。然后,在外边,对输入的数据的精度,进行更进一步的处理。最终应该是能完成这个功能。具体的,现在同事还在测试中。

通过对CGAL这一段时间的学习,我发觉,CGAL确实是一个很强大的图形算法库,对数据精度要求相当高,所以处理出来的数据正确率也是相当高的,对于那种对算法处理速度要求特别高的,不推荐用CGAL,但可以用CGAL中的算法的思想。

目前CGAL也有商业化的产品GeometryFactory,客户还是挺多的,像国产CAD的龙头产品(吼得最大,动作最大的产品,哈)ZWCAD,也是其客户。

哈哈,就稍微总结在这里,对CGAL的学习,借用一句广告词——永不止步。


 

你可能感兴趣的:(CGAL)