计算机图形学第6讲图元属性及图形处理华中科技大学吴义忠13545009970cad.wyz@hust.edu.cn主要内容图元属性:关键数据;颜色、点属性、线属性、曲线属性、填充属性、字符属性图元的一般处理填充算法裁剪算法反走样6.1图元属性——颜色颜色与灰度RGB模式与索引模式IndexRGBA模式(alfa)OpenGL颜色函数glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB)orGLUT_INDEXRGBA模式Index模式:voidglClearColor*();voidglClearIndex(GLfloatcindex);voidglSecondaryColor*();voidglEnable(GL_BLEND)6.1图元属性——点属性关键数据:点坐标颜色和大小样式(OpenGL不支持,可以自定义)voidglPointSize(GLintsize);6.1图元属性——线属性关键数据:起点、终点坐标颜色glColor*(…)线宽glLineWidth(wid)线型glEnable(GL_LINE_STIPPLE)glLineStipple(…);画笔和画刷:使用矩形笔画线,则画刷起作用(OpenGL未提供)6.1图元属性——曲线属性关键数据颜色线宽线型精度(显示曲线的段数)Bezier曲线/NURBS曲线(后)6.1图元属性——填充属性关键数据:实体集合填充颜色填充样式glPolygonStipple(pattern)填充区域glBegin/glEndglEnable(GL_POLYGON_STIPPLE)6.1图元属性——字符属性颜色字体大小位置、方向glTranslateglRotate6.2图元的一般处理属性改变:颜色、线型、宽度等;关键数据改变:图形变换:移动、旋转、放缩复制操作:拷贝粘贴、镜像、阵列关键点操作:拖动裁剪与延伸倒角与圆弧倒角……光栅显示的重要特点是能进行面着色,区域填充就是在一个闭合区域内填充某种颜色或图案。区域填充一般分两类:多边形填充和种子填充。表示内点表示边界点6.3区域填充算法多边形填充算法给定一顶点序列(Pi,i=0,1,…,n),依次连线构成一封闭多边形。多边形内点判别——射线法•若射线与多边形边界的交点个数为奇数时,则该点为内点;反之,交点个数为偶数时,则该点为外点。•当扫描线过多边形顶点时,则交点为奇异点。奇异点为局部极值点应看成两点,若为非极值点应看成一点。多边形填充算法多边形内点判别——夹角法夹角和为0,点p为外点;夹角和为360°,点p为内点CABDEPABCDEP这类算法建立在多边形边边界的矢量形式数据之上,可用于程序填色,也可用交互填色。该算法基于几何求交算法,步骤如下:•输入多边形顶点坐标;•求多边形顶点中最大和最小y坐标,以确定范围;•计算每条扫描线起止点(交点),并扫描填充,直至所有扫描线处理完毕。1)扫描线填充算法思路(Scan-LineFilling)算法步骤扫描线填充算法改进——边相关扫描线填充算法本算法改进的关键所在:•如何快速求扫描线与多边形交点;•扫描线填充利用画水平直线快速画法(为什么不用斜线?);•应该利用扫描线与多边形交点的连贯性加速求交算法(多边形与扫描线相交,则与下一条扫描线很可能相交,交点可直接计算)由于相邻扫描线上的交点是与多边形的边线相关的。对同一条边,前一条扫描线yi与该边的交点为xi,而后一条扫描线yi+1=yi+1与该边的交点则为xi+1=xi+1/m,利用相关性可省去大量求交运算(算法详见图形学教材)。这类算法建立在多边形边界的图象形式数据之上,并需提供多边形界内一点的坐标,一般只能用于人机交互填色,而难以用于程序填色。表示内点表示边界点从多边形内部点出发,沿四连通方向(或八连通方向)扩散搜索区域内所有待填充的象素点,适用于交互绘图。算法思想:用4连通填充算法的填充结果用8连通填充算法的填充结果2)种子填色算法(SeedFilling)种子填色算法(见Test1.vcprj)①给定多边形边界颜色及内部填充颜色;②从内部点(x,y)开始,检测该点与边界和填充色是否相同,均不相同则填充该点;③检测相邻点与边界和填充色是否相同,均不相同则填充该点;④重复第③步直至所有象素点被填充。算法步骤:算法特点:直接基于象素,用递归算法,不必求交。但递归太多,存储不够,易造成堆栈溢出。(可用一个大的矩阵记录象素填充的状态来避免递归算法)任意封闭区域的填充算法边界实体集合生成封闭性判断若封闭:得到边界实体集合的包容盒坐标转换:世界坐标-设备坐标每条扫描线求交根据交点显示扫描线3)图案填充算法(参考)实际应用中,有时需要用图案来填充平面区域,只需将种子填充算法中写象素的那部分代码修改。(种子点颜色改写为定义图案对应点颜色查表即可)定义填充图案是一个M×N的位图,用数组存放。M、N常比需要填充区域尺寸小得多(8×8、16×16等),图案设计成周期性的,使之重复使用构成任意尺寸图案。边界的处理?图案填充算法图案定位方法相对定位法:把图案原点与填充区域边界或内部的某点对齐。当被填充的多边形移动时,图案也跟着移动,看起来比较自然。对于多边形,可取边界上最左边的顶点,对于圆和椭圆这样具有光滑边界的区域,最好取区域内部某一点,如取中心与图案原点对齐。绝对定位法:把图案原点与屏幕原点对齐。将整个屏幕看成被要填充的图案布满,只是要填充的区域是透明的,可以让图案显露出来,其它区域对此图案却是不透明的,图案被全部挡住。这种方法比较简单,并且在相邻区域用同一图案填充时,可以达到无缝连接的效果。但它有一个潜在的毛病,即当区域移动时,图案不会跟着移动。其效果是区域内的图案变了。任意区间的图案填充算法前面同“实填充”根据对齐方式确定包容盒内任意像素点处的颜色根据交点信息确定哪些像素点显示OpenGL中的填充glBegin(GL_TRIANGLE/POLYGON/QUAD),等自动实现多边形填充设置glPolygonStipple(pattern)可实现图案填充,过程同字符绘制包容盒定义BoundingBox在计算机图形学、CAD、CAE中经常遇到相交(碰撞)测试。如鼠标拾取,视窗裁剪、曲面求交、光线跟踪、布尔运算、装配干涉校验、动画漫游、运动碰撞、机器人与机床刀具的轨迹规划等。尤其对较大规模数据的模型而言,处理相交(碰撞)测试的速度对系统效率影响很大。为加速测试计算速度,通常采用包容盒方法。1)相交(碰撞)测试算法轴对齐包容盒(矩形盒):通常称AABB,表面平行于坐标面。有向包容盒:简称OBB,即任意方向的AABB,往往由一个中心,三个单位矢量和三个半边长定义。AABBAxisAlignBBOBBOrientedBBn3n1n2n4s1d1maxd1minK-DOPKdiscreteorientedpolytope多边形/多面体包容盒环包容盒球体包容盒6.4多边形裁减算法直线的包围盒,计算直接利用其特征点——起始点和终点就可得到矩形的包围盒是其本身,圆的包围盒是该圆的边界矩形圆弧的包围盒,主要是由圆弧的起始点和终止点,以及与通过圆心的4个坐标轴相交的交点自由曲线的包容盒,可根据离散的小直线段的起始点和终止点比较后获得,若精确求解并不经济,因图形显示采用离散多边形,且图形变换频繁复杂组合图形的包容盒,可以在简单图形的包容盒基础上进行比较得到包容盒计算AABB:直接比较所有多面体(前面的离散多面体)顶点坐标即可得球体包容盒:计算麻烦。较为简单的方法是先计算AABB,再计算AABB的中心,以此为球心,球心到最远顶点的距离即为半径。其它更好更优的算法可查资料。显然,最远距离两点最为球的直径是最优解,关键是快速。OBB:计算方法较多,较繁琐。方法之一是:1)计算凸包;2)计算凸包质心;3)计算协方差矩阵的特征向量;4)其特征向量即为OBB三个方向;5)向三个方向投影即可求出半长值。AABB、圆球包容盒比较粗糙,各有优势。K-DOP比AABB更紧致,OBB则较k-DOP更优,选用何种包容盒视复杂度而定。相交测试1)尽可能用最简单算法排除或确定相交情形,如采用包容盒排除;2)充分利用前一次计算结果,尽量避免复杂计算(如sin,开方等);3)如果使用了多种测试,可以尝试改变内部顺序,或许会有意外收效;4)尽量降低维数,使问题简化,确保计算鲁棒性。算法实现的基本原则:求交计算是CG&CAD最常用算法,计算量大,其准确性与效率直接影响系统的可靠性与实用性。为加速测试过程,减小计算量,算法应注意:注意:在数学上两个浮点数可以严格相等,但计算机表示的浮点数有误差,难以绝对相等,相应地,求交运算中要引进容差。i)当两个点的坐标值充分接近时,即其距离充分近时,就被认为是重合的点,一般取∆=10-6或更小的数。ii)当两条直线的夹角接近0度(一般取∆=10-6或更小)时,就被认为是两条平行线。iii)同样,共线、共面、平行面等的判断也是近似的。2)多边形裁剪算法确定图形中哪些部分落在显示区之内,以便显示落在显示区内的那部分图形。这个选择过程称为裁剪。只有窗口内的物体才能显示,窗口之外的物体都是不可见的。Sutherland-Hodgeman多边形裁剪算法I.每次用窗口的一条边界(包括延长线)对要裁剪的多边形进行裁剪,裁剪时,顺序地测试多边形各顶点,保留边界内侧的顶点,删除外侧的顶点,同时,适时地插入新的顶点:即交点和窗口顶点,从而得到一个新的多边形顶点序列。II.然后以此新的顶点序列作为输入,相对第二条窗边界线进行裁剪,又得到一个更新的多边形顶点序列。III.依次下去,相对于第三条、第四条边界线进行裁剪,最后输出的多边形顶点序列即为所求的裁剪好了的多边形,如下图所示。(1)(2)(3)(4)新的多边形顶点序列产生规则:在用窗口一条边界及其延长线裁剪一个多边形时,该边界线把平面分成两个部分:边界内侧和边界外侧。如下图所示,依序考虑多边形的各条边。假设当前处理的多边形的边为SP(箭头表示顺序关系,S为前一点,P为当前点),边SP与裁剪线的位置关系只有下面四种情况:1、S在外侧,P在内侧。则交点Q、当前点P保存到新多边形中。2、S、P均在内侧。则当前点P保存到新多边形中。3、S在内侧,P在外侧。则交点Q保存到新多边形中。4、S、P均在外侧。则没有点被保存到新多边形中。算法思想(续):上述算法中点在边界内侧的判断方法:为了判断pi点是否在边界内侧,可用坐标比较法和向量叉积符号判别法。1)坐标比较法:将点的某个方向分量与边界进行比较。例如,判断某点是否在下边界内侧,用条件判别式:if(p[i][1]=ymin)即可。对其它边界也一样。2)向量叉积法:为简单计,测试点表示为P点。假设窗口边界方向为顺时针,如图中所示,对于其中任一边界向量,从向量起点A向终点B看过去,如果被测试点P在该边界线右边(即内侧),AB×AP的方向与X-Y平面垂直并指向屏幕里面,即右手坐标系中Z轴的负方向。反过来,如果P在该边界线的左边(即外侧),这时AB×AP的方向与X-Y平面垂直并指向屏幕外面,即右手坐标系中Z轴的正方向。Sutherland-Hodgeman多边形裁剪算法特点Sutherland-Hodgeman多边形裁剪算法具有一般性,被裁剪多边形可以是任意多边形,裁剪窗口不局限于矩形,可以是任意凸多边形。上面的算法是多边形相对窗口的一条边界进行裁剪的实现,对于窗口的每一条边界依次调用该算法程序,并将前一次裁剪的结果多边形作为下一次裁剪时的被裁剪多边形,即可得到完整的多边形裁剪程序。3)剖面线算法(任意多边形裁减,同实填充算法)剖面线是一组等距的平行线,用填充算法速度慢,直接多边形裁减更快,算法步骤:i)按多边形的初始条件及剖面线的角度和间距,计算剖面线的范围和数量;ii)求剖面线与轮廓边的相交位置;iii)对剖面线上的交点进行排序,并按奇偶规则绘制有效剖面线段。简