计算机图形学实验报告.docx_第1页
计算机图形学实验报告.docx_第2页
计算机图形学实验报告.docx_第3页
计算机图形学实验报告.docx_第4页
计算机图形学实验报告.docx_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实 验 报 告课程名称:计算机图形学学 院:信息科学与工程学院专 业:数字媒体技术班 级:2013级姓 名:李义学 号:2013010520152015年12月19日山东科技大学教务处制目录:实验一:环境设置 3实验二:直线的生成算法4实验三:圆的生成算法6实验四:扫描填充算法7实验五:裁剪算法11实验六:Bezier曲线14实验一:环境设置一、实验目的和要求:1、了解和使用TurboC提供的基本图形函数2、像素点的生成3、掌握Turbo C 进行图形程序设计的基本方法;.4熟悉Visual C+实验环境二、实验内容:1.Turbo C集程序编辑、编译、连接、调试为一体具有速度快、效率高、功能强等优点。Turbo C是基于DOS平台的C编译系统,占用系统资源少,提供的界面直观、易用。程序的编译、连接、调试、运行、环境设置等工作都在同一界面上进行,从而用户使用非常方便。用户在使用Turbo C之前,必须将Turbo C系统安装在用户的磁盘上,建立一个Turbo C的使用环境。运行Turbo C有两种方式:1)由DOS平台进入Turbo C,2) 由Windows平台进入Turbo C.一个新建立的文件,也可以是一个已存在的文件。编辑好源文件存盘后,下面的工作就是对源文件(可以是单个文件,也可是多个文件)进行编译、连接和运行。在Turbo C中,对源程序进行编译、连接和运行可以分三步单独进行,也可以将编译和连接同时进行,然后运行;或者将编译、连接和运行一次完成。说明:(1)在操作完成后应选Project下的Clear Project,清空当前有效的项目文件(用Project name 指定的),否则系统在以后的编译中仍编译该项目文件,而不是当前编辑屏幕中的源程序。(2)多文件编译中因出错停止编译的方式用户需要用Project的子菜单Break make on进行设置(图 14)。Errors表示编译完一个文件后,有“错误”信息就停止编译。Warnings表示编译完一个文件后,有“警告”以上信息就停止编译。Fatal errors表示编译完所有文件后,停止编译。Link进行连接之前停止编译。图 14当程序在编译、连接中没有错误,但运行结果不正确的情况下,我们通常用以下两种方法调试程序。1)跟踪进入方法,2) 设置断点方法。设置Turbo C 环境参数是指出包含文件和库文件存放的位置以及输出文件(.OBJ和.EXE)准备存放的位置。设置Turbo C 环境参数通过主菜单Options中的选项完成,如图21。图 212 熟悉Visual C+实验环境(1)启动Developer Studio,了解初始化界面由哪些部分组成查看各菜单项,看看都有哪些子菜单和命令(2) 将鼠标放置于各工具条图标上,系统会自动显示该图标代表的命令含义,了解一下都有哪些命令。(3) 在任意工具条上单击鼠标右键,弹出式菜单上将显示所有可用的工具条,选择其中没有对号()的项,看看有什么效果,再选择有对号的项看有什么效果。(4) 将鼠标移动到任意工具条上,将鼠标放到图标间隙,按下鼠标左键不放,移动鼠标到屏幕中间,看有什么现象发生,再将它拖回到原来位置观察有什么现象发生。(5) 将鼠标移动到下边的输出窗口,按鼠标右键,弹出一个菜单,选择其中的菜单项”Hide”,选择菜单View|Output,重新显示该窗口,看窗口是不是又显示出来了。(6) 学习使用帮助系统。在Visual C+5.0中,在工作区窗口的InfoView中选择内容,双击它,在文档区显示具体的帮助信息。在Visual C+6.0,选择菜单Help|Contents,启动MSDN联机帮助系统,学习使用该帮助系统。选File|Exit退出Developer Studio。(2)像素是组成图形的最小单位,像素的大小可以通过设置不同的显示方式来改变。该实验实现了简单圆的生成(3)基于Turbo C的开发环境实现人造卫星运动动画。实验二:直线的生成算法一、 实验目的1、 通过用中点画线法绘制直线,加深对算法原理的理解。2、 对程序以及函数的细节有更深入的把握。二、 实验要求实现一个直线的中点生成算法的程序三、 实验原理当前像素点为(xp,yp),下一个像素点有两个可选择点P1(xp+1,yp+1)或P2(xp+1,yp+1)。若M=(xp+1,yp+0.5)为P1与P2之中点,Q为理想直线x=xp+1垂线的交点。当M在Q的下方时,则P2 应为下一个象素点;M在Q的上方,应取P1为下一点。构造判别式:d=F(M)=F(xp+1,yp+0.5) =a(xp+1)+b(yp+0.5)+c其中a=y0-y1, b=x1-x0, c=x0y1-x1y0。当d0,M在L(Q点)上方,取右方P1为下一个象素;当d=0,选P1或P2均可, 约定取P1为下一个象素;若当前象素处于d=0情况,则取正右方象素P1 (xp+1, yp), 要判下一个象素位置,应计算 d1 = F(xp+2, yp+0.5)=a(xp+2)+b(yp+0.5)=d+a; 增量为a若dSetPixel(x,y,color);while(xx1)if(dSetPixel(x,y,color);void CMy2View:On1() / TODO: Add your command handler code hereint x0,x1,y0,y1,color;x0=111;y0=111;x1=138;y1=138;color=RGB(255,0,0);CClientDC dc(this);Midpoint_Line(&dc,x0,y0,x1,y1,color);五、 实验心得写代码时一定要细心,不能漏写、写错,另外,要注意分号的使用。实验三:圆的生成算法一、 实验目的1、 通过用中点画圆法绘制圆,加深对算法原理的理解。2、 对程序以及函数的细节有更深入的把握。二、实验要求实现一个圆的中点生成算法的程序三、实验原理如果我们构造函数 F(x,y)=x2+y2-R2,则对于圆上的点有F(x,y)=0,对于圆外的点有F(x,y)0,对于圆内的点F(x,y)0 。与中点画线法一样,构造判别式:d=F(M)=F(xp+1,yp-0.5)=(xp+1)2+(yp-0.5)2-R2若 dSetPixel(xc+x),(yc+y),c);pDC-SetPixel(xc-x),(yc+y),c);pDC-SetPixel(xc+x),(yc-y),c);pDC-SetPixel(xc-x),(yc-y),c);pDC-SetPixel(xc+y),(yc+x),c);pDC-SetPixel(xc-y),(yc+x),c);pDC-SetPixel(xc+y),(yc-x),c);pDC-SetPixel(xc-y),(yc-x),c);while(x=y)if(dSetPixel(xc+x),(yc+y),c);pDC-SetPixel(xc-x),(yc+y),c);pDC-SetPixel(xc+x),(yc-y),c);pDC-SetPixel(xc-x),(yc-y),c);pDC-SetPixel(xc+y),(yc+x),c);pDC-SetPixel(xc-y),(yc+x),c);pDC-SetPixel(xc+y),(yc-x),c);pDC-SetPixel(xc-y),(yc-x),c);Sleep(1);ReleaseDC(pDC);五、 实验心得在程序调试中有很多错误,最后发现是没有弄清函数的主调关系,最后查阅了资料,调试好了程序。实验四:扫描填充算法一、 实验目的1、 掌握多边形扫描填充算法的思路2、 对程序以及函数的细节有更深入的把握。二、实验要求用VC编程实现扫描线填充算法三、实验原理对于给定的一个多变形,用一组水平的扫描线进行扫描,对每一条扫描线均可求出与多边形边的交点,这些交点将扫描线分割成落在多边形内部的线段和落在多边形外部的线段,并且两者相间排列,将落在多边形内部的线段上的所有像素点赋以给定的填充色彩。这样不需要检验每一个像素点,而只考虑与多边形相交的交点分割后的扫描线段。首先将有效多边形边界存储在一个有序边表中:有序边表每一个元素对应一条扫描线并按照扫描线从低到高排列;多边形的每条边,按照较低端点的y1值,存储在边表y1扫描线对应元素指向的链表中,链表中的节点记录了边的高端y2值、低端的x1值和1/m,这样就可以知道扫描线有没有和这条边相交(是否在y1和y2之间),初始交点(y1,x1),中间交点(y1+k,x1+k/m)。另外,所谓有效边是指去掉水平边、和为了解决交点计数问题而缩短了的多边形边。然后从多边形底部到顶部处理扫描线,对每条当前的扫描线,建立活化边表(和当前扫描线有交点的多边形边):活化边表可以是一个链表,其中的节点按照和扫描线交点从左到右排列。初始的活化边表可以直接从有序边表的对应扫描线链表中生成(需要排序),以后每次扫描线向上移动可以经过以下几个步骤更新活化边表:(1) 检查活化边表每个节点的上端y值,如果小于扫描线的y值,说明这条边已经扫描完毕,应该从活化边表中删除;否则,更新节点对应边和扫描线交点的x坐标值,这只要执行x+=1/m就可以了。(2) 加入新和扫描线相交的多边形边,即把有序边表中和新扫描线对应的链表中的节点加入到活化边表中来。(3) 根据节点的x值重新排序活化边表中的节点。最后根据扫描线连贯性,填充扫描线在多边形内线段的像素,即根据活化边表中节点的顺序和x值,确定需要染色的点。四、主要代码 void CFillView:Bubble(int n)for(int i = 0; i n-1; i+)for(int j = 0; j BubblePointsj+1.px)|(BubblePointsj.py BubblePointsj+1.py)Point tmp = BubblePointsj; BubblePointsj = BubblePointsj+1;BubblePointsj+1 = tmp;int CFillView:Table(int n)int i,j,ym,l,r;ym = BubblePoints0.py;int k = 0,g = 0;for(i = 0; i BubblePointsi.py) Arraykg.dx = (double)(inputPointsl.px - BubblePointsi.px) / (inputPointsl.py - BubblePointsi.py);Arraykg.x_ = BubblePointsi.px; Arraykg.ymax = inputPointsl.py;Arraykg.ypre = BubblePointsi.py;g+;if(inputPointsr.py BubblePointsi.py) Arraykg.dx = (double)(inputPointsr.px - BubblePointsi.px) (inputPointsr.py - BubblePointsi.py);Arraykg.x_ = BubblePointsi.px; Arraykg.ymax = inputPointsr.py;Arraykg.ypre = BubblePointsi.py;g+;return k;void CFillView:bubble(int n,double arr10)for(int i = 0; i n-1; i+)for(int j = 0; j arrj+1)double tmp = arrj;arrj = arrj+1;arrj+1 = tmp;void CFillView:OnDraw(CDC* pDC)CFillDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);int n = 7;double arr10; Input(n); Bubble(n);int a = Table(n); int i,j,k,p = 0;int ymin = BubblePoints0.py;int ymax = BubblePointsn-1.py;for(i = ymin; i ymax; i+)p = 0;for(j = 0; j a ; j+)for(k = 0; k Arrayjk.ypre & i Arrayjk.ymax)Arrayjk.x_ += Arrayjk.dx;arrp+ = Arrayjk.x_ ; bubble(p,arr);bool canDraw = true;k = 0;int j = (int)arrk; while(jSetPixel(j+,i,RGB(255,0,0);if(j arrk+1)canDraw = !canDraw;k+;elsej+;if(j arrk+1)canDraw = !canDraw;k+; 五、实验心得在算法实现过程中遇到了一些困难,有些问题考虑的不太全面,花费了很时间去调试,另一个就是在细节方面处理得不够好。实验五:裁剪算法一、 实验目的1、 掌握Cohen-Sutherland裁剪算法与中点分割裁剪算法2、 对程序以及函数的细节有更深入的把握。二、实验要求用VC编程实现Cohen-Sutherland或中点分割裁剪算法三、实验原理1、Cohen-Sutherland裁剪算法对于每条线段P1P2分为三种情况处理:(1)若P1P2完全在窗口内,则显示该线段P1P2。(2)若P1P2明显在窗口外,则丢弃该线段。(3)若线段不满足(1)或(2)的条件,则在交点处把线段分为两段。其中一段完全在窗口外,可弃之。然后对另一段重复上述处理。为快速判断,采用如下编码方法:将窗口边线两边沿长,得到九个区域,每一个区域都用一个四位二进制数标识,直线的端点都按其所处区域赋予相应的区域码,用来标识出端点相对于裁剪矩形边界的位置。将区域码的各位从右到左编号,则坐标区域与各位的关系为: 上 下 右 左 X X X X任何位赋值为1,代表端点落在相应的位置上,否则该位为0。若端点在剪取矩形内,区域码为0000。如果端点落在矩形的左下角,则区域码为0101。若P1P2完全在窗口内code1=0,且code2=0,则“取”;若P1P2明显在窗口外code1&code20,则“弃”; 在交点处把线段分为两段。其中一段完全在窗口外,可弃之。然后对另一段重复上述处理。3、 中点分割裁剪算法从P0点出发找出离P0最近的可见点,和从P1点出发找出离P1最近的可见点。这两个可见点的连线就是原线段的可见部分。 与Cohen-Sutherland算法一样首先对线段端点进行编码,并把线段与窗口的关系分为三种情况,对前两种情况,进行一样的处理;对于第三种情况,用中点分割的方法求出线段与窗口的交点。A、B分别为距P0 、 P1最近的可见点,Pm为P0P1中点。从P0出发找距离P0最近可见点采用中点分割方法先求出P0P1的中点Pm,若P0Pm不是显然不可见的,并且P0P1在窗口中有可见部分,则距P0最近的可见点一定落在P0Pm上,所以用P0Pm代替P0P1;否则取PmP1代替P0P1。再对新的P0P1求中点Pm。重复上述过程,直到PmP1长度小于给定的控制常数为止,此时Pm收敛于交点。从P1出发找距离P1最近可见点采用上面类似方法。四、主要代码 void Encode (int x,int y,int *code,int XL,int XR,int YB,int YT) /请将此程序补充完整 int c=0; if(xXR) c=c|RIGHT; if(yYT) c=c|TOP; (*code)=c;/编码裁剪算法:void C_S_Line(POINT &p1,POINT &p2,int XL,int XR,int YB,int YT) /请将此程序补充完整 int x1,x2,y1,y2,x,y,code1,code2,code; x1=p1.x; x2=p2.x; y1=p1.y; y2=p2.y; Encode(x1,y1,&code1,XL,XR,YB,YT); Encode(x2,y2,&code2,XL,XR,YB,YT); while(code1!=0|code2!=0) if(code1&code2)!=0) return; code=code1; if(code1=0) code=code2; if(LEFT&code)!=0)x=XL;y=y1+(y2-y1)*(XL-x1)/(x2-x1); else if(RIGHT&code)!=0) x=XR;y=y1+(y2-y1)*(XR-x1)/(x2-x1); if(BOTTOM&code)!=0)y=YB;x=x1+(x2-x1)*(YB-y1)/(y2-y1); else if(TOP&code)!=0) y=YT;x=x1+(x2-x1)*(YT-y1)/(y2-y1); if(code=code1)x1=x;y1=y;Encode(x,y,&code1,XL,XR,YB,YT); elsex2=x;y2=y;Encode(x,y,&code2,XL,XR,YB,YT); p1.x=x1;p1.y=y1;p2.x=x2;p2.y=y2;int IsInArea(POINT point,int XL,int XR,int YB,int YT) /请将此程序补充完整 if(point.x=XL & point.xYB & point.yend.x)?begin.x:end.x; minx=(begin.xend.y)?begin.y:end.y; miny=(begin.yend.y)?begin.y:end.y; if(m

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论