—1—xxxx2015—2016学年第一学期《高级计算机图形学》硕士试卷大题一二三四总分得分一、填空(将正确答案填入对应小题中,每小题3分,共30分)1、计算机图形学是研究利用计算机来的原理、方法和技术的一门学科。2、光栅图形子系统的两个重要部件是:。3、平行投影与透视投影区别是;正投影与斜投影的区别是。4、光栅图形子系统的两个重要部件是:。5、使用下面的二维图形变换矩阵:T=203010001产生变换的结果是。6、5×6的控制点网格可以构造片3次B样条曲面。7、OpenGL三维平行投影函数是。8、请写出斜二测投影的投影矩阵。9、OpenGL视点变换函数是。10、请写出OpenGL中清除深度缓存消隐的调用。二、选择填空(选择正确的答案填入对应题号,每小题2分,共20分)1、使用下列二维图形变换矩阵:︵︶—2—T=100001010,产生变换的结果为。A沿X坐标轴平移1个单位,同时沿Y坐标轴平移-1个单位B绕原点逆时针旋转90度C沿X坐标轴平移-1个单位,同时沿Y坐标轴平移1个单位D绕原点顺时针旋转90度2、下面哪个OpenGL函数的调用会改变材质的环境光系数。AglMaterialfv(GL_FRONT,GL_AMBIENT,amb)BglMaterialfv(GL_FRONT,GL_DIFFUSE,dif)CglLightfv(GL_FRONT,GL_AMBIENT,amb)DglLightfv(GL_FRONT,GL_DIFFUSE,dif)3、下面那种特性是Bezier曲线不具有的。A对称性B凸包性C通过特征多边形的起点和终点D局部支柱性4、下面几种连续变换,试问哪一种变换矩阵不能互换。A两个连续的旋转变换B两个连续的平移变换C两个连续的比例变换D平移变换与旋转变换5、下列有关投影的叙述语句中,正确的论述为。A透视投影与平行投影相比,能真实的反映物体的精确的尺寸和形状B平行投影的投影中心到投影面距离是有限的C透视投影的灭点可以有多个D斜平行投影的投影线与投影面是垂直的6、下面对于Bezier曲线端点的描述是最准确的。A曲线过多边形的端点P1和PnB曲线与多边形的端点直线P1P2和PnPn-1相切—3—C曲线过多边形的端点P1和Pn并与端点直线P1P2和PnPn-1相切D曲线无约束,仅与控制点有关。7、下面那种方法不会减少图形走样现象。A增加画线宽度B提高屏幕分辨率C使用区域采样算法D使用加权区域采样8、图形学使用齐次矩阵的原因是。A便于矩阵运算B便于表示平移变换C便于表示错切变换D有利于将二维图形变换为三维图形9、下面哪项不是三次样条曲线的常用约束条件。A自由端B抛物端C夹持端D闭合端10、下面关于Bresenham圆弧生成算法描述正确的是。ABresenham不必做四舍五入运算BBresenham算法速度快但效果没有DDA方法好CBresenham算法需要做除法DBresenham算法只能绘制八分之一圆弧三、问答题(共20分)1、试写出关于直线121xy对称的组合变换矩阵(10分)—4—2、请简要说明鼠标追踪球算法。(10分)—5—四、编程题(30分)1、试编写函数,drawRotateRect(intx0,inty0,intx1,inty1,intn,floatdelt);绘制如图所示的n个向内旋转矩形,其中x0,y0为矩形左上角坐标,x1,y1为矩形右下角坐标,delt为旋转角度,n为绘制矩形的数目。(15分)voiddrawRotateRect(intx0,inty0,intx1,inty1,intn,doubledelt);解:具体代码如下,voiddrawRotateRect(intx0,inty0,intx1,inty1,intn,doubledelt){inti,j,xm,ym,tx,ty;intr[4][2];doublesinAF,cosAF,s;xm=(x0+x1)/2;ym=(y0+y1)/2;sinAF=sin(delt);cosAF=cos(delt);s=1.0/(sinAF+cosAF);r[0][0]=x0;r[0][1]=y0;r[1][0]=x0;r[1][1]=y1;r[2][0]=x1;r[2][1]=y1;r[3][0]=x1;r[3][1]=y0;for(i=0;i4;i++){drawLine(r[i][0],r[i][1],r[(i+1)%4][0],r[(i+1)%4][1]);}for(j=0;jn;j++){for(i=0;i4;i++){//(1)平移到矩形中心r[i][0]-=xm;r[i][1]-=ym;//(2)旋转角度delttx=(int)(cosAF*r[i][0]-sinAF*r[i][1]);ty=(int)(sinAF*r[i][0]+cosAF*r[i][1]);r[i][0]=tx;r[i][1]=ty;//(3)缩放delt—6—r[i][0]=(int)(r[i][0]*s);r[i][1]=(int)(r[i][1]*s);//(4)反平移r[i][0]+=xm;r[i][1]+=ym;}for(i=0;i4;i++){drawLine(r[i][0],r[i][1],r[(i+1)%4][0],r[(i+1)%4][1]);}}}—7—2、用glsl语言编写顶点和片段Shader程序,点光源的逐点光照效果。(15分)解:在OpenGL中假定,不管观察者的角度如何,得到的散射光强度总是相同的。散射光的强度与光源中散射光成分以及材质中散射光反射系数相关,此外也和入射光角度与物体表面法线的夹角相关。OpenGL用下面的公式计算散射光成分:I是反射光的强度,Ld是光源的散射成分(gl_LightSource[0].diffuse),Md是材质的散射系数(gl_FrontMaterial.diffuse)。这个公式就是Lambert漫反射模型。Lambert余弦定律描述了平面散射光的亮度,正比于平面法线与入射光线夹角的余弦。在顶点shader中要实现这个公式,需要用到光源参数中的方向、散射成分强度,还要用到材质中的散射成分值。因此使用此shader时,在OpenGL中需要像在平时一样设置好光源。注意:由于没有使用固定功能流水线,所以不需要对光源调用glEnable。要计算余弦值,首先要确保光线方向向量(gl_LightSource[0].position)与法线向量都是归一化的,然后就可以使用点积得到余弦值。注意:对方向光,OpenGL中保存的方向是从顶点指向光源,与上面图中画的相反。OpenGL将光源的方向保存在视点空间坐标系内,因此我们需要把法线也变换到视点空间。完成这个变换可以用预先定义的一致变量gl_NormalMatrix。这个矩阵是模型视图变换矩阵的左上3×3子矩阵的逆矩阵的转置。以下就是上述内容的顶点shader代码:—8—voidmain(){vec3normal,lightDir;vec4diffuse;floatNdotL;/*firsttransformthenormalintoeyespaceandnormalizetheresult*/normal=normalize(gl_NormalMatrix*gl_Normal);/*nownormalizethelight'sdirection.NotethataccordingtotheOpenGLspecification,thelightisstoredineyespace.Alsosincewe'retalkingaboutadirectionallight,thepositionfieldisactuallydirection*/lightDir=normalize(vec3(gl_LightSource[0].position));/*computethecosoftheanglebetweenthenormalandlightsdirection.Thelightisdirectionalsothedirectionisconstantforeveryvertex.Sincethesetwoarenormalizedthecosineisthedotproduct.Wealsoneedtoclamptheresulttothe[0,1]range.*/NdotL=max(dot(normal,lightDir),0.0);/*Computethediffuseterm*/diffuse=gl_FrontMaterial.diffuse*gl_LightSource[0].diffuse;gl_FrontColor=NdotL*diffuse;gl_Position=ftransform();}—9—在片断shader中要做的就是使用易变变量gl_Color设置颜色。voidmain(){gl_FragColor=gl_Color;}图显示了应用此shader的茶壶效果。注意茶壶的底部非常黑,这是因为还没有使用环境光的缘故。加入环境光非常容易,只需要使用一个全局的环境光参数以及光源的环境光参数即可,公式如下所示:前面的顶点shader中需要加入几条语句完成环境光的计算:voidmain(){vec3normal,lightDir;vec4diffuse,ambient,globalAmbient;floatNdotL;normal=normalize(gl_NormalMatrix*gl_Normal);lightDir=normalize(vec3(gl_LightSource[0].position));NdotL=max(dot(normal,lightDir),0.0);diffuse=gl_FrontMaterial.diffuse*gl_LightSource[0].diffuse;/*ComputetheambientandglobalAmbientterms*/ambient=gl_FrontMaterial.ambient*gl_LightSource[0].ambient;—10—globalAmbient=gl_FrontMaterial.ambient*gl_LightModel.ambient;gl_FrontColor=NdotL*diffuse+globalAmbient+ambient;gl_Position=ftransform();}