附加说明:
1. CGAL整体概述
CGAL是一个用C++描述的,包含三个主要部分的计算几何算法库.
第一部分是核心组件(Kernel),它包括基本的几何对象以及做用在这些对象上的各种操作.这些对象被实现成使用表现类参数化的独立的类,这样使得核心更具有灵活性和适应性.
第二部分是一系列的基础几何数据结构和算法.它们被特征类参数化.而特征类定义了数据结构或者算法和它们使用的原生类型(primitives)的接口.在很多情况下CGAL中的核心类可以作为这些数据结构或算法的特征类使用.
第三部分是由一些支持设施比如为方便调试设计的迭代器,随即数源,I/O支持以及一些可视化工具等等.这个部分主要介绍核心部分.核心由一些基础对象组成,比如点,向量,方向,直线,射线,线段,三角形,ISO型长方形和四面体.每个部分都有一些对这些对象进行操作的函数.一般有访问函数(比如一个点的坐标),测试点和这个对象的位置关系,得到对象的包围盒子的函数,长度,面积等等.核心中还包含一些基本超作,比如仿射变幻,相交的检测与计算,距离计算.
2. CGAL核心说明
我们学习的对象是d维欧几里德仿射空间.这里我们主要考虑2维和3维得情况.空间中的对象是有点集组成.表示点的一般方法是使用笛卡儿坐标.它假定了一个参照框架(一个原点和d个正交轴).这个框架中一个点是由一个d维的向量表示的(c0,c1,...,cd-1),相应的线性空间中的向量也是如此.每个点都有唯一的笛卡儿坐标与之对应.另一种表示点的方法是齐次坐标.在这个框架中一个点是有一个d+1(h0,h1...,hd)维向量表示的.根据公式ci=hi/hd,对应的点的笛卡儿坐)标(c0,c1,...,cd-1)可以计算出来.注意齐次坐标的点的表示是不唯一的.当λ≠0时,向量(h0,h1,…hd)和向量(λh0, λh1 …, λhd)表示同一个点.如果一个点的笛卡儿坐标是(c0,c1,…,cd-1),它可以表示成(c0,c1,…,cd-1,1)这个齐次坐标.齐次坐标系可实际上可以在一个更一般的空间的中表示对象.这个空间叫射影空间.在CGAL中我们不会进行射影几何的计算.我们使用齐次坐标是为了避免除法运算,而增加的这个坐标是作为公共分母.
2.1 通过参数化实现泛型
几乎所有的核心对象(已经对应的函数)都是由模板来实现的.而模板参数是用用户来选择从而决定核心对象的表现形式.
2.2 笛卡儿坐标系核心
通过Cartesian
Cartesian
2.3 齐次坐标系核心(由于ARRANGMENT的例子都是基于笛卡儿坐标系核心的,所以没有做过多的研究)
齐次坐标系中可以避免除法运算,因为引入的补充坐标可以坐标为公共分母.避免了除法运算对几何计算的精确性相当有利.通过Homogeneous
Homogeneous
2.4 命名约定
使用核心类不仅可以避免出问题,而且使得CGAL类具有一致性.
1. 以大写字母开头的名字表示几何对象,像Point,Segment,Triangle.
2. 下划线加上对象的维度,_2,_3或者_d
3. 核心类型加上参数类型比如Cartesian
2.5 作为特征类的核心组件
CGAL基本库中的算法与数据结构是由一些特征类来参数化的.这些特征类包含了一类对象和上面算法或数据结构的操作和函数的行为一致.基础库中的大部分的算法与数据结构都可以由核心组件作为特征类.一些算法可以根据传入的几何对象的类型进行自动的推导,从而不需要直接指定.有些类还需要更多的参数.有些则不能使用核心组件.
2.6 选择一种核心组件和预定义核心组件
如果你使用整形的笛卡儿坐标,大部分的几何计算将只使用整形数值.特别是在只使用断言计算的时候.例如点集三角化和凸包计算.这些情况下笛卡儿坐标系是第一选择,即使是使用RingNumberType.你可以使用精度受限的int和long,使用double来表示整形,或者任意精度的整形例如GMP整形的包装类GMPZ,lead_integer,或者MP_Float.要注意,除非使用任意精度的环类型,溢出将会产生错误.
如果出现新建点的情况,比如求两条直线的交点,笛卡儿坐标中的计算经常出现除法.因此使用笛卡儿坐标的时候需要FieldNumberType.相对的,转换到齐次坐标的时候也一样.double是一个不精确的FieldNumberType.你可以把任何RingNumberType传给Quotient配接器来得到一个FieldNumberType从而可以在笛卡儿坐标系中进行运算.一般来说使用RingNumberType进行齐次坐标运算是比较合适的.其他一些FieldNumberType有leda_rational和leda_real..
如果可靠性对你来说非常重要,使用经过认定的精确计算的数据类型是比较好的选择.Filtered_kernel提供了一种过滤机制使得核心具有既精确又有效率的断言.仍然还有许多人喜欢使用double,因为他们需要速度,而且可以接受近似的结果,甚至可以忍受时不时由于舍入误差而崩溃的算法.
预定义核心组件
为了使用方便,CGAL预定义3个类型
它们都是笛卡儿坐标系核心
它们都支持从double型来建立笛卡儿坐标系里的点
它们用不同的方式处理建立几何对象的问题
---Exact_predicates_exact_constructions:精确的生成几何对象,提供精确的几何断言
---Exact_predicates_exact_construtions_kernel_with_sqrt:和上面一样,但数值类型提供了精确的开方运算
---Exact_predictates_inexact_constructions_kernel:提供精确断言,但是生成几何对象可能存在舍入误差.这对于大部分的CGAL算法来说已经足够了.而且比前面两种情况要快很多.
这三种预定义核心组件都是基于笛卡儿坐标系核心的,只是其构造的域参数类型不同。
我个人建议,内核用基本的笛卡儿坐标系核心,域参数类型用MF_FLOAT或者DOUBLE类型,因为,这样的效率会比其它,对精度对准确度有要求的域参数类型和内核封装类型(其实也是从笛卡儿坐标系核心派生出来的)快。效率最高的Exact_predictates_inexact_constructions_kernel就是Filtered_kernel