计算机图形学几何工具算法详解 第一章 绪论

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/BDalasja/article/details/86293654

计算机图形学几何工具算法详解 这本书在网上只找到影印版,很多文字都不太清晰,看起来有点儿费劲,故转录成普通文字版。

1.1 如何使用本书

本书包含许多方面的内容。简单地浏览一下目录,就可以知道本书是一本关于二维和三维几何算法的书籍,这些算法可应用于计算机图形学和其他领域。本书各章节的组织方式便于读者找到感兴趣的算法,并使各章节的内容尽可能地互相独立,因此,本书非常适合作为参考书,供经验丰富的业界人士为手头的项目查找特定的算法。

然而,本书不仅仅是一本参考书。仔细地研究本书的内容就会发现,许多用于分析几何问题的概念都是通用的。

例如,考虑计算不同图元对(比如点、线段、三角形、矩形四面体或框)之间的距离这一三维几何问题。每一对图元对之间的距离都可根据有关图元形状的特定知识来分析。分析该问题的常用的统一方法是用不同的参数来表示不同的图元,即零、一、二、三分别表示点、线段、三角形或矩形、四面体或框。位于不同图元上的任意两点之间的距离平方表达式是一个包含适当参数的二次多项式。这两个图元之间的距离平方就是该二次多项式的最小值。搜索该函数的值域,将找到位于不同图元上的最近的两个点所对应的变量值,以及相应的两个图元之间的最小距离平方。

搜索参数域的思想是用于计算两个凸多面体之间距离的GJK距离算法的基础。解决不同问题的通用思想形成了计算机图形学L作者解决新问题必须具备的一组分析工具的实现基础。因此,本书也非常适合作为学习工具,用以帮助相关人员实践计算机图形学科学。而且,我们相信,本书是一本用于计算机图形学几何算法课程的好教材。

有些读者希望,在投入几何算法分析之前,首先掌握理解这种分析所必需的基础数学工具的适当知识。为了满足他们的需要,本书的前三章简要介绍了向量和矩阵代数。

本书的附录包括对三角几何公式的回顾及用于本书算法的许多数值方法的概要。我们的目的是在本书中包含足够的基础知识和先进资料,以使读者能很好地理解所有的算法。然而,实现这些算法需涉及许多的概念,为了完整地理解这些相关的概念,读者可能需要学习其他的资料。比如,有些算法需要求解多项式方程系统。可用多种方法来求解一个系统,有的方法在数值精度上更加适合于特定的算法。我们当然鼓励读者学习尽可能多的相关材料并掌握足够的知识,以解决应用中出现的各种问题。掌握的知识越多,解决实际问题的能力越强。

1.2 关于数值计算的若千问题

我们认为本书能满足许多领域的读者的需求。无论是哪个领域的读者,在计算机编程中都不可避免地面临一个难题,即必须处理浮点数系统中出现的计算问题。当然,总的来说,在试图实现算法之前,必须先充分地理解算法的理论要点。但是仅有理论上的理解是不够的。熟悉浮点数系统的程序员都知道这一点,只有他们才能体会其中的奥妙,他们能找到许多你根本想像不到的方法,来证明你的程序逻辑是根本行不通的。

1.2.1 低层问题

用理论公式来表示儿何算法时,通常采用实数。在浮点系统中编码实现这些算法时,我们将直接面临的一个问题是,并非所有的实数都表现为浮点数。

如果r是一个实数,设 f ( r ) f(r) 为其浮点数表示。在大多数情况下,f 被四舍五入成最接近的浮点数或者被舍去小数部分。无论釆用哪种方法,用 f 表示 r 的绝对误差为 f ( r ) r |f(r) - r| 。其相对误差为 f ( r ) r / r |f(r) - r| / |r| (假设r≠0)。

浮点数的算术运算也会产生数值误差。如果r和s都是实数,它们之间的四则基本运算为:加,r+s ;减,r-s;乘,r×s;除,r/s。假设用由 , , , \oplus, \ominus, \otimes, \oslash 来表示对应的浮点算术运算。则和r+s近似表示为 f ( r ) f ( s ) f(r)\oplus f(s) ,差r-s近似表示为 f ( r ) f ( s ) f(r)\ominus f(s) 等。 浮点数不会保持实数的般算术性质。比如,如果s≠0,则 r + s r r + s \neq r 。但是 f ( r ) + f ( s ) = f ( r ) f(r) + f(s) = f(r) 是可能成立的,特别是当f®在数量上比f(s)大得多时。

实数加法具有结合性和交换性。它与相加数字的次序无关。但是,浮点数加法与相加数字的次序有关。假设已有数字r,s,以及将要与它们相加的t。在实数运算中, ( r + s ) + t = r + ( s + t ) (r+s) + t = r + (s+t) 。在浮点数算术中, ( f ( r ) f ( s ) ) f ( t ) = f ( r ) ( f ( s ) f ( t ) ) (f(r)\oplus f(s) ) \oplus f(t) = f(r)\oplus ( f(s) \oplus f(t)) 却不一定成立。例如,假设f®在数量上比f(s)和f(t)大得多,则有
f ( r ) + f ( s ) = f ( r ) , f ( r ) + f ( t ) = f ( r ) ) f(r) + f(s) = f(r), f(r) + f(t) = f(r)) 。于是有 ( f ( r ) f ( s ) ) f ( t ) = f ( r ) f ( t ) = f ( r ) (f(r)\oplus f(s) ) \oplus f(t) = f(r) \oplus f(t) = f(r) 。但是有可能使 f ( s ) f ( t ) f(s) \oplus f(t) 足够大,使得 f ( r ) ( f ( s ) f ( t ) ) f ( r ) f(r)\oplus ( f(s) \oplus f(t)) \neq f(r) 。这样就产生了违反结合性的例子。

一般地,非负浮点数求和应该按从小到大的顺序进行,以避免大数屏蔽小数

如果 r 1 r n r_1 \cdots r_n 到m是将要相加的数,如果它们的大小次序为 r 1 r n r_1 \leqslant \cdots \leqslant r_n ,则在浮点加法中的相加次序应该为 ( ( f ( r 1 ) f ( r 2 ) ) f ( r 3 ) ) f ( r n ) ((f(r_1) \oplus f(r_2)) \oplus f(r_3)) \oplus \cdots \oplus f(r_n)

其他需要关注的浮点问题是:两个数量几乎相等的数相减,或者除以接近零的数所得的有效数字的消去,这两种情况都将产生不可接受的四舍五入误差。演示纠正这两种误差的方法的一个典型例子,就是求解当 a 0 a \neq 0 时的二次方程 a x 2 + b x + c = 0 ax^2 + bx + c = 0 。其理论根为

x 1 = b + b 2 4 a c 2 a x 2 = b b 2 4 a c 2 a x_1 = \frac{-b + \sqrt{b^2 - 4ac}}{2a} 和 x_2 = \frac{-b - \sqrt{b^2 - 4ac}}{2a}

假设b>0并且 b 2 b^2 在数量上比4ac大得多,则 b 2 4 a c \sqrt{b^2 - 4ac} 将近似等于b,因此x的分子由数量几乎相等的两个数之差决定,这将导致有效数字的损失。注意, x 2 x_2 并不受上述问题的影响,因为它的分子没有数字消去。一种纠正方法是,观察到x等价于
x 1 = 2 c b + b 2 4 a c x_1 = \frac{-2c}{b + \sqrt{b^2 - 4ac}}
分母是两个数量相当的正数之和,因此不会出现相减产生的数字消去。但是,观察下
x 2 = 2 c b b 2 4 a c x_2 = \frac{-2c}{b - \sqrt{b^2 - 4ac}}
在该式中,x受到了相减产生的数字消去和除以接近零的数的影响。显然,仅仅选取一种求根公式并不足以适应所有的情况。为完备起见,应该考虑b和 b 2 4 a c \sqrt{b^2 - 4ac} 的数量大小,并据此选用合适的公式来求解 x 1 x 2 x_1 x_2

即使数值误差在合理的范围内,上述例子还说明了另一个需要处理的问题。通过分析可知,理论上 b 2 4 a c b_2 - 4ac ,因此该二次方程仅有实数根。数值的四舍五入误差将可能引起表示 b 2 4 a c b_2 - 4ac 的浮点数为很小的负数,这将导致平方根运算的失败(一般产生一个无效的NaN[非数])。如果理论上已知 b 2 4 a c b_2 - 4ac ,那么计算平方根的安全方法是使用公式 b 2 4 a c \sqrt{|b_2 - 4ac|} m a x ( 0 , b 2 4 a c ) \sqrt{max(0, b_2 - 4ac)}

1.2.2 高层问题

进行数学思考时,浮点数系统中存在一些主要的陷阱,其中之一与排中律( Law of theExcluded Middle)有关。

简单地说,一个命题非真即假。用符号术语来表述就是,如果S是一个布尔语句( Boolean statement)(其值非真即假),则布尔语句S或者非S总为真实现代码时往往假定排中律总是正确的。然而在浮点算术中却并非总是如此

【实例】
假定有一个凸四边形( convex quadrilateral),按逆时针次序其顶点依次为 v i ( 0 i 3 ) v_i(0 \leqslant i \leqslant 3) ,P为四边形内的点,即P在四边形内,而不是在它的四条边上。当所有点
都用实数表示时,下面的三个陈述中必有一个是正确的:

  • P在三角形( V0, V1, V3)内
  • P在三角形(v1, V2, V3)内
  • P在对角线V1 V3上。

在通过计算重心坐标来进行包含测试的浮点数系统中,上述所有陈述可能都是错误的! 当P几乎位于对角线(V1,V3)上时将出现问题。此时,包含P的三角形的重心坐标之在理论上是一个小正数。浮点四舍五入误差可能将该坐标变为一个小负数。这样,P将被认为位于三角形之外。如果它也位于另一个三角形之外,则上述三个布尔条件都为假。当试图在三角形网格中判断哪个三角形包含指定点时,例如,在德洛奈三角剖分的增量构造过程中,可能会出现这种问题。

**【实例】**再假定有一个凸四边形,其任意的三个顶点都构成一个三角形。其中任何一个三角形的外接圆不一定包含第四个顶点。当所有点用实数表示时,在理论上,至少有个外接圆必将包含第四个顶点。
在浮点数系统中,浮点四含五入误差可能导致如下的测试结果:没有任何一个外接圆包含对应的第四个顶点。当试图求解包含有限点集的最小面积圆时,可能会出现这种问题。

**【实例】**理论上,凸多面体与平面的交集只能是一个点,一条线段,或者一个凸多边形。在浮点数系统中,通过计算得到的交集可能包括一个凸多边形和与其顶点相连的一条或多条线段。例如,交集可能包含四个点 v i ( 0 i 3 ) v_i(0 \leqslant i \leqslant 3) ,一个三角形{V0, V1, V2)和一条边(V2, V3)。构造相交所得的多边形的程序逻辑必须处理这类异常的情况。

几乎在与浮点数有关的任何实现中都可能出现许多像这些实例一样的问题,因此,在构建程序逻辑时,应该时刻注意不要仅仅依赖数学推理

在许多计算儿何算法中都存在一个高层问题,即共线、共面或共点的问题。为了简化分析,关于这些算法的理论讨论往往假设这种问题不会出现。例如,在一组点的德洛奈三角剖分中,如果不存在四点共圆,则三角剖分是惟一的。构建构造三角剖分的增量算法是很简单的。然而,算法的实现必须慎重考虑出现四点共圆(或在浮点系统中出现四点近似共圆,参见低层问题中的实例)的一种或两种可能的构形。凸包的构造也受到点的共线和共面问题的困扰。

由于浮点问题的存在,我们需要仔细地实现与相交点的构造有关的特定算法。考虑计算两个椭圆的相交点的问题。正如你在稍后的章节中将读到的,该问题等价于计算具有个变量的四次多项式的根。求根的数值算法可用于求解这类多项式方程,但是当四次项的系数为零或接近零时,应该小心求解。在这种情况下,求根过程可能误入歧途。从几何意义来说,当椭圆为圆或接近圆时,将出现这种情况。即使首项系数足够大,也可能出现另外一类问题,即偶次重根问题。如果r是函数f(x)的一个奇次重根,则f®=0,但是f在根的一边为负,在根的另一边为正(至少在x充分接近r时是这样)。如果r是偶次重根则f在根的两边的符号相同(在x充分接近r时是这样)典型的例子是,对于函数 f ( x ) = x r = 0 f(x) = x,r=0 是一个奇次重根(1);对于函数 f ( x ) = x 2 r = 0 f(x) = x^2,r=0 是一个偶次重根(2)。对分求根法要求根为奇次重根,因此不能用这种方法来求解函数 f ( x ) = x 2 f(x) = x^2 的根。牛顿求根法的标准形式用于求解重次为1的根,但我们将讨论求解更多重次根的更高级的修正形式。

求根的数值问题可简单地视为使用浮点数的一个副作用,它并不会频繁出现。然而由于几何问题的本质特性,有时还是会出现这种情况! 考虑检测两个运动椭园第一次相交的问题。假设两个椭园具有不同的轴长,它们第一次接触时的交集是一个单独的点。而且,此时待求根的这个四次多项式具有一个偶次重根(基于上述假设)。因此,你的求根方法必须能够处理偶次重根。在处理对象的相交问题时,奇次相重和偶次相重的概念与横截性( transversality)和相切性( tangency)相关。如果一条曲线与另一条曲线相交,并H它们各自在相交点的切线不平行,则相交是横截相交。对于这种相交的任何多项式方程都具有一个奇次重根。如果切线平行,则曲线相切接触,并且多项式方程有一个偶次重根。在许多应用中,特别是在运动物体的碰撞检测中,相切接触具有重要意义。

最后,在实现算法时考虑较少的一种现象是输入参数的次序相关性。例如,如果要实现个检测两条线段是否相交的函数 TestIntersection( Segment, Segment)(返回值非true即 false),那么,对任意输入s0和s1,我们将期望 TestIntersection(s0,s1)和 Testintersecti on(s1,s0)产生相同的结果。如果该函数不能满足这种要求,那么可能是因为算法设计得不合理,但更可能是因为在实现时没能正确地处理浮点问题。

1.3 各章内容概要

我们为希望复习向量和矩阵代数的基本概念的读者提供了第2章,第3章和第4章。附录A提供了用于本书算法的许多数值方法的概要。三角几何公式可在附录B中找到。附录C是一个关于在本书中将遇到的一些几何图元基本公式的快速参考。

第5章提供了几何问题涉及的各种二维对象的定义,包括直线、射线、线段、多边形二次曲线段(二次方程定义的曲线),以及多项式曲线。主要的几何问题包括在第6章讨论的几何测量和在第7章讨论的相交问题。第8章提供了一些重要的杂项问题。

第9章提供了儿何问题涉及的各种三维对象的定义,包括直线、射线、线段、平面和面形对象(内嵌于三维屮面中的二维对象)、多面体和多边形网格、二次曲面(一次方程定义的曲面)、多项式曲线、多项式曲面、有理曲线,以及有理曲面。主要的几何问题包括在第10章讨论的儿何测量和在第11章讨论的相交问题。第12章提供了一些重要的杂项问题。

在第13章中提供了关于计算几何学主题的大量材料。这些主题包括爷间分区二叉树对多边形和多面体的布尔运算、点在多边形内和点在多面体内的测试、点集所组成凸包的构造、点集的德洛奈三角剖分、多边形的三角剖分和多边形的凸块分解,以及点集定义的有边界容器的最小面积和体积。本书还包含一节内容,讨论了二维或三维中多边形面积的计算和多面体体积的计算。

猜你喜欢

转载自blog.csdn.net/BDalasja/article/details/86293654