三维消隐算法

本文转载新浪博客


zihahage的博客


第八章 三维消隐算法

当我们观察空间任何一个不透明的物体时,只能看到该物体朝向我们的那些表面,其余的表面由于被物体所遮挡我们看不到。

  如果把可见和不可见的线都画出来,对视觉会造成多义性。如下图所示,图(a)的图形就可能表示成两种不同情况下的空间物体,如图(b)和图(c)。

第八章消隐第二部分 - 小柳树 - 小柳树的博客

(a)线框图      (b)消隐图1    (c)消隐图2 
平面立体的线框图和消隐图

 

第八章消隐第二部分 - 小柳树 - 小柳树的博客

(a) 画出所有的线段 (b)消隐图1   (c)消隐图2  
两个物体间的相互遮挡关系

  第八章消隐第二部分 - 小柳树 - 小柳树的博客一、消隐处理

  要画出确定的、立体感很强的三维图形,就必须将那些被不透明的面(或物体)所遮挡的线段(或面)移去,这就是隐藏线或隐藏面的消隐处理。

  消隐处理从原理上讲并不复杂。为了消除被遮挡的线段,只需将物体上的所有线段与遮挡面进行遮挡测试,看线段是否被全部遮挡、部分遮挡或者不被遮挡,然后画出线段的可见部分。

  但是消隐处理的具体实现并不那么简单,它要求适当的算法及大量的运算。

  在60年代,消隐问题曾被认为是计算机图形学中的几大难题之一。到目前为止,虽然已有数十种算法被提出来了,但是由于物体的形状、大小、相对位置等因素千变万化,因此至今它仍吸引人们作出不懈的努力去探索更好的算法。

  这方面的研究是围绕着:算法正确、节省内存空间、加快运算速度等目标而进行的。

  消隐不仅与消隐对象有关,还与观察者的位置有关。如下图所示,由于视点的位置不同,物体的可见部分也不同:

  1、当视点在E1位置时,AB两面可见,CD两面不可见;
  2、当视点移到E2位置时,D面由不可见变为可见,而B面则由可见变为不可见。

  因此,消隐算法是相对于空间给定位置的观察者决定哪些线段、棱边、表面或物体是可见的,哪些是不可见的。

第八章消隐第二部分 - 小柳树 - 小柳树的博客
视点位置与可见性的关系

   二、消隐算法的分类:

  第八章消隐第二部分 - 小柳树 - 小柳树的博客1、物体空间消隐算法

  以场景中的物体为处理单元。假设场景中有k个物体,将其中一个物体与其余k-1个物体逐一比较,仅显示它可见表面以达到消隐的目的。

  算法描述如下:

  for(场景中的每一个物体)
  { 将该物体与场景中的其它物体进行比较,确定其表面的可见部分;
   显示该物体表面的可见部分;
  }

  此类算法通常用于线框图的消隐。

  如果场景中有k个物体,这类算法的计算量正比于k2

  第八章消隐第二部分 - 小柳树 - 小柳树的博客2、图像空间消隐算法

  以窗口内的每个像素为处理单元。确定在每一个像素处,场景中的k个物体哪一个距离观察点最近,从而用它的颜色来显示该像素。

  算法描述如下:

  for(窗口中的每一个像素)
  { 确定距视点最近的物体,以该物体表面的颜色来显示像素;
  }

  如果场景中有k个物体,屏幕分辨率为m×n,则这类算法的计算量为:mnk。

8.1 消隐常用的计算方法

消隐的对象是三维物体。我们用平面多边形表示物体的表面,物体的曲面部分可

以用平面多边形逼近的方法近似表示。多边形又可用它的边表示,每条边又可以用其两个端点来定义。因此,消隐过程中所涉及到的几何元素一般都是点、直线段和平面多边形,消隐算法需要对它们进行大量的计算和比较。 

消隐常用的计算方法有:

  8.1.1 两直线段求交点

  8.1.2 平面多边形的外法矢量

  8.1.3 包含性检验

  8.1.4 包围盒检验

  8.1.5 交矩形检验

  8.1.6 深度检验

  8.1.7 平面和棱边的分类

8.1.1 两直线段求交点

  直线有几种表达式,在计算机图形学中常用参数方程的形式进行描述。

  设两直线段分别为P1P2、P3P4,如图中所示。

第八章消隐第二部分 - 小柳树 - 小柳树的博客

两直线的交点

  其参数方程:

第八章消隐第二部分 - 小柳树 - 小柳树的博客

 

  两直线的交点应满足:

第八章消隐第二部分 - 小柳树 - 小柳树的博客

 

  求得:

第八章消隐第二部分 - 小柳树 - 小柳树的博客

 

  若参数值同时满足0≤u≤1,0≤v≤1,则两线段有交点,代入公式(8-1)或者(8-2)即可求得交点坐标(x,y)。否则无交点。

8.1.2 平面多边形的外法矢量

  为了判别物体上各表面是朝前面还是朝后面,需求出各表面(平面多边形)指向物体外侧的法矢量。如图中所示。

第八章消隐第二部分 - 小柳树 - 小柳树的博客

物体表面外法矢量

  设物体位于右手坐标系中,多边形顶点按逆时针排列。当多边形为凸多边形时,该平面的外法矢量为多边形相邻两边矢量的叉积。见图中的外法矢量:

第八章消隐第二部分 - 小柳树 - 小柳树的博客

  这种方法虽然简单,但当多边形为凹多边形时,则可能出现错误,即所求出的矢量为内法矢量。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客求任意多边形法矢量的算法:

  设法矢量

第八章消隐第二部分 - 小柳树 - 小柳树的博客

  而三个方向分量为:

第八章消隐第二部分 - 小柳树 - 小柳树的博客 (8-5)

  式中:n为顶点号,若i≠n,则j=i+1;否则i=n,j=1。

  以上算法适合任意平面多边形。非平面但最佳逼近该平面的法矢量也可用此算法求出。为避免在程序中出现两种计算外法矢量的方法,建议凸多边形也采用该算法进行计算。多边形所在的平面方程可写成:

第八章消隐第二部分 - 小柳树 - 小柳树的博客 (8-6)

  其中:

第八章消隐第二部分 - 小柳树 - 小柳树的博客 (8-7)

  这里第八章消隐第二部分 - 小柳树 - 小柳树的博客为平面上任意一点。

8.1.3 包含性检验

  在消隐算法中,经常会遇到判别一点的投影(仍然是点)是否落在多边形投影范围内的问题,这个判别称为包含性检验。有多种包含性检验方法,这里介绍其中的一种:交点记数法。

  如下图所示,从判断点沿任意方向(一般平行于坐标轴)引射线至无穷远处,例如平行x轴的直线:

第八章消隐第二部分 - 小柳树 - 小柳树的博客

  求出射线与多边形投影(一般仍为多边形)各边的交点个数:

  1、当交点数为奇数时,点在多边形投影内;

  2、若交点数为偶数时,点在多边形投影外。

第八章消隐第二部分 - 小柳树 - 小柳树的博客

包含性检验

  所引射线过多边形投影顶点,必须特殊对待,否则会出现错误。具体做法为:

  1、若共享顶点是局部极值点时,交点记数加2;

  2、否则,交点记数加1。

  更多的内容请看2.3 区域填充中“奇异点的处理”。

8.1.4 包围盒检验

  包围盒检验的目的是排除不可能产生遮挡关系的两个对象(物体之间或物体上两个表面之间),以减少不必要的求交计算。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客一、算法思想

  1、先求出对象在画面坐标系中投影的最大、最小值域,也就是建立包围该投影的最小矩形盒。

  2、然后判断两对象盒是否重叠。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客二、共有三种情况

  三种情况如图中所示:

  1、图(a)为两盒不重叠,故两对象不可能存在遮挡关系;

  2、图(b)两盒虽然重叠,但两对象没有相互遮挡的问题;

  3、图(c)盒子及对象都重叠,两对象有遮挡关系,需进一步进行隐藏关系计算。

第八章消隐第二部分 - 小柳树 - 小柳树的博客

(a) 两盒不重叠

(b)两盒重叠,
  对象无遮挡

(c)两盒重叠,
  对象有遮挡

包围盒检验图示

  第八章消隐第二部分 - 小柳树 - 小柳树的博客三、具体算法

  1、分别求出两对象投影AB在x,y方向上的最大、最小值:

  (1)xAmin、yAmin、xAmax、yAmax

  (2)xBmin、yBmin、xBmax、yBmax

  2、比较:

  (1)若xAmax≤xBmin

  (2)或xAmin≥xBmax

  (3)或yAmax≤yBmin

  (4)或yAmin≥yBmax

  以上不等式只要有一个满足,两盒就不重叠;

  只有四个不等式均不成立时,两盒才重叠。

8.1.5 交矩形检验

  在8.1.4的包围盒检验图示中,图(b)和图(c)的两种情况都需进一步求出AB两对象投影的边与边的交点。为减少求交次数和排除图(b)的情况,可利用两包围盒重叠部分的矩形,称它们为交矩形I,来进行交矩形检验。

  两对象投影(多边形)中与交矩形有交点的边才可能相交,从而排除不可能相交的边,以减少求交次数。例如下面交矩形检验图示(b)中,由于A的各边不与交矩形I相交,因此AB本身不相交,就不必对线段求交点。

  在下图(c)中,AB各有两边与交矩形I边界相交,因此需要求交点;而其余的边不相交,则不必求交点。

 

第八章消隐第二部分 - 小柳树 - 小柳树的博客

(a) 两盒不重叠

(b)两盒重叠,
  对象无遮挡

(c)两盒重叠,
  对象有遮挡

 

交矩形检验图示

  具体算法:

  第八章消隐第二部分 - 小柳树 - 小柳树的博客1、求交矩形I的极值:xImin、yImin、xImax、yImax

  xImin = max(xAmin,xBmin

  yImin = max(yAmin,yBmin

  xImax = min(xAmax,xBmax)  

  yImax = min(yAmax,yBmax

  第八章消隐第二部分 - 小柳树 - 小柳树的博客2、判别线段与交矩形是否相交:

  设某对象的边投影(线段)的起点为(x1 ,y1),终点为(x2 ,y2),则:

  当min(x1,x2)≥xImax

  或min(y1,y2)≥yImax

  或max(x1,x2)≤xImin

  或max(y1,y2)≤yImin

  时,则线段不与交矩形相交。

8.1.6 深度检验

  深度检验的目的是为了判别线段与多边形沿着视线方向的前后遮挡关系。在同一投影点上,离视线近的对象会挡住离视线远的对象。为了减少比较和计算的工作量,检验分两步进行:粗略检验和精确检验。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客1、粗略检验

  粗略检验是将那些对某条线段不构成遮挡的多边形排除,不再进行下面的精确检验。

  设视点在z轴正向无穷远处。如果线段两端点的z坐标均大于多边形每一顶点的z坐标,则线段在该多边形之前,那么线段不可能被多边形遮挡。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客2、精确检验

  设线段两端点为P(xp,yp,zp),Q(xq,yq,zq),多边形所在平面F的方程为

第八章消隐第二部分 - 小柳树 - 小柳树的博客

  分别过PQ两点作两条平行z轴的直线L1和L2L1L2与平面F的交点分别为P1(xp,yp,zp1)和Q1(xq,yq,zq1),比较重影点(沿着视线方向,它们在投影平面上是重叠的点)PP1QQ1的z坐标值,有以下三种情况:

  (1)若 zP>zP1且zq>zq1,则线段PQF面之前,PQ全部可见;

  (2)若 zP<zP1且zq<zq1,则线段PQF面之后,PQ可能全部被遮挡,也可能部分被遮挡。

  (3)若 zP<zP1且zq>zq1或zP>zP1且zq<zq1,则PQ部分在F面之前,部分在F面之后。

  对于后两种情况需要进一步判别线段的可见性。

  精确检验的进一步判别:

第八章消隐第二部分 - 小柳树 - 小柳树的博客

线段投影的分段

  图中为线段PQ的投影pq与多边形投影的相互关系。多边形投影把pq分成七个子线段,其中pu1,u2u3,u4u5,u6q,显然不被多边形遮挡,是可见的。

  需要判别的是其余的子线段u1u2,u3u4和u5u6是否可见:

  如属于第二种情况,显然它们都不可见;

  若属于第三种情况,还需对每一段进行判别。具体方法为:在PQ和多边形所在平面各取一点构成重影点来比较。这里依据上图所示规律:

  若子线段上任一点可见,则该子线段可见,反之不可见。

  以子线段u1u2为例。取u1u2的中点M(xm,ym,zm)及与M对应的位于F平面上的点M1(xm,ym,zm1)为一对重影点。设与参数t1和t2对应的子线段u1u2的端点为(x1,y1,z1)和(x2,y2,z2),则u1u2的中点M为:

  xm=(x1+x2)/2
  ym=(y1+y2)/2
  zm=(z1+z2)/2

  过M点作直线L平行z轴,则该直线的参数方程:

  x=xm
  y=ym
  z=zm+t

  代入上述的多边形所在平面F的方程,得

  t = -(Axm+Bym +Czm+D)/C

  其中C≠0。交点M1的z坐标值 zm1 = zm + t,于是点MM1M1:过M点平行z轴的直线L和平面F的交点)构成一对重影点。显然:

  当t≤0时,则zm1≤zm,表明M点位于M1点之前,故子线段u1u2F面之前,u1u2可见;
  反之t≥0,zm1≥zm,则M点位于M1点之后,子线段u1u2F面之后,u1u2不可见。

  同理可判断u3u4和u5u6的可见性。

  求L1L2F面交点的方法与此相同。

8.1.7 平面和棱边的分类

  根据平面上任一点的外法矢量与过该点的视线矢量(该点与视点的连接矢量,指向视点)的夹角θ可将平面分成朝前面和朝后面两类:

  (1)若θ ≤ 90°,平面面向观察者,称为朝前面;
  (2)若 90°<θ≤ 180°,则平面背向观察者,称为朝后面。

 

第八章消隐第二部分 - 小柳树 - 小柳树的博客

棱边的分类

 

  朝后面是不可见的;

  朝前面可能全部可见,也可能部分可见或全部不可见,故称为潜在可见面。

  根据组成棱边的两个平面的性质可以将棱边分成下面四类(见棱边分类图示):

  第八章消隐第二部分 - 小柳树 - 小柳树的博客1、H1

  H1类棱边所在的两平面均为朝后面,故H1类棱边不可见。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客2、H2

  H2类棱边所在的两平面,一个为朝前面,另一个为朝后面,且两面角(体内测量)大于180°,这类棱边也是完全不可见的。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客3、H3

  H3类棱边所在的两平面,一个为朝前面,另一个为朝后面,但是两面角(体内测量)小于180°,这类棱边称为轮廓边,它构成立体的外部轮廓。对于单个形体,这类棱边是可见的,如图中所示。对于多个形体,这类棱边可能全部可见,也可能部分可见的。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客4、H4

  H4类棱边所在的两平面均为朝前面,因朝前面可能全部可见,也可能部分可见(见8.3节图示中的π5)或全部不可见(见8.3节图示中的π4),故这类棱边可能全部可见,也可能部分可见或全部不可见。

 

8.2 凸多面体消隐(Roberts消隐)

凸多面体是由多个多边形包围而成的平面立体。对于这样的形体可通过各组成平面的朝向在物体空间进行消隐。

  平面πi上任一点的外法矢ni与该点的视线矢量si的数量积:

 

ni·si= |ni||si|cosθ,   0≤θ≤π (8-8)

 

从而有

 

第八章消隐第二部分 - 小柳树 - 小柳树的博客 (8-9)

 

  θinisi之间的夹角,i=1,2,…,n,这里n为平面数。

  当 cosθi ≥ 0,即 0 ≤θi ≤π/2时,πi为朝前面,为可见的,应该画出;

  当 cosθi < 0,即 π/2 <θi≤π时,πi为朝后面,不可见的,不画出或用虚线表示。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客视线矢量si平行某一基本坐标轴:

  当视线矢量平行某一基本坐标轴时,那么平面的外法矢量n{ABC}与视线矢量的夹角就是外法矢量n与某一基本坐标轴的夹角:

  (1)COSα(视线矢量平行x轴)

  (2)或 COSβ(视线矢量平行y轴)

  (3)或 COSγ(视线矢量平行z轴)

  1、假设视线矢量平行z轴时:

第八章消隐第二部分 - 小柳树 - 小柳树的博客

  因为分母无符号,所以COSγ的符号就由平面的外法矢量n在z轴的方向分量C所决定:

  (1)C≥0,平面可见;

  (2)C<0,平面不可见。

  2、同理,若视线矢量平行x轴时,某平面的可见性由该平面外法矢量n在x轴的方向分量A所决定。

  3、若视线矢量平行y轴时,某平面的可见性由该平面外法矢量n在y轴的方向分量B所决定。

  平面的外法矢量n{ABp}的计算见前面介绍的公式(8-5),即

第八章消隐第二部分 - 小柳树 - 小柳树的博客 (8-5)

 

  式中:n为顶点号,若i≠n,则j=i+1;否则i=n,j=1。

  此算法应属消除隐藏面算法,也叫Roberts消隐算法。虽然这种算法只适用于单个凸多面体,但它也常用于其它消隐算法之前,以消除画面中的朝后面(即自隐藏面或背面),所以这一算法也称为背面剔除法。对于凸多面体,采用该算法后约有半数的隐藏面被剔除掉。

8.3 任意多面体的隐藏线消除

  上一节介绍的凸多面体消隐算法虽然简单,但应用时受限。通常我们遇到的平面立体很少是单纯的凸多面体,更常见的是任意形状的平面立体(组合体)。对于单个凸多面体,其表面不是全部可见就是全部不可见,因此构成各表面的棱边也必然是全部可见或全部不可见。

  然而任意平面立体则不同,除了有全部可见和全部不可见的棱边外,还有部分可见的棱边。如图中顶点16、13组成的棱边(π5上)为部分可见,由顶点11、14组成的棱边(π4上)所在的两平面虽然都是朝前面,但全部不可见。因此,对于任意平面立体必须寻求适当的消隐算法。这类算法有很多,但一般都要涉及8.1所述“消隐常用的计算方法”。下面介绍其中的一种算法,它是以物体空间和图像空间结合的方式实现的。

第八章消隐第二部分 - 小柳树 - 小柳树的博客

任意多面体的隐藏情况

  第八章消隐第二部分 - 小柳树 - 小柳树的博客一、算法思想

  算法的基本思想是将形体朝前面上的H3H4类棱边与构成形体的每个表面作包围盒检验、深度检验和求交等处理,以决定棱边的可见性。为了减少计算量,可预先把朝后面全部剔除,而只将H3H4类棱边与朝前面作上述处理。朝后面总是不可见的,不会仅仅由于朝后面的遮挡而使棱边不可见,即去掉朝后面并不影响消隐结果同时也排除了H1类棱边。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客二、剔除朝后面和建立潜在可见面表

  用8.2的方法将朝后面全部剔除,只保留朝前面并建立其平面方程系数表,称为潜在可见面表。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客三、建立潜在可见棱边表

  算法采用图中的三表结构:面表、棱边表和顶点表。

  面表的第一列为该面的棱边总数,第二列为内环数,无内环则为0。

  棱边表中存放着相应面棱边的顶点序列,外环按逆时针方向排列,内环按顺时针方向排列。

  为了区分内外环,内环与外环之间用0隔开。

  下图表示了一个带孔的长方体,和三表数据结构。

第八章消隐第二部分 - 小柳树 - 小柳树的博客

  为了便于对H3H4类棱边进行消隐处理,利用上述的三表数据结构为这两类棱边另外建立一个潜在可见棱边表。表中存放着每条棱边的两个端点号(或两个端点的指针)。为避免重复,在建立潜在可见棱边表的过程中,如当前棱边已在表中,则不重复进来,否则将当前棱边送入表中。

  检查当前棱边是否已在表中,可通过比较当前棱边和表中所有棱边的端点号是否相同来进行。由棱边表顶点序列的排列规则可知,若当前棱边第一个端点号和第二个端点号分别与表中某棱边第二个端点号和第一个端点号相等时,则说明当前棱边和该棱边是同一条棱边。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客四、求每条潜在可见棱边与各个朝前面的隐藏关系

  从潜在可见棱边表中顺序取出每条棱边与各个潜在可见面作包围盒和深度检验。如果被排除,即一条棱边与某潜在可见面无隐藏关系,则不进行下面的试求交,但要设定该棱边的可见标志;若不能被上述两种检验所排除,即一条棱边可能被某潜在可见面所隐藏时,则试求出它的投影与该面投影各棱边的交点,如有交点,则用深度检验的方法确定交点所分割的各子段的可见性并设置可见性标志。

  当某条棱边被mm≥2)个潜在可见面所隐藏时,可得到m组可见的参数区间 第八章消隐第二部分 - 小柳树 - 小柳树的博客  i=1 ,2 , … ,m ;这里ni为第i组区间的个数。该棱边最终的可见部分应该是这些区间的交集。为求出这个交集,我们首先求出二组区间的交集,即:

第八章消隐第二部分 - 小柳树 - 小柳树的博客

  与

第八章消隐第二部分 - 小柳树 - 小柳树的博客

  的交集。其算法如下图所示。

第八章消隐第二部分 - 小柳树 - 小柳树的博客

求交集,决定可见区域

  1、置每个小区域左端的特征为“-”,右端特征为“+”,将两组的λ值合并后从小到大排序。

  2、从最左的负特征端点开始,置IN=-1。

  3、 取下一个端点,判别特征:

  (1) 若特征为“+”,则IN=IN+1;
  (2) 若特征为“-”,则IN=IN-1;

  重复3,直至最后一个端点。

  4、 每个从IN=-2到IN=-1的端点对,就是可见的区间段。

  不难把此算法推广到m组区间的求交集问题上。

8.4 Z缓冲器算法

  Z缓冲器算法也叫深度缓冲器算法,属于图像空间消隐算法。

  深度缓冲器算法有两个缓冲器:深度缓冲器和帧缓冲器。对应两个数组:深度数组depth(x,y)和属性数组intensity(x,y)。前者存放着图像空间每个可见像素的z坐标,后者用来存储图像空间每个可见像素的属性(光强或颜色)值。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客一、Z缓冲器算法基本思想

  将投影平面每个像素所对应的所有面片(平面或曲面)的深度进行比较,然后取离视线最近面片的属性值作为该像素的属性值。

  算法通常沿着观察坐标系的Z轴来计算各物体表面距观察平面的深度,它对场景中的各个物体表面单独进行处理,且在各面片上逐点进行。物体的描述转化为投影坐标系之后,多边形面上的每个点(x,y,z)均对应于观察平面上的正投影点(x,y)。因而,对于观察平面上的每个像素点(x,y),其深度的比较可通过它们z值的比较来实现。对于右手坐标系,z值最大的点应是可见的。见下图。

第八章消隐第二部分 - 小柳树 - 小柳树的博客

在观察平面上,面s1相对其它面z值最大,因此它在该位置(x,y)可见

  第八章消隐第二部分 - 小柳树 - 小柳树的博客二、Z缓冲器算法步骤

  初始时,深度缓冲器所有单元均置为最小z值,帧缓冲器各单元均置为背景色,然后逐个处理多边形表中的各面片。每扫描一行,计算该行各像素点(x,y)所对应的深度值z(x,y),并将结果与深度缓冲器中该像素单元所存储的深度值depth(x,y)进行比较:

  若

z>depth(x,y) (8-10)

  则

depth(x,y)=z (8-11)

 

  而且将该像素的属性值I(x,y)写入帧缓冲器,即

intensity(x,y)= I(x,y) (8-12)

  否则不变。

  也可用背面剔除法进行预处理,即背面不参加处理,以提高消隐的效率。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客三、深度值的计算

  若已知多边形的方程,则可用增量法计算扫描线每一个像素的深度。

  设平面方程为:

第八章消隐第二部分 - 小柳树 - 小柳树的博客

  则多边形面上的点(x,y)所对应的深度值为:

第八章消隐第二部分 - 小柳树 - 小柳树的博客  C≠0

  由于所有扫描线上相邻点间的水平间距为1个像素单位,扫描线行与行之间的垂直间距也为1。因此可以利用这种连贯性来简化计算过程,如图所示。

第八章消隐第二部分 - 小柳树 - 小柳树的博客

深度计算

  若已计算出(x,y)点的深度值为zi,沿x方向相邻连贯点(x+1,y)的深度值zi+1可由下式计算:

第八章消隐第二部分 - 小柳树 - 小柳树的博客 (8-13)

  沿着y方向的计算应先计算出y坐标的范围,然后从上至下逐个处理各个面片。由最上方的顶扫描线出发,沿多边形左边界递归计算边界上各点的坐标:

第八章消隐第二部分 - 小柳树 - 小柳树的博客 (8-14)

  这里m为该边的斜率,沿该边的深度也可以递归计算出来,即:

第八章消隐第二部分 - 小柳树 - 小柳树的博客 (8-15)

  如果该边是一条垂直边界,则计算公式简化为:

第八章消隐第二部分 - 小柳树 - 小柳树的博客 (8-16)

  对于每条扫描线,首先根据公式(8-15)计算出与其相交的多边形最左边的交点所对应的深度值,然后,该扫描线上所有的后续点由(8-13)式计算出来。

  所有的多边形处理完毕,即得消隐后的图形。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客四、Z缓冲器算法特点

  z缓冲器算法的最大优点在于简单,它可以轻而易举地处理隐藏面以及显示复杂曲面之间的交线。画面可任意复杂,因为图象空间的大小是固定的,因此计算量最多随画面复杂度线性增长。

  它的主要缺点是,深度数组和属性数组需要占用很大的内存。以深度数组为例,对于800×600的显示分辨率,需要480000个单元的缓冲器存放深度值,如每个单元需要4个字节,则需要1.92兆字节。

  一个减少存储需求的方案是,每次只对场景的一部分进行处理,这样只需要一个较小的深度数组。处理完一部分之后,该数组再用于下一部分场景的处理。

8.5 扫描线算法

  扫描线算法也属于图像空间消隐算法。该算法可以看作是多边形区域填充里介绍过的边相关扫描线填充算法的延伸。不同的是在消隐算法中处理的是多个面片,而多边形填充中是对单个多边形面进行填充。

  消隐处理中,在逐条处理各扫描线时,首先要判别与其相交的所有多边形表面的可见性,然后计算各重叠面片的深度值以确定离观察者最近的面片。当某像素点所对应的可见面被确定后,该点的光强值也可以计算出来,将其置入帧缓冲器。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客一、扫描线算法的三表数据结构

  首先为各面片建立边表(ET)和多边形表(PT)。

  1、边表(ET

  对投影到屏幕上的这些多边形的所有非水平边建立ET表,ET表包含:

  (1) ymax :该边最大的y值。
  (2) x :具有较小y坐标值一端的x值,即端点(x,ymin)。
  (3) 1/m :该边斜率的倒数。
  (4) ID :该边属于哪个多边形的标志码。
  (5) z :该多边形 x 对应点处的深度值。
  (6) dzx :该多边形深度沿 x 轴方向的增量,见公式(8-13)。
  (7) dzy :该多边形深度沿 y 轴方向的增量,见公式(8-15)。

  边结点结构如下:

第八章消隐第二部分 - 小柳树 - 小柳树的博客

  2、 多边形表(PT

  对于每个多边形应当包含的信息为:

  (1)ID :多边形标志码。
  (2)A、B、C、D :平面方程各系数。
  (3)color :多边形的颜色值。
  (4)flag :进出标志,表明扫描线是否进入该多边形内,初始时置为“假”。
  (5)num :计数器,记录与该多边形相交的扫描线的根数。

  多边形表的结构如下:

第八章消隐第二部分 - 小柳树 - 小柳树的博客

  3、为了计算扫描线与各边的交点,还需活动边表(AET

  (1)AET是与当前扫描线相交的多边形边结点链接而成的表。

  (2)AET的边结点按x增加的顺序排列。

  (3)AET中结点的数据项与ET表一致,只是AET中结点的数据内容将随着扫描线的变动而不断更新。

  (4)其x项的更新为当前扫描线与各边交点的x坐标值,其它项也视具体情况随x值的更新而更新。

  (5)扫描转换时,当进入下一条扫描线前,需删除那些已脱离扫描线的多边形的边结点,并从ET表中增加一些新的边结点。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客二、扫描线经过非多边形相交区域

第八章消隐第二部分 - 小柳树 - 小柳树的博客

多边形投影相互相交

  当扫描线经过非多边形相交区域时,如图中的y=β扫描线。扫描线β首先与多边形ABC的边AB相交,扫描线进入多边形内,多边形ABCflag标志由假(F)转为真(T)。由于在此区段中扫描线仅与一个多边形相交,因而用多边形ABC的颜色写像素。

  当扫描线与AC边相交后,扫描线穿出多边形ABC,其标志变为F,从而用背景色写像素。

  接着扫描线与多边形DEFDF边相交至与EF边相交前,标志变为T,写入多边形DEF的颜色,在与EF边相交之后,DEF的标志变为F,则像素写入背景色。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客三、扫描线经过多边形投影相互覆盖区域

第八章消隐第二部分 - 小柳树 - 小柳树的博客

多边形投影相互覆盖

  当扫描线经过多边形投影相互覆盖区域时,如图中的y=γ。同样,在扫描线γAB边相交前像素写背景色。扫描线与AB边相交后,进入多边形ABC,其标志转为T,此时以多边形ABC的颜色写像素。而当扫描线与DE边相交后,多边形DEFflag标志也转为T

  当两个以上的多边形标志为真时,将以何值写入像素呢?

  应该选择离观察者最近的多边形的颜色值写入,这时就需要由这几个多边形在x点处的深度信息来决定。

  本例中即为扫描线γDE边相交处的x点,按图中的情况,多边形DEF具有较大的z值,因而DEF是可见的,应将多边形ABC隐去。因此,使用多边形DEF的颜色直到BC边交点,这时多边形ABC的标志转为F,扫描线仅位于一个多边形DEF内,则仍以DEF的颜色写入像素。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客四、多边形发生相互贯穿

第八章消隐第二部分 - 小柳树 - 小柳树的博客

多边形相互贯通

  在多边形发生相互贯穿的情况下,仍可以使用扫描线消隐算法。如图中所示,多边形GHIJKL发生相互贯穿。

  此时,可将多边形GHI分为两个多边形GHH'G'H'G'I,引入了虚边G'H'

  然后,应用此算法于三个多边形GHH'G'H'G'IJKL

  当扫描转换时,同时求得两多边形的贯穿点G'H'

  第八章消隐第二部分 - 小柳树 - 小柳树的博客五、扫描线消隐算法特点:

  扫描线消隐算法不仅用于多边形的消隐,还可扩展应用到任意曲面体的消隐。

  在任意曲面体的消隐中,需要将多边形表PT改为曲面表ST,活动边表改为活动曲面表,并需要一些附加的计算:

  如将一个曲面分解成多个小多边形 。

  扫描转换时,当进入下一条扫描线,需删除那些已脱离扫描线的多边形结点,并增加一些新加入的多边形结点。当然,工作量会增加许多。

8.6 画家算法

  假设一个画家要作一幅画,画中远处有山,近处有房子,房子的前面有树。画家在纸上先画远处的山,再画房子,最后画树,通过这样的作画顺序正确地处理了画中物体的相互遮挡关系。

  由Newell等人于1972年提出的画家算法就是基于这种思想的消隐算法,该算法运用物体空间和图像空间进行操作。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客一、画家算法的基本思想:

  先将画面中的物体按其距离观察点的远近进行排序,结果存放在一张线形表中。距观察点远者称其优先级高,放在表头,距观察点近者称其优先级低,放在表尾,这张表称为深度优先级表。

  然后按照从表头到表尾的顺序逐个绘制物体。由于距观察者近的物体在表尾最后画出,它覆盖了远处的物体,最终在屏幕上产生了正确的遮挡关系。

  画家算法看起来十分简单,但关键是如何对画面中各种不同情况下的多边形按深度排序,建立深度优先表。

  假设视点在z轴正向无穷远处,视线方向沿着z轴负向看过去。如果z值大,离观察点近;而z值小,离观察点远。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客二、多边形优先级的考虑

第八章消隐第二部分 - 小柳树 - 小柳树的博客

多边形的优先级

  1、首先对一个简单的画面,如图(a)所示可以直接建立一个确定的深度优先表,排序可以一次完成,不会有任何的歧义。

  例如,多边形可按其最大或最小值排序,都可以很容易地把它们按深度大小分开。

  2、但是,当画面略微复杂一点,如图(b)所示,却无法按简单的z向排序建立确定的深度优先表,以确定每一个多边形的优先级。

  例如,若按最小z坐标值(zmin)对PQ排序,则在深度优先表中,P应排在Q之前,如按此顺序将PQ写入帧缓冲器,则Q将部分地遮挡P。但实际上是P部分地遮挡Q

  如果按最大z坐标值(zmax)对PQ排序,同样也不能得到正确的消隐结果。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客三、交叉覆盖和循环覆盖多边形的优先级考虑

第八章消隐第二部分 - 小柳树 - 小柳树的博客

循环覆盖多边形的优先级

  对更复杂的情况,如图所示,出现的困难更多。图(a)、(b)均有交叉覆盖或循环遮挡的情况。

  如在图(a)中,PQ的前面,QR的前面,而R反过来又在P的前面。

  在图(b)中,PQ的前面,而Q又在P的前面。

  对它们均无法直接建立确定的深度优先表。

  第八章消隐第二部分 - 小柳树 - 小柳树的博客四、解决深度优先级冲突的排序算法

  为了解决上述深度优先级冲突问题,Newell等人提出了一种针对多边形的特殊排序方法。该算法在处理每一幅画面时,动态地计算和产生一个新的深度优先表,在通过一系列检验确定其深度优先表正确后,写入帧缓存,否则重新计算并产生一个新的深度优先表。假定视点在Z轴正向无穷远处,则该算法叙述如下:

  1、计算多边形最小深度值zmin,并以此值的优先级进行排序,建立初步的深度优先表。表中第一个元素是对应有最小zmin值的多边形,标记为P,优先级最高。表中第二个多边形标记为Q

  2、考察PQ之间的关系:

  (1)若P上离视点最近的顶点PzmaxQ上离视点最远的顶点Qzmin还远,

QzminPzmax

  则P不遮挡Q,将P写入帧缓冲区,见图示。

第八章消隐第二部分 - 小柳树 - 小柳树的博客

  (2)若QzminPzmax,那么P不但有遮挡Q的可能,而且还可能部分地遮挡表上Q之后的任一满足 RzminPzmax的多边形R。

  我们把所有这种有可能被P所遮挡的多边形的全体记为{Q}。

  为了进一步确定P是否真正遮挡{Q}中的多边形,做以下逐步的测试,如果对{Q}中每个Q,都能通过以下问题中任一个,那么P不会遮挡{Q},因而可将P写入帧缓冲区中去。

  所提出的问题是:

  ①PQ的外接最小包围盒在X方向不相交吗?
  ②PQ的外接最小包围盒在Y方向不相交吗?
  ③P是否全部位于Q所在平面的背离视点的一侧。下图(a)能通过这一测试。
  ④Q是否全部位于P所在平面的靠近视点的一侧。下图(b)能通过这一测试。
  ⑤PQ在显示屏幕上的投影是否可以分离。

  若{Q}和P不能通过以上测试,就不能把P写到帧缓冲区中去,则交换PQ,并将Q作上记号,形成新的优先级表。

  (3)对重新排列的表重复(2)中步骤,对于图(c),经重新排列后,就能把Q写入帧缓冲区中去了。

第八章消隐第二部分 - 小柳树 - 小柳树的博客

多边形重叠判断

  (4)执行(3)以后,若Q的位置需再次交换,则表明存在交叉覆盖的情况,见下图所示,这时可将P沿Q所在平面分割成两部分P1P2,从表中去掉原多边形P,而将P的这两个新的部分插入原表中的适当位置,使其仍保持按zmin排序的性质。对新形成的表,重新执行(2)。

第八章消隐第二部分 - 小柳树 - 小柳树的博客

  第八章消隐第二部分 - 小柳树 - 小柳树的博客五、画家算法特点:

  1、画家算法同时在物体空间和图像空间中进行处理,即:

  在物体空间中排序以确定优先级;

  而显示结果在算法运行之际就要不断地写入图像空间的帧缓冲区中。

  2、该算法利用几何关系来判断可见性,而不是像在z缓冲器算法中那样,逐个像素地进行比较。因此,它利用了多边形深度的相关性,可见性判别是根据整个多边形来进行的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值