计算机图形学课程设计.docx
- 文档编号:4970825
- 上传时间:2022-12-12
- 格式:DOCX
- 页数:32
- 大小:121.37KB
计算机图形学课程设计.docx
《计算机图形学课程设计.docx》由会员分享,可在线阅读,更多相关《计算机图形学课程设计.docx(32页珍藏版)》请在冰豆网上搜索。
计算机图形学课程设计
河南理工大学万方科技学院
课程设计报告
课程名称:
计算机图形学
设计题目:
直线快速裁剪算法
组成员:
专业班级:
08—计算机科学与技术—01
指导老师:
2011-6-12
第一章前言
计算机图形学(ComputerGraphics,简称CG)是一种使用数学算法将二维或三维图形转化为计算机显示器的栅格形式的科学。
简单地说,计算机图形学的主要研究内容就是研究如何在计算机中表示图形、以及利用计算机进行图形的计算、处理和显示的相关原理与算法。
计算机图形学的研究内容非常广泛,像图形硬件、图形标准、图形交互技术、光栅图形生成算法、曲线曲面造型、实体造型、真实感图形计算与显示算法、非真实感绘制,以及科学计算可视化、计算机动画、自然景物仿真、虚拟现实等。
经过40多年的发展,计算机图形学已成为计算机科学中,最为活跃的分支之一,并得到广泛的应用。
其中最重要的莫过于计算机辅助设计与制造(ComputerAidedDesign/ComputerAidedManufacture),例如AUTOCAD2008,Maya8.5,3dsMax9都是这方面最领先的图形学软件。
另外,在人们做研究分析时,可视化可以给予人们更清晰,更明了的结果。
而青少年们最关注的电子游戏方面更是少不了计算机图形学的帮助。
目前的次世代游戏机,索尼的PS3,微软的XBOX360上的游戏画面无疑给人以震撼的视觉冲击。
随着Nvidia的G80系列显卡及收购了ATI的AMD所推出的R600系列显卡的全面发售,微软的新一代图形API——DirectX10的威力很快也将全面爆发。
在今后的生活中,计算机图形学必将得到突飞猛进的发展。
随着计算机硬件的不断更新以及各种图形软件的不断推出,计算机图形学的应用前景将会更加引人入胜。
为了更好地学好计算机图形学,掌握一些最基本的知识,和一些简单的计算机图形学编程软件的操作和基本的库函数,特此进行了此次课程设计。
通过课程设计,学会一些基本的图形学软件的基本操作和库函数的应用,提高通过具体的平台实现图形算法的设计、编程与调试的能力,完成对实验结果分析、总结及撰写技术报告的能力。
第二章设计内容与要求
2.1总体目标和要求
总体目标:
以计算机图形学算法为基础,深入研究,继而策划、设计并实现一个能够实现直线快速裁剪的小型程序,并能分析出程序中出现的不足,能提出一些改进的意见。
通过程序设计的一般流程:
策划、设计、开发、测试、总结、验收等来学习程序的制作流程。
以此来达到以下几个目的:
(1)、了解计算机图形学中编程软件中的一些库函数,并掌握一些基本的库函数。
(2)、巩固已学习的计算机图形学的基本算法思想,熟悉图形学中的基本算法。
(3)、学习计算机图形学的简单算法的使用技巧。
(4)、培养认真学习,积极思索,勇于探索的精神。
(5)、提高通过具体的平台实现图形学算法的设计、编程与调试能力,完成对实验结果分析、总结及撰写技术报告的能力。
总体要求:
通过编程设计一个小程序,程序实现功能为跟据输入的连点来生成直线,通过相应的操作来实现窗口对直线的裁剪。
开发环境:
visualc++6.0+opengl
2.2内容与要求
设计分为七个部分,分别是:
1、矩形裁剪窗口的设计
矩形窗口的初始大小是100*100,要求在试验过程中矩形裁剪窗口的大小可以通过输入矩形窗口的长和宽来改变其大小。
2、4个编辑文本框的设计
四个编辑文本框只能输入数字,以此来控制两个输入点的位置来生成直线,同时通过输入矩形框的长和宽来控制矩形裁剪框的大小。
3、四个按钮的设计
四个按钮要实现四个功能。
分别是:
输入点的确定、裁剪区域窗口的刷新、实现相应的裁剪功能、和退出整个程序。
4、四个标签的设计
四个标签要显示:
X坐标、Y坐标、窗口长度、窗口宽度。
5、直线段的生成算法的设计
通过输入框输入直线段两端的坐标。
也通过鼠标在区域内左单击鼠标确定开始点,再单击左键确定终端,以此来形成一条待裁剪的直线段。
6、直线段裁剪
通过直线裁剪算法:
Cohen-Sutherland编码裁剪算法来进行直线段的裁剪。
第三章总体设计
3.1矩形裁剪窗口的设计
在图形裁剪区域中要形成一个矩形的裁剪窗口,用来对形成的直线进行裁剪。
其初始值为:
100*100,可以通过输入矩形裁剪窗口的长和宽来控制矩形窗口的大小,以此来对直线进行最适当的裁剪。
3.2个编辑文本框的设计
四个编辑框只能输入值只能是数字,以此来控制两个输入点x和y值,从而确定输入点的位置,依次输入两个点来生成一条待裁剪直线段。
同时也可以通过输入矩形框的长和宽来确定矩形裁剪框的大小。
3.3四个按钮的设计
在程序窗口的右侧要有四个按钮,要通过四个按钮来实现控制直线段的两个输入点的位置、对程序窗口进行刷新:
对裁剪后的直线段进行清除,仅剩下一个矩形裁剪框、对待裁剪直线段进行裁剪以及推出程序功能。
名称分别设定为:
输入点、刷新、运行算法、推出程序。
3.4四个标签的设计
在程序窗口中要创建四个标签,以此来提示输入框中输入的内容,四个标签分别显示为:
X坐标、Y坐标、窗口长度、窗口宽度。
3.5直线段的生成算法的设计
直线的生成有两种方法分别是通过键盘生成一条直线段;和通过鼠标生成一条直线段。
(1)、通过键盘生成一条直线段:
在程序界面的右侧的X坐标和Y坐标输入框中分别输入一个数值来确定一个端点,单击输入点,然后再输入一组X和Y的值来确定另一个坐标,以此来生成一条直线段。
(2)、通过鼠标生成一条直线段:
在程序界面的左侧裁剪框中用鼠标的左键单击任意位置生成一个端点,再单击另一个位置来生成另一个端点,从而生成一条直线段。
3.6直线段裁剪
通过直线裁剪算法:
Cohen-Sutherland编码裁剪算法来进行直线段的裁剪。
直线与矩形裁剪框的关系有三种分别是直线完全在裁剪窗口内、线段完全在裁剪窗口外、线段部分在裁剪窗口,部分在裁剪窗口外。
对直线段与裁剪窗口的三种不同关系有以下三种处理方法:
(1)、若线段完全在裁剪窗口之内,则显示该线段,成为“取”。
(2)、若线段明显在裁剪窗口之外,则丢弃该线段,成为“弃”。
(3)、若线段既不满足“取”的条件,也不满足“舍”的条件,则把线段分割为两段。
其中一段完全在裁剪窗口之外,可弃之;对另一段则重复上述操作。
第四章详细设计
4.1矩形裁剪窗口的设计
在图形裁剪区域中要形成一个矩形的裁剪窗口,用来对形成的直线进行裁剪。
其初始值为:
100*100,可以通过输入矩形裁剪窗口的长和宽来控制矩形窗口的大小,以此来对直线进行最适当的裁剪。
其部分代码如下:
(1)、矩形窗口的初始化:
this->m_length.SetWindowText("100");//初始化长度和宽度框为100
this->m_width.SetWindowText("100");
this->length=100;//初始化裁剪窗口为100*100
this->width=100;
this->s_pcount=0;//初始化输入点计数变量为0
(2)、矩形窗口的设置:
HCURSORCCohen_SutherlandDlg:
:
OnQueryDragIcon()
{
return(HCURSOR)m_hIcon;
}
voidCCohen_SutherlandDlg:
:
OnKillfocusEditLength()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
CStringbufl;//长度编辑框的文本临时缓存
charszChar[50];//提示语句缓存
this->m_length.GetWindowText(bufl);//获得长度编辑框的文本
//itoa(length,buf,10);
//dc.TextOut(100,100,buf);
if(bufl!
="")//如果长度框不为空就转换成int
{
length=atoi(bufl);
}
else//如果长度框为空就提示错误
{
sprintf(szChar,"长度不能为空");
MessageBox(szChar,"Error",0);
}
if(length<=300&&length>0)//如果长度范围在1-300那么就尝试显示裁剪窗口
{
if(width<=300&&width>0)//如果宽度在1-300之间就显示裁剪窗体
{
this->OnPaint();
}
}
else
{
sprintf(szChar,"长度必须为1-300之间的整数");
MessageBox(szChar,"Error",0);
}
}
4.2个编辑文本框的设计
四个编辑框只能输入值只能是数字,以此来控制两个输入点x和y值,从而确定输入点的位置,依次输入两个点来生成一条待裁剪直线段。
同时也可以通过输入矩形框的长和宽来确定矩形裁剪框的大小。
其部分控制代码如下:
this->m_length.SetLimitText(3);//编辑框设定只能输入3个字节
this->m_width.SetLimitText(3);
this->m_xpoint.SetLimitText(3);
this->m_ypoint.SetLimitText(3);
4.3四个按钮的设计
在程序窗口的右侧要有四个按钮,要通过四个按钮来实现控制直线段的两个输入点的位置、对程序窗口进行刷新:
对裁剪后的直线段进行清除,仅剩下一个矩形裁剪框、对待裁剪直线段进行裁剪以及推出程序功能。
名称分别设定为:
输入点、刷新、运行算法、推出程序。
4.4四个标签的设计
在程序窗口中要创建四个标签,以此来提示输入框中输入的内容,四个标签分别显示为:
X坐标、Y坐标、窗口长度、窗口宽度。
4.5直线段的生成算法的设计
直线的生成有两种方法分别是通过键盘生成一条直线段;和通过鼠标生成一条直线段。
(1)、通过键盘生成一条直线段:
在程序界面的右侧的X坐标和Y坐标输入框中分别输入一个数值来确定一个端点,单击输入点,然后再输入一组X和Y的值来确定另一个坐标,以此来生成一条直线段。
(2)、通过鼠标生成一条直线段:
在程序界面的左侧裁剪框中用鼠标的左键单击任意位置生成一个端点,再单击另一个位置来生成另一个端点,从而生成一条直线段。
两种直线段生成的方法的代码如下:
voidCCohen_SutherlandDlg:
:
OnButtonInpoint()//确定输入点函数,跟鼠标点击函数左右相同,只是输入点的方式不一样,利用编辑框进行输入
{
CStringbufx,bufy;//x,y坐标输入框的文本临时缓存
intx,y;//x,y坐标临时变量
charszChar[50];//提示语句缓存
this->m_xpoint.GetWindowText(bufx);//获得x坐标编辑框的文本
if(bufx!
="")//如果x框不为空就转换成int
{
x=atoi(bufx);
}
else//如果x框为空就提示错误
{
sprintf(szChar,"x坐标不能为空");
MessageBox(szChar,"Error",0);
}
this->m_ypoint.GetWindowText(bufy);//获得y坐标编辑框的文本
if(bufy!
="")//如果x框不为空就转换成int
{
y=atoi(bufy);
}
else//如果x框为空就提示错误
{
sprintf(szChar,"y坐标不能为空");
MessageBox(szChar,"Error",0);
}
if(x<300&&x>=0&&y<300&&y>=0)
{
this->p_group[s_pcount].x=x;
this->p_group[s_pcount].y=y;
s_pcount++;
}
else
{
sprintf(szChar,"x和y坐标必须在0-299之间");
MessageBox(szChar,"Error",0);
}
this->ShowLine(this->p_group,this->s_pcount);
}
voidCCohen_SutherlandDlg:
:
ShowLine(POINTp[],intcount)//将点数组的数据进行配对成直线进行显示
{
if(count<2)
return;
CDCdc;
HDChdc=:
:
GetDC(this->GetSafeHwnd());
dc.Attach(hdc);
intj=0;//临时变量,用来遍历点数组的
for(inti=0;i<=count/2;i++)
{
if(p[j].x!
=NULL&&p[j].y!
=NULL&&p[j+1].x!
=NULL&&p[j+1].y!
=NULL)
{
dc.MoveTo(p[j].x+11,p[j].y+11);
dc.LineTo(p[j+1].x+11,p[j+1].y+11);
}
j+=2;
}
dc.Detach();
:
:
ReleaseDC(this->GetSafeHwnd(),hdc);
}
voidCCohen_SutherlandDlg:
:
OnLButtonUp(UINTnFlags,CPointpoint)//画点函数,将点击鼠标的位置记录下来,并尝试进行绘制直线
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
if(point.x<311&&point.x>10&&point.y<311&&point.y>10)
{
this->p_group[s_pcount].x=point.x-11;
this->p_group[s_pcount].y=point.y-11;
s_pcount++;
}
this->ShowLine(this->p_group,this->s_pcount);
CDialog:
:
OnLButtonUp(nFlags,point);
}
unsignedcharCCohen_SutherlandDlg:
:
code(floatx,floaty)//对某点位置进行编码,有5种情况
{
unsignedcharc=0;//裁剪窗体里面,0000
if(((int)(x+0.5))<((int)(0.5+(300.0-length)/2)))//裁剪窗体左面,0001
c=c|1;
elseif(((int)(x+0.5))>((int)(0.5+(300.0-length)/2)+length))//裁剪窗体右边,0010
c=c|2;
if(((int)(y+0.5))<((int)(0.5+(300.0-width)/2)))//裁剪窗体上面,0100
c=c|4;
elseif(((int)(y+0.5))>((int)(0.5+(300.0-width)/2)+width))//裁剪窗体下面,1000
c=c|8;
returnc;
}
4.6直线段裁剪
通过直线裁剪算法:
Cohen-Sutherland编码裁剪算法来进行直线段的裁剪。
直线与矩形裁剪框的关系有三种分别是直线完全在裁剪窗口内、线段完全在裁剪窗口外、线段部分在裁剪窗口,部分在裁剪窗口外。
对直线段与裁剪窗口的三种不同关系有以下三种处理方法:
(1)、若线段完全在裁剪窗口之内,则显示该线段,成为“取”。
(2)、若线段明显在裁剪窗口之外,则丢弃该线段,成为“弃”。
(3)、若线段既不满足“取”的条件,也不满足“舍”的条件,则把线段分割为两段。
其中一段完全在裁剪窗口之外,可弃之;对另一段则重复上述操作。
其代码如下:
voidCCohen_SutherlandDlg:
:
Cohen_Sutherland_Clip(floatx1,floaty1,floatx2,floaty2,intcount)//对一条直线进行C_S算法,count是用来操作全局变量p_group的(用以更新全局变量的数据)
{
unsignedcharc1,c2,c;
floatx,y,wx,wy;
c1=code(x1,y1);//对第一点进行编码
c2=code(x2,y2);//对第二点进行编码
while((!
(c1==0))||(!
(c2==0)))//当两个点其中一个的编码不为零就进行循环,也就是说有一点不在裁剪窗体里面就进行循环
{
if(c1&c2)//当两个点都在裁剪窗体外面时删除这条线段,然后结束函数
{
this->p_group[count].x=NULL;
this->p_group[count].y=NULL;
this->p_group[count+1].x=NULL;
this->p_group[count+1].y=NULL;
return;
}
c=c1;
if(c==0)//找出在裁剪窗口外的一点
c=c2;
wx=x2-x1;
wy=y2-y1;
if((c&1)==1)//如果线段的一部分在窗体左面,那么根据窗口左边届的x坐标修计算其y坐标
{
y=y1+wy*((float)((300.0-length)/2)-x1)/wx;
x=(float)((300.0-length)/2);
}
elseif((c&2)==2)//如果线段的一部分在窗体右面,那么根据窗口右边届的x坐标修计算其y坐标
{
y=y1+wy*((float)(((300.0-length)/2)+length)-x1)/wx;
x=(float)(((300-length)/2)+length);
}
elseif((c&4)==4)//如果线段的一部分在窗体上面,那么根据窗口上边届的y坐标修计算其x坐标
{
x=x1+wx*((float)((300.0-width)/2)-y1)/wy;
y=(float)((300.0-width)/2);
}
elseif((c&8)==8)//如果线段的一部分在窗体下面,那么根据窗口下边届的y坐标修计算其x坐标
{
x=x1+wx*((float)(((300.0-width)/2)+width)-y1)/wy;
y=(float)(((300.0-width)/2)+width);
}
if(c==c1)//如果c1是窗口外的点,那么更新原来的线段数据到x1
{
x1=x;
y1=y;
c1=code(x1,y1);
}
else//如果c2是窗口外的点,那么更新原来的线段数据到x2,然后继续循环进行裁剪,直到线段在裁剪窗口里面为止
{
x2=x;
y2=y;
c2=code(x2,y2);
}
}//while()
this->p_group[count].x=(int)(0.5+x1);//更新线段到全局变量中
this->p_group[count].y=(int)(0.5+y1);
this->p_group[count+1].x=(int)(0.5+x2);
this->p_group[count+1].y=(int)(0.5+y2);
}
voidCCohen_SutherlandDlg:
:
OnOK()//运行算法按钮响应
{
//TODO:
Addextravalidationhere
if(this->s_pcount<1)
return;
CDCdc;
HDChdc=:
:
GetDC(this->GetSafeHwnd());
dc.Attach(hdc);
intj=0;//临时变量,用来遍历点数组的
for(inti=0;i<=(this->s_pcount+1)/2;i++)//每次两个点进行算法,不够两个就停止
{
this->Cohen_Sutherland_Clip((float)this->p_group[j].x,(float)this->p_group[j].y,(float)this->p_group[j+1].x,(float)this->p_group[j+1].y,j);
dc.MoveTo(this->p_group[j].x+11,this->p_group[j].y+11);
dc.LineTo(this->p_group[j+1].x+11,this->p_group[j+1].y+11);
j+=2;
}
dc.Detach();
:
:
ReleaseDC(this->GetSafeHwnd(),hdc);
this->OnPaint();
//CDialog:
:
OnOK();
}
voidCCohen_SutherlandDlg:
:
OnButtonClean()//刷新操作,就是清空点数组以及计数器s_pcount复位为0,然后重绘
{
//TODO:
Addyourcontrolnotificationhandlercodehere
for(inti=0;i<1000;i++)
{
this->p_group[i].x=NULL;
this->p_group[i].y=NULL;
}
this->s_pcount=0;
this->OnPaint();
}
voidCCohen_SutherlandDlg:
:
OnMouseMove(UINTnFlags,CPointpoint)//移动鼠标时如果已经输入了某点坐标,那么跟随鼠标移动显示直线
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
if((this->s_pcount%2)==1)
{
if(point.x<311&&point.x>10&&point.y<311&&point.y>10)
{
CDCdc;
HDChdc=:
:
GetDC(this->GetSafeHwnd());
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机 图形学 课程设计