球体消隐课程设计报告.docx
《球体消隐课程设计报告.docx》由会员分享,可在线阅读,更多相关《球体消隐课程设计报告.docx(13页珍藏版)》请在冰豆网上搜索。
球体消隐课程设计报告
一.设计内容与要求…………………………………………2
1.1总体目标和要求……………………………………2
1.2内容与要求…………………………………………2
二.总体设计…………………………………………………2
2.1球的消隐处理基本原理……………………………2
2.2具体设计实现………………………………………3
三.详细设计…………………………………………………3
3.1程序流程图…………………………………………3
3.2调试后正确的程序清单……………………………5
4.功能实现………………………………………………10
4.1程序运行结果………………………………………10
4.2功能实现及分析……………………………………10
5.总结……………………………………………………11
6.参考文献………………………………………………11
球体背面剔除消隐算法
第1章设计内容与要求
1.1总体目标和要求
课程设计的目的:
以图形学算法为目标,深入研究。
继而策划、设计并实现一个能够表现计算机图形学算法原理的或完整过程的演示系统,并能从某些方面作出评价和改进意见。
通过完成一个完整程序,经历策划、设计、开发、测试、总结和验收各阶段,达到:
1)巩固和实践计算机图形学课程中的理论和算法;
2)学习表现计算机图形学算法的技巧;
3)培养认真学习、积极探索的精神;
4)具备通过具体的平台实现图形算法的设计、编程与调试的能力;
5)完成对实验结果分析、总结及撰写技术报告的能力。
总体要求:
策划、设计并实现一个能够充分表现图形学算法的演示系统,界面要求美观大方,能清楚地演示算法执行的每一个步骤。
开发环境:
ViusalC++6.0
1.2内容与要求
球体背面剔除消隐算法
内容:
(1)掌握背面剔除消隐算法原理;
(2)实现矢量点积与叉积运算;
(3)透视投影变换
(4)曲面体经纬线划分方法
功能要求:
(1)绘制球体线框模型的透视投影图,使用背面剔除算法实现动态消隐;
(2)通过右键菜单显示消隐效果,右键菜单有两个选项:
未消隐与消隐;
(3)使用键盘的上下左右控制键旋转消隐前后的球体;
(4)单击左键增加视距,右击缩短视距;
第2章总体设计
2.1球的消隐处理基本原理
球体的曲面通常采用一组网格多边形来表示,即把曲面离散成许多小平面片,用平面逼近曲面,一般使用许多四边形来逼近曲面。
网格四边形愈多,逼近曲面的精度就愈高,逼近效果就愈好,曲面看起来就越光滑。
一般根据实际需要来确定合适的逼近精度即网格多边形数目。
当曲面表示为一组网格多边形时,消隐处理的主要工作是确定各网格多边形的可见性,由此可用平面立体的算法对曲面进行消隐处理。
球面的参数方程为:
x=R·sina·cosβ
y=R·sina·sinβ(0≤a≤π,0≤β≤2π)
z=R·cosa
设两个参数a和β对球面进行网格化,当相邻的曲线参数分别为a1、a2、β1、β2时,构成四边形网格P0P1P2P3,其外法线N表示如下:
N=P0P1×P1P2
对N进行单位化:
n={nx,ny,nz}=n/|N|
若设视方向为S,其平行于y轴:
S={0,1,0}
①n·S=ny≥0,网格可见,画出;
②n·S=ny<0,网格不可见,不画
2.2具体设计实现
(1)掌握运行环境VisualC++编程、调试方法,熟练掌握OpenGL的使用,并能将两者相结合完成实验设计;
(2)理解球体背面剔除消隐算法的基本原理;
(3)利用OpenGL中的函数绘制一个线框球并显示出来。
具体方案如下:
(a)先通过透视投影变换绘制出小四边形平面片,进行球体线框模型的绘制。
(b)完成球体的绘制后,进行设置球体的旋转效果,根据球体背面剔除消隐算法来完成球体的动态消隐。
(c)创建右键菜单显示消隐效果,右键菜单有未消隐和消隐两个选项。
(d)设置使用键盘的上下左右控制键旋转消隐前后的球体。
(e)设置单击鼠标左键增加视距,右击缩短视距。
(f)编写主函数,然后编写以上思想的子函数,对整个程序进行基本的代码编写,分模块完成所要求的各个功能,最后进行代码的运行和调试。
第3章详细设计
3.1程序流程图
程序主流程图
3.2调试后正确的程序清单
#include
#include
#defineNO_XIAOYIN1
#defineXIAOYIN2
staticfloata=1.0f,b=0.0f,c=0.0f;
GLfloatrtri,r=1.0f;//旋转角度
boolbXiaoyin=true;
voidinit(void)
{
glClearColor(0.0f,0.0f,0.0f,0.0f);
glShadeModel(GL_SMOOTH);//设为smooth处理方式
glEnable(GL_DEPTH_TEST);//激活深度测试
}
voiddisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//清除颜色缓存和深度缓存
glLoadIdentity();
glTranslatef(-1.0f,0.0f,-4.0f);//控制球的位置和大小
glRotatef(rtri,a,b,c);//旋转
glColor3f(0.0f,1.0f,0.0f);//控制球的颜色
if(bXiaoyin)
glutWireSphere(r,45,30);//初始化线框球球体围绕z轴分割45
次,球体沿着z轴分割30次
else
{
glDisable(GL_TEXTURE_2D);
glColorMask(0,0,0,0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glPolygonOffset(1.1f,4.0f);
glEnable(GL_POLYGON_OFFSET_FILL);
//auxSolidSphere(1.0);
glutSolidSphere(r,45,30);//实心球
glDisable(GL_POLYGON_OFFSET_FILL);
glColorMask(1,1,1,1);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
//auxSolidSphere(1.0);
glutSolidSphere(r,45,30);
}
glutSwapBuffers();//交换双缓存
}
voidreshape(intwidth,intheight)//对屏幕窗口的形状进行调整
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
voidprocessMenuEvents(intoption)//此函数处理根据菜单选项来执行的动作
{
switch(option){
case1:
bXiaoyin=true;
glutPostRedisplay();
break;
case2:
bXiaoyin=false;
glutPostRedisplay();
break;
}
}
voidcreateGLUTMenus()//创建菜单
{
intmenu;
menu=glutCreateMenu(processMenuEvents);
glutAddMenuEntry("消隐",XIAOYIN);//在菜单中添加选项
glutAddMenuEntry("未消隐",NO_XIAOYIN);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
voidkeyboard(unsignedcharkey,intx,inty)////键盘控制球体的缩放
{
switch(key)
{
case'o':
r+=0.1f;
glutPostRedisplay();
break;
case'i':
r-=0.1f;
glutPostRedisplay();
break;
case'x':
exit(0);
break;
default:
break;
}
}
voidkeyboard1(intkey,intx,inty)
{
switch(key)
{
caseGLUT_KEY_LEFT:
//向左旋转
a=0.0f;
b=1.0f;
c=0.0f;
rtri-=2.0f;//减一个角度
glutPostRedisplay();//重画
break;
caseGLUT_KEY_RIGHT:
//向右旋转
a=0.0f;
b=1.0f;
c=0.0f;
rtri+=2.0f;//加一个角度
glutPostRedisplay();
break;
caseGLUT_KEY_UP:
//向上旋转
a=1.0f;
b=0.0f;
c=0.0f;
rtri-=2.0f;
glutPostRedisplay();
break;
caseGLUT_KEY_DOWN:
//向下旋转
a=1.0f;
b=0.0f;
c=0.0f;
rtri+=2.0f;
glutPostRedisplay();
break;
default:
break;
}
}
voidmouse(intbutton,intstate,intx,inty)//用鼠标实现放大缩小
{
switch(button)
{
caseGLUT_LEFT_BUTTON:
r+=0.1f;
glutPostRedisplay();
break;
caseGLUT_RIGHT_BUTTON:
r-=0.1f;
glutPostRedisplay();
break;
default:
break;
}
}
intmain(intargc,char**argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
//使用双缓存模式和深度缓存
glutInitWindowSize(800,500);//窗口大小
glutInitWindowPosition(200,200);//窗口在屏幕的位置
glutCreateWindow("球体消隐");
init();
glutDisplayFunc(display);//注册重绘函数
glutReshapeFunc(reshape);//注册改变窗口形状函数
glutKeyboardFunc(keyboard);//注册键盘动作函数
glutSpecialFunc(keyboard1);//注册特殊键盘动作函数
glutIdleFunc(display);//设置空闲时调用的函数
glutMouseFunc(mouse);//注册鼠标动作函数
createGLUTMenus();
glutMainLoop();//进入主循环等待事件发生
return0;
}
第4章功能实现
4.1程序运行结果
运行结果如下图所示
消隐前消隐后
4.2功能实现及分析
此次程序设计运用计算机图形学所学到的知识,基本完成了课程设计所要求的功能。
以下为本实验能实现的功能:
(1)绘制了一个球体线框模型的透视投影图,并使用背面剔除算法实现动态消隐,利用glutWireSphere(r,45,30);函数初始化一个线框球,球体围绕z轴分割45次,沿着z轴分割30次
(2)通过右键菜单显示消隐效果,右键菜单有两个选项:
未消隐与消隐,主要利用processMenuEvents()函数和createGLUTMenus()实现。
processMenuEvents()函数体是一个典型的switch语句。
(3)使用键盘的上下左右控制键旋转消隐前后的球体;上键由内向外旋转,下键由外向内旋转,左键向左旋转,右键向右旋转。
(4)单击左键增加视距,右击缩短视距,同时利用键盘字母“i”实现球体的缩小,字母“o”控制球体的放大,字母“x”为退出窗口界面。
第5章总结
课程设计是对所学课程的一个综合应用,是对所学课程掌握全面与否的检验。
由于对OpenGL算法与VC++编程不是很熟悉,在设计过程中遇到了一些困难。
不过通过老师、同学的指导,以及自己查阅相关资料,这些疑惑就全部解决了,因此课程设计才得以顺利完成。
本次计算机图形学的课程设计,使我对图形学有了更深一步的认识,深切感受到图形学在如今的广泛应用,学到了许多新知识。
OpenGL的图形绘制函数有多种,我通过查询资料一一弄懂各个函数的含义。
然后根据消隐知识,掌握球体消隐算法的基本原理和算法思想,进而实现了球体的动态消隐。
在程序设计过程中也存在不足,由于自身编程经验的缺乏,开始时遇到了一些困难。
比如用程序实现上下左右键盘对球体的控制,查了很多资料还是没找到,最后在同学的帮助下轻易的完成。
认识到自己的不足,在以后的学习中我会努力改正。
参考文献
1、计算机图形学徐文鹏机械工业出版社2009.02
2、计算机图形学实践教程孔令德清华大学出版社2008.05
3、计算机图形学实用技术陈元琰、张晓竞科学出版社2000.09
4、VisualC++6.0编程王建平科学出版社2000.08
5、计算机图形学何援军机械工业出版社2009