试卷答题
课程名称:计算机图形学
姓名 年级:2011级 成绩
1、编写一程序实现,将中点画线算法推广以便能画出任意斜率的直线段。(10分)
答:
程序流程图:
开始输入坐标点|斜率|>1斜率为正yes斜率为正画线处理画线处理画线处理画线处理结束
核心函数:
void Midpoint(int x0,int y0,int x1,int y1)//画直线 {
int a,b,d1,d2,d,x,y; float dx=x1-x0; float dy=y1-y0; a=y0-y1,b=x1-x0;
if(fabsf(dx)>(fabsf(dy)))//判断斜率是否大于一 {
//斜率小于一 d=2*a+b;
d1=2*a,d2=2*a+2*b; x=x0,y=y0;
glBegin(GL_POINTS); glVertex3f(x,y,0);
glEnd();
if(y0<=yy1)//斜率为正 {
while(x x++,y++,d+=d2; } else{x++,d+=d1;}//否则取右方的点 glBegin(GL_POINTS); glVertex3f(x,y,0); glEnd(); } } else {//斜率小于0时 d=2*a-b; d2=2*a-2*b; while(x {//斜率大于一 d=2*b+a; d1=2*b,d2=2*a+2*b; x=x0,y=y0; glBegin(GL_POINTS); glVertex3f(x,y,0); glEnd(); if(y0<=yy1) { while(y glVertex3f(x,y,0); glEnd(); } } else { //斜率为负 d=a-2*b; d1=-2*b,d2=2*a-2*b; while(y>y1) { if(d<0){x++,y--,d+=d2;}//取右下方的点 else{y--,d+=d1;}//取右方的点 glBegin(GL_POINTS); glVertex3f(x,y,0); glEnd(); } } } } 流程图: 运行结果: 3、假设圆的圆心不在原点,试编写一个算法对整个圆进行扫描转换,需做出控制界面。(15分) 答:程序流程图 开始输入圆的圆心和半径初始化dx>yd>0d=d+4*(x-y)+10y--p=p+4*x+6x++输出xy结束 核心代码: void drawcircle(float xc,float yc,float radius) { xc=xc; yc=yc; xc=int(xc+0.5); yc=int(yc+0.5); cout< radius=y=int(radius+0.5); p=3-2*radius; while(x if(p<0)//如果p<0,说明正右方的点离圆上的点近,选取正右方的点 } p=p+4*x+6;//选取正右方的点,p的增量为4*x+6 else //如果p>=0,说明右下方的点离圆上的点近,选取右下方的点 { p=p+4*(x-y)+10;////选取右下方的点,p的增量为4*(x-y)+10 y-=1;//选取右下方的点时,要将y-- } x+=1;//无论选取哪一个点,x都要自增1 } if(x==y)//x>=y跳出循环 plot_circle_points(xc,yc,x,y); 运行结果: 4、编写一程序实现线段裁剪的中点分割算法,程序需演示逼近的步骤,并做出控制界面。(15分) 答: 流程图: 开始输入坐标坐标编码关键代码: void CS_LineClip(float x1,float y1,float x2,float y2) { float xm=0,ym=0; int code1,code2,code; //对两个顶点进行编码 code1=encode(x1,y1); code2=encode(x2,y2); float x,y,xx,yy;//临时存储两点坐标 否结束code1!=0||code2!=0是int(code1&code2)!=0否是确定要裁剪端点code直线在窗体外处理code在窗体左侧是窗体左侧处理否code在窗体有侧是窗体右侧处理code在窗体下侧窗体上侧处理否是窗体下侧处理否 环 while(code1!=0||code2!=0) { if(int(code1&code2)!=0)//如果code1&code2)!=0则直线在裁剪窗体外面 { Draw_windows(); return; } if(code1!=0) //判断是哪个端点在窗体外 { code=code1;//对code1端点赋值给code准备裁剪 x=x1; y=y1; xx=x2; yy=y2; } else { code=code2;//对code2端点赋值给code准备裁剪 x=x2; y=y2; xx=x1; yy=y1; } if(int(LEFT&code)!=0)//要裁剪的端点才窗体左侧 { do { xm=(x+xx)/2,ym=(y+yy)/2;//取中点 if(xm>window.XL)//判断中点是否在窗体可见侧 { //中点赋值给p2点 xx=xm; yy=ym; } else { //中点赋值给p1点 x=xm; y=ym; } draw_point(xm,ym); }while(fabsf(x-xx)>0.5||fabsf(y-yy)>0.5);//两点间距离小于某个常数退出循 环 环 } else if(int(RIGHT&code)!=0)//要裁剪的端点才窗体右侧 { do { xm=(x+xx)/2,ym=(y+yy)/2;//取中点 if(xm else if(int(BOTTOM&code)!=0) { do { xm=(x+xx)/2,ym=(y+yy)/2;//取中点 if(ym>window.YB)//判断中点是否在窗体可见侧 {//中点赋值给p2点 xx=xm; yy=ym; } else {//中点赋值给p1点 x=xm; y=ym; } draw_point(xm,ym); }while(fabs(x-xx)>1.0||fabs(y-yy)>1.0);//两点间距离小于某个常数退出循 } else if(int(TOP&code)!=0) { do { xm=(x+xx)/2,ym=(y+yy)/2;//取中点 if(ym } if(code==code1) { x1=xm;y1=ym;code1=encode(int(xm+0.5),int(ym+0.5)); } else { x2=xm;y2=ym;code2=encode(int(xm+0.5),int(ym+0.5)); } Draw_windows(); Draw_Line(x1,y1,x2,y2); } } 运行结果: 5、编写一程序实现多边形扫描转换算法中的扫描线填充算法,需做出控制界面。(15分) 流程图: 输入顶点建立新边表建立活性链表i=y值最小顶点i int max_y=0,MinY=1024; int i; for(i=0;i } { if(p0->ymax==i)//如果谋边扫描结束,就把他从活性边表中删除 { q->next=p0->next; delete p0; p0=q->next; } else//否则指针后移判断下一条边 { q=q->next; p0=q->next; } } p0=pNET[i]->next; q=pAET; while(p0)//将新边按大小顺序添加到活性边表中 { while(q->next && p0->x >= q->next->x) q=q->next; NET *s=p0->next; p0->next=q->next; q->next=p0; p0=s; q=pAET; } p0=pAET->next; //配对输出结果 while(p0 && p0->next) { for(float j=p0->x;j<=p0->next->x;j++) { glBegin(GL_POINTS); glVertex3f(j,i,0); glEnd(); glFlush(); } p0=p0->next->next; } } glEnd(); glFlush(); 运行结果: 6、编写程序实现,设有三角形ABC,其中三个顶点为A(1,3), B(5,10), C(10,12)求对于直线y=x+1的对称变换后的A’B’C’,并显示。(10分) 答:程序流程图 平移直线截距的距离旋转直线斜率的角度对称反旋转反平移 关键代码: void getXY(float x,float y)//计算操作后顶点 { X1=a[0][0]*x+a[0][1]*y+a[0][2]; Y1=a[1][0]*x+a[1][1]*y+a[1][2]; } void setABC()//得到操作后的三角形 { getXY(xa,ya); xa=X1;ya=Y1; getXY(xb,yb); xb=X1;yb=Y1; getXY(xc,yc); xc=X1;yc=Y1; } void mouse(int button, int state, int x, int y) { if(button == GLUT_RIGHT_BUTTON) { if(state == GLUT_DOWN) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); xa=10,ya=30,xb=50,yb=100,xc=100,yc=120; display(); left_click_count=0; right_click_count=0; } } else if(button == GLUT_LEFT_BUTTON) { if(state == GLUT_DOWN) { switch(left_click_count) { case 0:///平移 a[0][2]=0; a[1][2]=-10; setABC();// glColor3f( 1.0, 0.0, 1.0); seta(); draw_Triangle(); left_click_count++; break; case 1://旋转 a[0][0]=0.707; a[0][1]=0.707; a[1][0]=-0.707; a[1][1]=0.707; setABC(); glColor3f( 0.0, 0.0, 1.0); seta(); draw_Triangle(); left_click_count++; break; case 2: //对称 a[0][0]=1; a[1][1]=-1; setABC(); xc=X1;yc=Y1; glColor3f( 0.0, 1.0, 1.0); seta(); draw_Triangle(); left_click_count++; break; case 3: //旋转 a[0][0]=0.707; a[0][1]=-0.707; a[1][0]=0.707; a[1][1]=0.707; setABC(); glColor3f( 0.0, 0.0, 1.0); seta(); draw_Triangle(); left_click_count++; break; case 4: //平移 a[0][2]=0; a[1][2]=10; setABC(); glColor3f( 1.0, 0.0, 1.0); seta(); draw_Triangle(); left_click_count++; default: break; } } } } 运行结果: 7、在OPENGL下,编写一程序,采用顶点数组数据结构绘制立方体线框,用不同颜色绘制边线, 并让立方体绕对角线旋转45度. (20分) 答:流程图: 平移到原点旋转使得旋转轴与坐标轴重合旋转45反旋转反平移 关键代码: void myDisplay6(void) { glEnable(GL_DEPTH_TEST);//开启更新深度缓冲区的功能 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//清空 glMatrixMode(GL_PROJECTION);//glMatrixMode设置当前矩阵模式为投影矩阵 glLoadIdentity();//将当前点移到了屏幕中心 gluPerspective(75,1,1,400);//指定了观察的视景体 glMatrixMode(GL_MODELVIEW);//设置当前矩阵模式为模型视景矩阵 glLoadIdentity(); gluLookAt(3,3,3,1,1,1,0,0,1);//视点矩阵 draw_Coordinate();//画坐标系 glTranslatef(a[0][0],a[0][1],a[0][2]);//平移 glRotatef(45,0.0f,0.0f,1.0f);//旋转 glRotatef(54.74,0.0f,1.0f,0.0f);//旋转 glRotatef(45,0.0f,0.0f,1.0f);//旋转 glRotatef(54.74,0.0f,-1.0f,0.0f);//旋转 glRotatef(45,0.0f,0.0f,-1.0f);//旋转 glTranslatef(-a[0][0],-a[0][1],-a[0][2]);//平移 draw_cube();//画立方体 glutSwapBuffers(); } 运行结果: 8、在OPENGL下,已知单位正立方体,试编写一程序实现输出该形体的正平行投影和一点透视投影图。(15分) 答: 核心代码 void display0() { glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-2.5,2.5,-2.5,2.5,1.5,40); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(1.5,1.5,3.0,1.2,1.2,-4.5,0,0,1); draw_Coordinate(); draw_cube(); glutSwapBuffers(); } void display() { glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-4.0,4.0,-4.0,4.0,1,1200); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(8,8,8,0,0,0,1,0,0); draw_Coordinate(); draw_cube(); glutSwapBuffers(); } 运行结果: 9在OPENGL下,使用Grouraud明暗处理方法生成在一个球面的真实图形。(15分) 核心代码: void init(void) { GLfloat mat_specular[] = {0.0, 1.0, 0.0, 1.0}; GLfloat mat_shininess[] = {100.0}; GLfloat light_position[] = {1.0, 1.0f, 1.0, 0.0}; GLfloat white_light[] = {0.0, 1.0, 0.0, 1.0}; GLfloat lmodel_ambient[] = {0.1, 0.1, 0.1, 1.0};// 定义光模型参数 glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_SMOOTH);//光滑明暗模式 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);//光线照射到该材质上,经过镜面反射后形成的光线强度(颜色) glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);//镜面反射指数 //用定义好的光源属性给指定光源GL_LIGHT0进行设置 glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);//设置漫射光成分 glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);//设置镜面光成分 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);// 定义光模型 glEnable(GL_LIGHTING);//启用灯源 glEnable(GL_LIGHT0);//启用0号光源 glEnable(GL_DEPTH_TEST);//启用深度测试,根据坐标的远近自动隐藏被遮住的图形(材料) } 运行结果: 11、在OPENGL下,使用下列函数生成的棋盘纹理映射到一个球面上。(15分) 0,g(u,v)1,u*8v*8为奇数 u*8v*8为偶数关键代码: void makeCheckImages(void)//生成纹理 { int i, j, c; for (i = 0; i < checkImageHeight; i++) { for (j = 0; j < checkImageWidth; j++) { c = ((((i&0x8)==0)^((j&0x8)==0)))*255; checkImage[i][j][0] = (GLubyte) c; checkImage[i][j][1] = (GLubyte) c; checkImage[i][j][2] = (GLubyte) c; checkImage[i][j][3] = (GLubyte) 255; } } } int InitGL(GLvoid) { makeCheckImages(); glGenTextures(1, &texName); //根据纹理参数返回n个纹理索引 glBindTexture(GL_TEXTURE_2D, texName);//将纹理与纹理处理目标绑定 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);//S方向上的贴图模式,将纹理坐标在0.0,1.0的范围之内. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);//T方向上的贴图模式,将纹理坐标在0.0,1.0的范围之内. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);// 放大过滤,使用距离当前渲染像素中心最近的4个纹素加权平均值 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);//缩小过滤,使用距离当前渲染像素中心最近的4个纹素加权平均值 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage);//根据指定的参数,生成一个2D纹理 glEnable(GL_TEXTURE_2D);//// 启用二维纹理 GLUquadricObj *quadratic=gluNewQuadric(); //创建二次曲面对象 gluQuadricTexture(quadratic, GL_TRUE);//启用该二次曲面的纹理 gluSphere(quadratic,1.0, 50, 50);//创建一个球面对象 return true; }
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- cepb.cn 版权所有 湘ICP备2022005869号-7
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务