8253030计算机图形学实验指导书.docx
- 文档编号:24603680
- 上传时间:2023-05-29
- 格式:DOCX
- 页数:41
- 大小:29.09KB
8253030计算机图形学实验指导书.docx
《8253030计算机图形学实验指导书.docx》由会员分享,可在线阅读,更多相关《8253030计算机图形学实验指导书.docx(41页珍藏版)》请在冰豆网上搜索。
8253030计算机图形学实验指导书
《计算机图形学》
实验指导书
华南农业大学信息学院信息学院
章晓华主编
目录
第一部分《计算机图形学》实验要求1
一、《计算机图形学》实验教学概述1
1、实验教学的基本情况1
2、实验教学的指导思想和教学目的1
3、实验项目表1
二、《计算机图形学》实验教学规范2
1、实验课的意义2
2、实验步骤2
3、实验报告(文档)规范2
4、实验考核3
第二部分实验内容4
实验一图元的生成算法4
实验二多边形填充7
实验三二维图形变换13
实验四直线Sutherland算法的实现21
实验五二维图形系统25
第一部分《计算机图形学》实验要求
一、《计算机图形学》实验教学概述
1、实验教学的基本情况
课程总学时数:
48学时;课程总学分:
3学分
实验总学时:
16
适用专业:
信息学院计算机科学与技术、软件工程、网络工程专业,软件学院软件工程专业
考核方式及方法:
实际操作+程序运行+实验报告。
实验成绩、考勤及书面作业成绩组成平时成绩。
平时成绩占课程总成绩30%,考试成绩占课程总成绩70%。
成绩评定:
在参考“难度系数”的基础上
>=90——选做内容/必做内容功能完善,编程风格好,人机接口界面好;
80~90——必做内容功能完善,完成部分选做内容,编程风格好,人机接口界面良好;
70~80——完成必做内容,编程风格良好;
60~70——能完成必做内容;
<60——未按时完成必做内容,或者抄袭(含雷同者)。
2、实验教学的指导思想和教学目的
1)指导思想:
掌握计算机图形的生成技术和生成各种平面图形和简单立体图形的基本算法,掌握图形填充、裁剪、图形变换及图形消隐等计算机图形处理的基本方法,初步掌握用C++语言编写基本图形生成和处理程序的方法,为后续的课程奠定良好的基础。
2)教学目的:
为了使学生在课程学习的同时,通过在具体的编程环境中的实际操作,对计算机图形学的基本概念和方法能有一个初步的了解,使学生加深了解和更好地掌握《计算机图形学》课程教学大纲要求的内容,并培养学生动手编程解决实际问题的能力,训练学生分析问题和调试程序的能力,锻炼学生撰写科技实验论文的能力。
3、实验项目表
实验项目
难度系数
实验类型
每组人数
实验一:
图元的生成算法
验证性
1
实验二:
多边形填充
验证性
1
实验三:
二维图形变换
验证性
1
实验四:
直线Sutherland算法的实现
验证性
1
实验五:
设计一个简单的图形系统
设计性
1
二、《计算机图形学》实验教学规范
1、实验课的意义
实验是对学生的一种全面综合训练。
是与课堂听讲、自学和练习相辅相成的必不可少的一个教学环节。
通常,实验题中的问题比平时的习题复杂得多,也更接近实际。
实验着眼于原理与应用的结合点,使学生学会如何把书上学到的知识用于解决实际问题,培养软件工作所需要的动手能力;另一方面,能使书上的知识变"活",起到深化理解和灵活掌握教学内容的目的。
平时的练习较偏重于如何编写功能单一的"小"算法,而实验题是软件设计的综合训练,包括问题分析、总体结构设计、用户界面设计、程序设计基本技能和技巧,多人合作,以至一整套软件工作规范的训练和科学作风的培养。
此外,还有很重要的一点是:
机器是比任何教师都严厉的检查者。
2、实验步骤
在《计算机图形学》的课程实验过程中,要求学生做到:
1)预习实验指导书有关部分,认真做好实验内容的准备,就实验可能出现的情况提前做出思考和分析。
2)认真书写实验报告。
实验报告包括实验目的和要求,实验情况及其分析。
写出程序设计说明,给出源程序框图和清单。
3)遵守机房纪律,服从辅导教师指挥,爱护实验设备
3、实验报告(文档)规范
实验报告的开头应首先包括如下成绩单表格,并填写班级、学号、姓名、题目等信息。
华南农业大学信息(软件)学院
《计算机图形》综合性、设计性实验成绩单
开设时间:
班级
学号
姓名
实验题目
把你选择的题目写在这里
成绩
教师签名
然后,在实验报告主体中包括以下六个内容:
1)需求分析
明确陈述说明程序设计的任务,强调的是程序要做什么,主要包括:
(1)输入的形式和输入值的范围;
(2)输出的形式;
(3)程序所能达到的功能;
(4)测试数据:
包括正确的输入及其输出结果和含有错误的输入及其输出结果。
2)概要设计
说明本程序中用到的所有抽象数据类型的定义、主程序的流程以及各程序模块之间的层次(调用)关系。
3)详细设计
实现概要设计中定义的所有数据类型,对每个操作只需要写出伪码算法;对主程序和其他模块也都需要写出伪码算法(伪码算法达到的详细程度应能够按照伪码算法在计算机键盘上直接输入高级程序设计语言程序);画出函数的调用关系图。
4)调试分析
内容包括:
(1)调试过程中遇到的问题是如何解决的以及对设计与实现的讨论和分析;
(2)算法的时间复杂性(包括基本操作和其他算法的时间复杂性的分析)和改进设想;
(3)设计过程的经验和体会;
(4)实现过程中出现的主要问题及解决方法。
5)用户使用说明
说明如何使用你编写的程序,详细列出每一步的操作步骤。
6)测试与运行结果
列出你的测试结果和运行情况(即运行时的关键画面),包括输入和输出。
这里的测试数据应该完整和严格,最好多于需求分析中所列。
值得注意的是,实验报告的各种文档资料,要在程序开发的过程中逐渐充实形成,而不是最后补写。
必要时可在实验报告中附部分关键源代码,但不需要附全部源代码。
4、实验考核
1)考核点:
编程(Programming:
50分)、测试分析(Testing&Analyzing:
20分)、实验报告(Documentation:
30分);
2)实验报告要求上交的内容包括:
①源代码及可执行程序(电子版);
②实验报告电子版;
③实验报告打印稿。
上交电子版文件要求以子目录格式,目录名形如:
200737401215张某某
上交时间与地点由任课教师指定。
第二部分实验内容
实验一图元的生成算法
一、实验目的
通过本次实验要求学生掌握Bresenham算法的基本原理和算法设计,并初步熟悉C/C++进行图形编程的方法。
二、实验内容及要求
实现绘制各种情况直线的Bresenham算法,并将实现的算法应用于任意多边形的绘制,要求多边形的顶点由键盘输入或鼠标拾取,绘制的多边形顶点要准确,图形应该封闭。
要求画出算法实现的程序流程图,使用VC++或Java实现算法,并演示。
三、算法设计
1)输入直线的起点坐标P0(x0,y0)和终点坐标(x1,y1)。
2)定义直线当前点坐标x和y,定义中点偏差判别式d,定义斜率k,定义像素点颜色rgb。
3)x=x0,y=y0,计算d=dx-2*dy,rgb=RGB(0,0,255)。
4)绘制点(x,y),判断d的符号。
若d<0,则(x,y)更新为(x+1,y+1),d更新为d+2*dx-2*dy;否则(x,y)更新为(x+1,y),d更新为d-2*dy。
5)如果当前点x小于x1,重复步骤(4),否则结束。
四、算法实现
1)分析各种情况下直线绘制的方法,确定直线绘制的算法流程
2)实现任意情况下的直线绘制算法,并测试该算法
3)上述算法测试成功后,考虑使用上述算法按次序连接多边形的顶点来绘制多边形。
实例程序(此代码为VC环境下使用)
voidBresenhamline(intx1,inty1,intx2,inty2)
{//对于所有直线均按照从左至右的方向绘制
if(x1>x2){
inttempx,tempy;
tempx=x1;x1=x2;x2=tempx;
tempy=y1;y1=y2;y2=tempy;
}
//根据斜率的情况不同而绘制
if(y1==y2){//斜率为0的情况
for(x=x1;x<=x2;x++)
pDC->SetPixel(x,y1,2);
}
elseif(x1==x2){//直线为垂直的情况
if(y1>y2){//使直线按从下往上画
inttempy=y1;
y1=y2;y2=tempy;
}
for(y=y1;y<=y2;y++)
pDC->SetPixel(x1,y,2);
}
else{
dy=y2-y1;
dx=x2-x1;
if(abs(dy)==abs(dx)){////斜率为1或-1时
x=x1;y=y1;
if(dy<0){//斜率为1
for(;y>=y2;y--){
x++;
pDC->SetPixel(x,y,2);
}
}//斜率为1
else{//斜率为-1
for(;y<=y2;y++){
x++;
pDC->SetPixel(x,y,2);
}
}//斜率为-1
}
elseif(abs(dy) if(dy>0&&dx>0){//斜率为正时 right=-2*dy; rightleft=2*dx-2*dy; d=dx-2*dy; x=x1;y=y1; while(x<=x2){ pDC->SetPixel(x,y,2); x++; if(d<0){ y++; d=d+rightleft; }else{ d=d+right; } } }//斜率为正时 else{//斜率为负时 right=2*dy; rightleft=2*dy-2*dx; d=2*dy-dx; x=x1;y=y1; while(x<=x2){ pDC->SetPixel(x,y,2); x++; if(d<0){ y++; d=d+rightleft; }else{ d=d+right; } } }//斜率为负时 }//斜率的绝对值小于1时 else{//斜率的绝对值大于1时 if(dy>0&&dx>0){//斜率为正时 right=2*dx; rightleft=2*dx-2*dy; d=2*dx-dy; x=x1;y=y1; while(y<=y2){ pDC->SetPixel(x,y,2); y++; if(d>=0){ x++; d=d+rightleft; }else{ d=d+right; } } }//斜率为正时 else{//斜率为负时 right=-2*dx; rightleft=-2*dx-2*dy; d=-2*dx-dy; x=x1;y=y1; while(y>=y2){ pDC->SetPixel(x,y,2); y--; if(d<0){ x++; d=d+rightleft; }else{ d=d+right; } } }//斜率为负时 }//斜率的绝对值大于1时 }//斜率的所有情况 } 实验二多边形填充 一、实验目的 通过本次实验要求学生掌握多边形区域扫描线填充的有序边表算法的基本原理和算法设计。 要求画出算法实现的程序流程图,使用Java或者VC++实现算法,并演示。 二、实验内容及要求 实现多边形区域扫描线填充的有序边表算法,设计相关的数据结构(如链表结构、结点结构等),并将实现的算法应用于任意多边形的填充,注意多边形的顶点应由键盘输入或鼠标拾取,填充要准确,不能多填也不能少填。 三、实验步骤 1)分析多边形区域扫描线填充算法的原理,确定算法流程 1初始化: 构造边表,AET表置空 2将第一个不空的ET表中的边插入AET表 3由AET表取出交点进行配对(奇偶)获得填充区间,依次对这些填充区间着色 4y=yi+1时,根据x=xi+1/k修改AET表所有结点中交点的x坐标。 同时如果相应的ET表不空,则将其中的结点插入AET表,形成新的AET表 5AET表不空,则转(3),否则结束。 2)编程实现 1首先确定多边形顶点和ET/AET表中结点的结构 2编写链表相关操作(如链表结点插入、删除和排序等) 3根据1)中的算法结合上述已有的链表操作函数实现多边形区域扫描线填充的主体功能 4编写主函数,测试该算法 四、算法实现 classAET { public: AET(); virtual~AET(); doublex; intyMax; doublek;//代替1/k AET*next; }; classBucket { public: Bucket(); virtual~Bucket(); intScanLine; AET*p;//桶上的边表指针 Bucket*next; }; voidCTestView: : CreatBucket()//建立桶结点 { intScanMin,ScanMax;//确定扫描线的最小值和最大值 ScanMax=ScanMin=Point[0].y; for(inti=1;i { if(Point[i].y { ScanMin=Point[i].y;//扫描线的最小值 } if(Point[i].y>ScanMax) { ScanMax=Point[i].y;//扫描线的最大值 } } for(i=ScanMin;i<=ScanMax;i++)//建立桶结点 { if(ScanMin==i)//桶头结点 { HeadB=newBucket;//建立桶的头结点 CurrentB=HeadB;//CurrentB为Bucket当前结点指针 CurrentB->ScanLine=ScanMin; CurrentB->p=NULL;//没有连接边链表 CurrentB->next=NULL; } else//建立桶的其它结点 { CurrentB->next=newBucket;//新建一个桶结点 CurrentB=CurrentB->next;//使CurrentB指向新建的桶结点 CurrentB->ScanLine=i; CurrentB->p=NULL;//没有连接边链表 CurrentB->next=NULL; } } } voidCTestView: : Et()//构造边表 { for(inti=0;i { CurrentB=HeadB;//从桶链表的头结点开始循环 intj=i+1;//边的第二个顶点,Point[i]和Point[j]构成边 if(j==Number)j=0;//保证多边形的闭合 if(Point[j].y>Point[i].y)//终点比起点高 { while(CurrentB->ScanLine! =Point[i].y)//在桶内寻找该边的yMin { CurrentB=CurrentB->next;//移到下一个桶结点 } E[i].x=Point[i].x;//计算AET表的值 E[i].yMax=Point[j].y; E[i].k=double((Point[j].x-Point[i].x))/(Point[j].y-Point[i].y);//代表1/k E[i].next=NULL; CurrentE=CurrentB->p;//获得桶上链接边表的地址 if(CurrentB->p==NULL)//当前桶结点上没有链接边结点 { CurrentE=&E[i];//赋边的起始地址 CurrentB->p=CurrentE;//第一个边结点直接连接到对应的桶中 } else { while(CurrentE->next! =NULL)//如果当前边已连有边结点 { CurrentE=CurrentE->next;//移动指针到当前边的最后一个边结点 } CurrentE->next=&E[i];//把当前边接上去 } } if(Point[j].y { while(CurrentB->ScanLine! =Point[j].y) { CurrentB=CurrentB->next; } E[i].x=Point[j].x; E[i].yMax=Point[i].y; E[i].k=double((Point[i].x-Point[j].x))/(Point[i].y-Point[j].y); E[i].next=NULL; CurrentE=CurrentB->p; if(CurrentE==NULL) { CurrentE=&E[i]; CurrentB->p=CurrentE; } else { while(CurrentE->next! =NULL) { CurrentE=CurrentE->next; } CurrentE->next=&E[i]; } } } CurrentB=NULL; CurrentE=NULL; } voidCTestView: : AddEdge(AET*NewEdge)//插入临时边表 { T1=HeadE; if(T1==NULL)//边表为空,将边表置为TempEdge { T1=NewEdge; HeadE=T1; } else { while(T1->next! =NULL)//边表不为空,将TempEdge连在该边之后 { T1=T1->next; } T1->next=NewEdge; } } voidCTestView: : EdgeOrder()//对边表进行排序 { T1=HeadE; if(T1==NULL) { return; } if(T1->next==NULL)//如果该边表没有再连边表 { return;//桶结点只有一条边,不需要排序 } else { if(T1->next->x { T2=T1->next; T1->next=T2->next; T2->next=T1; HeadE=T2; } T2=HeadE; T1=HeadE->next; while(T1->next! =NULL)//继续两两比较相连的边表的x值,进行排序 { if(T1->next->x { T2->next=T1->next; T1->next=T1->next->next; T2->next->next=T1; T2=T2->next; } else { T2=T1; T1=T1->next; } } } } voidCTestView: : PolygonFill()//多边形填充 { HeadE=NULL; for(CurrentB=HeadB;CurrentB! =NULL;CurrentB=CurrentB->next)//访问所有桶结点 { for(CurrentE=CurrentB->p;CurrentE! =NULL;CurrentE=CurrentE->next)//访问桶中排序前的边结点 { AET*TempEdge=newAET; TempEdge->x=CurrentE->x; TempEdge->yMax=CurrentE->yMax; TempEdge->k=CurrentE->k; TempEdge->next=NULL; AddEdge(TempEdge);//将该边插入临时Aet表 } EdgeOrder();//使得边表按照x递增的顺序存放 T1=HeadE;//根据ymax抛弃扫描完的边结点 if(T1==NULL) { return; } while(CurrentB->ScanLine>=T1->yMax)//放弃该结点,Aet表指针后移(下闭上开) { T1=T1->next; HeadE=T1; if(HeadE==NULL) { return; } } if(T1->next! =NULL) { T2=T1; T1=T2->next; } while(T1! =NULL) { if(CurrentB->ScanLine>=T1->yMax)//跳过一个结点 { T2->next=T1->next; T1->next=NULL; T1=T2->next; } else { T2=T1; T1=T2->next; } } BOOLIn=false;//设置一个BOOL变量In,初始值为假 doublexb,xe;//扫描线的起点和终点 for(T1=HeadE;T1! =NULL;T1=T1->next)//填充扫描线和多边形相交的区间 { if(In==false) { xb=T1->x; In=true;//每访问一个结点,把In值取反一次 } else//如果In值为真,则填充从当前结点的x值开始到下一结点的x值结束的区间 { x
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 8253030 计算机 图形学 实验 指导书