计算机图形学武汉大学电子信息学院王泉德qdwang@sohu.com第五章图形生成和计算一、区域填充一个区域是指一组相邻而又相连的象素,且具有同样的属性。区域的建立和定义通常可采用两种方式:内定义区域(Interior-Defined):区域内部所有象素具有同一种颜色或亮度值,而区域外的所有象素具有其他颜色或亮度值。边界定义区域(Boundary-Defined):区域边界上所有象素均具有特定的颜色或亮度值,而在区域内、外的象素则具有不同于边界值的颜色或亮度值。给出一个区域的边界,要求对边界范围内的所有象素单元赋予指定的颜色代码称为区域填充。区域填充算法可分为两大类:种子填充算法:假定封闭轮廓线内某点是已知的,然后算法开始搜索与种子点相邻且位于轮廓线内的点。种子填充算法只适用于光栅扫描设备。扫描转换填充算法:按扫描线的顺序确定某一点是否位于多边形或轮廓线范围之内。算法一般从轮廓线的顶部开始进行到它的底部。区域填充的边界可以是直线也可以是曲线。1:多边形区域的扫描转换2:多边形区域的种子填充3:光栅图形的反走样算法1.多边形的扫描转换1.1扫描转换计算机生成的物体常常可以用若干多边形来描述,有些非多边形的物体,也可以用多边形来逼近。在计算机图形学中,多边形有两种重要的表示方法:顶点表示和点阵表示。顶点表示是用多边形的顶点序列来刻划多边形。这种方式直观,几何意义强,占用内存少,但不能直接用于面着色。点阵表示是用位于多边形内的象素的集合来刻划多边形。这种方法虽然失去了很多重要的几何信息,但便于运用帧缓冲器表示图形,是面着色所需要的图形表示形式。顶点表示的多边形P4P0P3P2P1点阵表示的多边形光栅图形的一个基本问题就是把多边形的顶点表示转换成为点阵表示,也就是从多边形的给定边界出发,求出位于其内部的各个象素,并给帧缓冲器内部的各个对应元素设置相应的灰度和颜色,通常这种转换称为“多边形的扫描转换”。多边形的扫描转换过程,实际上就是给多边形包围的区域着色的过程,因此是一种面着色的方法。扫描转换的常用算法逐点判断算法扫描线算法边缘填充算法边界标志算法1.2逐点判断算法思想:逐个象素判别,确定它们是否在多边形内部,从而给出位于多边形内的点(象素)的集合。难点:如何确定一个点是否在多边形内部?点是否在多边形内部的检验为了对多边形内部的象素点赋值,首先要解决如何判断一个点是否判断的方法:先在多边形外部找一个点,然后用线段连接待判决点和待判决点,计算出此线段与多边形边界相交的次数,如果交点的数目为奇数,则待判决点在多边形内部;如果为偶数,待判决点在多边形外部。P113223P4图例PP’2224P11331(1)怎样才能“在多边形外部找一个点”?确定多边形的包围矩形:即xmin,ymin,xmax,ymax,在包围矩形外的点肯定是多边形的外部点;(2)交点计数的特殊情况处理线段和多边形相交在顶点(奇点的处理):–当线段与多边形P的交点是P的顶点Pi时,则称该交点为奇点;–为了保证线段和多边形P边界的交点个数为偶数,现将奇点分为极值点和非极值点两类:如果相交的两条边位于线段同侧,则顶点Pi为极值点,否则为非极值点;–当奇点是P的极值点时,该点按照两个交点计算;否则按照一个交点计算。线段和多边形边共线:线段与多边形相交二次;算法实现现设P=P0P1…PnP0为一给定的多边形。Framebuffer(x,y)是与点(x,y)相对应的帧缓冲器中的元素。则逐点判断的算法可以表示成为如下的程序:fory:=ymintoymaxdoforx:=xmintoxmaxdoifinside(p,x,y)thensetpixel(framebuffer,x,y,polygon-color)elsesetpixel(framebuffer,x,y,back-color);逐点判断的算法虽然程序简单,但是不可取。原因是速度太慢,该算法割断了各个象素之间的联系,孤立的考察各个象素和多边形P的内外关系,使得几十万甚至几百万个象素都要一一判别,每次判别都要多次求交点,需要做大量的乘除运算,花费大量的时间。1.3扫描线算法扫描线算法是多边形扫描转换的常用方法。相比起逐点判断算法,扫描线算法充分利用了象素之间的连贯性,避免的对象素的逐点判断和反复求交的过程。扫描线算法综合利用了区域的连贯性,扫描线连贯性和边的连贯性等三种形式的连贯性。区域的连贯性yk+1yk扫描线yk和yk+1将多边形P分割成若干的梯形,它们具有如下的性质:梯形的两底边分别在y=yk和y=yk+1两条扫描线上,腰在多边形P的边上和显示屏幕的边界上;这些梯形可以分为两类,一类在多边形P的内部,一类在多边形P的外部;两类梯形在长方形区域{yk,yk+1}内相间的排列,即相邻的两个梯形必有一个在多边形P内,另一个在P外;根据这些性质,实际上只要知道该长方形区域z中任一梯形内一点关于多边形P的内外关系后,整个梯形内关于多边形P的内外关系就可以确定了。扫描线的连贯性ykx1x2x3x4扫描线yk和多边形P相交,交点为X1,X2,….XL,它们具有如下的性质:L是偶数;该扫描线上,区段(Xk,Xk+1),k=1,3,5…位于多边形P内部,其余区段都在多边形P外。两类区段沿扫描线相间排列。ykx1x2x3x4边的连贯性设d为一整数,d=e-1。若多边形P的边Pr-1Pr与扫描线y=d和y=e都相交,和两交点的横坐标xe和xd满足下面的关系(mr为斜率):rdemxx1因此,可利用多边形与当前扫描线交点的位置及递推关系,求得多边形与下一条扫描线的交点的位置。以上性质称为边的连贯性,它是区域的连贯性在两条相邻扫描线上的体现。y=ey=dxexd扫描线和多边形相交在顶点(奇点的处理):–当扫描线与多边形P的交点是P的顶点Pi时,则称该交点为奇点;–为了保证扫描线和多边形P边界的交点个数为偶数,现将奇点分为极值点和非极值点两类:如果相交的两条边位于扫描线同侧,即:(yi+1-yi)*(yi-1-yi)0则顶点Pi为极值点,否则为非极值点;–当奇点是P的极值点时,该点按照两个交点计算;否则按照一个交点计算。扫描线和多边形边共线:线段与多边形相交二次;扫描线算法的实现算法的基本思想:利用多边形的边的连贯性和扫描线的连贯性,对于一个给定的多边形,用一组水平(垂直)的扫描线进行扫描对每一条扫描线均可求出与多边形边的交点交点将扫描线分割成落在多边形内部的线段和落在多边形外部的线段,并且二者相间排列将落在多边形内部的线段上的所有象素点赋以给定的色彩值。算法中不需要检验每一个象素点,而只考虑与多边形边相交的交点分割后的扫描线段。扫描线算法的实现原理根据多边形内部点的连续性知:一条扫描线与多边形的交点中,入点和出点之间所有点都是多边形的内部点。所以,对所有的扫描线填充入点到出点之间所有的点就可填充多边形。判断扫描线上的点是否在多边形之内根据多边形区域连续性,分为3个步骤:–求出扫描线与多边形所有边的交点;–把这些交点的x坐标值以升序排列;–从奇数交点出发到偶数交点的扫描线段位于多边形内部。如右图,排序x坐标得到的交点序列是(2,4,9,13),然后对交点2与4之间、9与13之间的所有象素点进行填充。0246810122468101234扫描线算法的实现原理—奇点的处理p1,p3,p4,p5属于局部极值点,要把他们两次存入交点表中。如扫描线y=7上的交点中,有交点(2,7,13),按常规方法填充不正确,而要把顶点(7,7)两次存入交点表中(2,7,7,13)。p2,p6为非极值点,则不用如上处理。0246810122468101234024681012246810123p1p2p3p4p5p6p1p2p3p4p5p6扫描线算法的实现步骤–对于一条扫描线填充过程可以分为四个步骤:•求交•排序•配对•填色0112233445566778891011P2(5,1)EP3(11,3)DP4(11,8)GFCBP5(5,5)P6(2,7)AP1(2,2)扫描线算法的数据结构–边的活化链表(AET):把与当前扫描线相交的边称为活性边,并把它们按与扫描线交点x坐标递增的顺序存放在一个链表中,结点内容•x:当前扫描线与边的交点坐标•△x:从当前扫描线到下一条扫描线间x的增量(边斜率的倒数)•ymax:该边所交的最高扫描线号ymax2073.5-1.57P6P1P5P6AB7281108P4P5P3P4CD△xymax△xymax△xymax△xymax0112233445566778891011P2(5,1)EP3(11,3)DP4(11,8)GFCBP5(5,5)P6(2,7)AP1(2,2)–边的分类表(ET):存放在该扫描线第一次出现的边。若某边的较低端点为ymin,则该边就放在扫描线ymin的新边表中。76P4P5P5P6543210P1P2P2P385-3253320711085285-1.57P6P1P3P4x:边的下端点的x坐标;△x:从当前扫描线到下一条扫描线间x的增量ymax:该边所交的最高扫描线号ymax76P4P5P5P6543210P1P2P2P385-3253320711085285-1.57P6P1P3P40112233445566778891011P2(5,1)EP3(11,3)DP4(11,8)GFCBP5(5,5)P6(2,7)AP1(2,2)扫描线算法描述1.建立ET表,置y为ET表中非空的最小y坐标值2.置AEL表为空,且按照y值将ET表的边加入AEL表中3.whileAEL表非空并且ET表中非空dobegin4.对AEL表中的xmin值按升序排列5.按照AEL表中交点前后次序,在每对奇偶交点间的x段予以填充6.if扫描线y=ymaxthen从AEL表中删除这些边7.对在AEL表中的其他边,计算与下一条扫描线的交点:x=x+1/m8.计算下一条扫描线:y=y+19.按照扫描线y值把ET表中相应的边加入AEL表中end10.endofalgorithm扫描线算法性能分析扫描线算法的数据结构和程序结构都远比逐点判断算法复杂,对各种表的维护和排序的耗费很大;但是由于它充分利用的多边形的区域、扫描线和边的三种形式的连贯性,从而避免了反复求交点的大量运算,因此速度比逐点判断法快的多。1.4边缘填充算法基本思想:在光栅图形中,如果某区域已经着上了为M的某种颜色,则对M做偶数次求补运算后,该区域的颜色不变;而做奇数次求补运算后,该区域则变为的颜色。因此,边缘填充算法对于每一条扫描线与多边形边的交点(x,y),依次将交点右方的所有象素取补,从而实现对多边形的填充。M算法实现步骤1:将位于扫描线y=e上的所有象素都着上值为M的颜色;forx:=xmintoxmaxdosetpixel(framebuffer,x,e,M);步骤2:对每一个交点xi,依次向右求补;fori:=1tomdoforx:=xitoxmaxdocomplement(framebuffer,x,e)当完成上述两个步骤后,扫描线y=e上位于多边形内部的象素进行了奇数次求补运算,并着上了的颜色。M改进:对于复杂的图形,一些象素可能被访问多次,一种改进的办法是引入栅栏。通过多边形设一栅栏,每次只对交点与栅栏之间的象素点取补,可使访问象素的次数减少。下图示出了这一算法的原理。边缘填充算法性能分析边缘填充算法的数据结构和程序结构都比扫描线算法简单的多。因为边缘填充算法用求补代替了排序,因此在算法执行时需要对帧缓冲器中的大批元素反复的赋值,因此速度不比扫描线算法快。1.5边界标志算法算法思想:先用一种特殊的颜色将多边形的边界勾画出来,然后在采用和扫描线算法相类似的方法将位于多边形内的各个区段着上所需要的颜色。边界标志算法实现步骤步骤1:以值为boundary-color的特殊颜色勾画多边形P的边界。可采用相应的直线生成算法;步骤2:逐条扫描线对多边形着色。先将扫描线上值为boundary-