实习报告实习名称:计算机图形学实习班级:学号:姓名:实习地点:实习指导教师:实习时间:年月日至月日2一、实习目的与意义本次计算机图形学的实习分两部分,一部分是利用AutoCAD进行二维和三维模型的制作,另一部分是利用VC6.0进行编程实现对图形的简单操作。通过对AutoCAD的实习,熟悉该软件的基本功能及操作特点,掌握二维及三维图形的基本制作过程。通过对VC6.0的编程实习,理解图形的生成、图形的变换、图形的显示以及二维裁剪的基本思想,熟练掌握计算机图形学的基本原理和方法;熟练掌握计算机图形学算法的实现算法;学习和掌握图形系统的设计;学习用VC++编写计算机图形学程序;建立面向对象编程的基本概念。二、实习主要内容1、AutoCAD软件操作(1)简单图形绘制(2)图形的基本编辑命令操作(3)标注文字及填充(4)三维图形绘制2.基于VC6.0下的计算机图形学程序编写(1)图形的生成:画直线、画圆、画曲线、画字符(2)图形的变换:平移、旋转、缩放、对称变换(3)图形的显示:扫描线填充、边缘填充、种子填充(4)图形的二维裁剪:CS裁剪、多边形裁剪、梁友栋裁剪、圆裁剪、中点分割法3三、实习的主要过程第一部分AutoCAD软件操作AutoCAD软件可以处理很多问题,在机械制图,土木建筑等方面有着广泛的应用,我们在机房打开AutoCAD软件对其进行系统配置,然后进行具体操作。通过配置可以实现工具栏之类的快捷运用。(1)简单图形绘制实习开始的第一天,在老师的讲解以及演示下,我们了解了AutoCAD软件的基本使用方法,与此同时,我们跟着老师的操作也逐渐熟悉了该软件的一些基本操作方法。从设置基本绘图环境开始,按照指导书上的指示,采用边完成简单图形边学习各种命令的方式,逐渐熟练掌握了AutoCAD的使用,熟练掌握了其基本绘图功能,如掌握了绘图命令POINT、LINE、CIRCLE、ARC、DONUT、RECTANGLE、POLYLINE的功能及操作;掌握了实体绘图命令键盘输入的方法;掌握了缩放命令(ZOOM)的使用方法等。由于指导书的例子有详尽的操作过程,所以对以上功能的使用方法的掌握比较快。通过完成例子掌握了他们的使用方法,接着完成其他的练习达到了巩固的目的。以下通过一些例子来说明对以上绘图功能的使用:例一:基本环境设置a:在命令中输入limits,确定相应的绘图区域大小b:在命令中输入zoom,选择A(全部),让画布全部充满屏幕。4c:下来进行基本的画图操作,比如line、pline、point、circle、polygon等,掌握了这些基本的画图操作。例二:通过pline直接实现对轮廓的绘制,circle实现对圆的绘制,绘制前仍需设置图幅大小。对于轴对称的图形我们可以只绘出图形的一半,然后通过mirror镜像操作实现。再绘制的过程中,我们可以采用相对坐标和极坐标来实现简单定位,避免了计算的麻烦。绘制以上的图形时,可以采用pline绘制出外围轮廓,然后再绘制两个圆的方法,也可以采用镜像的方法来实现,从而节省时间。5例三:绘制五角星时采用采用端点捕捉画线的方法,采用solid填充区域。例四:通过辅助线实现图形的简单绘制。通过以下的图形操作巩固并熟练了图形的简单绘制的方法。6(2)图形的基本编辑命令操作我们在绘制复杂图形的时候需要采用一些基本编辑命令操作,如复制、对称、旋转、剪切、圆的公切线、公切圆等操作,能过快速的绘制出图形。对于复杂的图形,还需要我们能敏锐的发现图形各部分间的相关关系,才能快速而准确的绘制出图形,这就要求我们要多练习,熟练掌握基本操作,才能快速绘制比较复杂的图形。在图形的编辑栏中有删除、复制、镜像(MIRROR)、偏移、阵列、旋转、修剪等操作,我们可以通过这些操作,来绘制复杂图形。例一:镜像操作、倒角处理绘制以上图形时,先用pline绘制出上半部分的轮廓线,接着对左右两端进行倒角处理,并补竖线,然后通过mirror镜像操作绘制另一半图形。最后绘制腰圆图形,通过复制,偏移等操作绘制出上图。7例二:通过circle操作,画出两个圆的公切圆,通过trim修剪得到以下图形例三:绘制以上图形时,需要先对图形进行研究,分析图上标注的含义,确定辅助线的位置,恢复被裁剪掉的图形方便绘制图形。通过这幅图的练习,让我们8明白绘制一些复杂图形时,往往无法直接绘制出来,需要我们通过研究图形找到辅助线才能快速又准确的绘制出图形。通过以下的图形绘制更加熟练的学会了构造辅助线,通过图形基本编辑命令操作来实现复杂图形的绘制。9(3)标注文字及填充标注能够帮助我们检验所画图形是否符合标准,所以绘制后的图形还需要进行标注,在标注时,要建立不同的图层,在进行标注时,要根据实际不同的情况建立不同的标注样式,进行图形的标注。以上的图形都进行了标注。图形填充例子:以下两个图形综合了前面的知识,同时加入了图形的填充,图形的绘制过程比较复杂,且需要借助相应的辅助线进行绘图。以下两个手柄图是对前面所学知识的汇总,需要熟练掌握基本图形绘制方法、编辑命令操作和辅助线的构建。10(4)三维图形绘制由于实习期间有较多科目的考试,三维图形的练习在CAD考核之前并没有做过,只是在考核的时候进行了三维图形的绘制,由于没有经过三维图形练习,对三维图形的绘制不熟悉,没能在规定时间内完成三维图形的绘制。在进行编程实习期间,才将三维图形的绘制给补了回来。11第二部分基于VC6.0下的计算机图形学程序编写本次的编程实习采用面向对象编程,通过MFC来编程,实现可视化操作。1.创建工程后,对菜单栏进行修改,用鼠标右键点击菜单中的空格,在出现的下拉菜单中点击最后一项“属性”,出现“MenuItemProperties”窗口;在窗口中“标题”栏输入“图形生成”,建立主菜单项“图形生成”,同理建立“图形变换”,“图形显示”“二维裁剪”的菜单项,并在其下拉选项中添加相应操作。修改后的菜单如下图所示:2.鼠标坐标显示为了精确定点,必须知道当前坐标,因此必须为操作者提示鼠标坐标。准备将坐标显示在应用程序窗口的右下脚。在自动生成的工程中,窗口的右下脚处原是用来显示键盘按键信息的(如下左图所示),现改为显示鼠标坐标(如下右图所示)。3.画直线、圆、曲线、字符、颜色设置(1)直线:分为DDA直线、中点直线12下面以DDA直线为例,说明如何创建菜单响应函数。已经创建了DDA直线菜单,菜单响应程序如下步骤:打开工程项目,依次点击菜单“查看”、“建立类向导”,出现如下窗口(如下图),也可以用Ctrl+W打开类向导。在ClassName:栏中选CMy2013302590035View(即菜单响应程序放在视图类中);在ObjectIds:栏中选ID_DRAW_DDALINE;在Messages:栏中选COMMAND;点击AddFunction按键,出现函数命名窗口,点击该窗口中的OK按键,该函数在2013302590035View.cpp中生成。点击该窗口中的EditCode按键查看、编辑该函数。具体实现:DDA直线的程序实现如下:首先编写菜单响应函数,对MenuID和PressNum两个变量赋初值;接下来建立相应的鼠标响应程序框架,DDA直线要求第一次点鼠标左键确定起始点,第二次点鼠标左键确定直线终止点,并画出直线,中13间利用橡皮筋技术实时显示直线的形状,完成直线绘画后,还要将橡皮筋旧线擦除。中点画线算法实现过程和DDA算法大致相同,但是其思想更加合理,更有利于硬件实现,提高了算法效率,程序实现同DDA大同小异,只是DOC.cpp中核心算法不同而已,中点画线法采用交点与中点差比较得判定。其算法的中心思想相同,即在坐标系的网格中,确定起始点后,再根据其不同的判断方法,取得离直线最近的像素点予以着色,用离散的点表示出所要直线。上图中红线为DDA直线,黑线为中点直线(2)曲线:曲线分为Brezier曲线、B样条曲线和Hermite曲线。均是由鼠标左键确定主要拐点,按右键确定选点已完成并进行曲线绘制,双击左键消除十字丝完成曲线绘制。Bezier曲线是由一群控制点决定的。一段曲线的次数与控制点的点数密切相关,人们常常使用三次曲线,那么一段曲线的控制点的点数为4。实际应用中,一条Bezier曲线是由多段Bezier曲线首尾相连而成。与之相应,一群控制点划分成多组控制点,每一组控制一段曲线的形状。为了使每一段曲线平滑地连接起来,要求前一组最后一个控制点与后一组第一个控制点相同(即共14用一个点),同时要求前一组倒数第二个控制点、最后一个控制点(即后一组第一个控制点)、后一组第二个控制点等三个控制点在一条直线上。如果要求给出的控制点在相邻的组之间都能满足这种要求,那么控制点的布点工作将受到极大的限制。这种要求不仅难以满足,而且灵活性被极大地削弱。解决的办法是计算得出连接点,即用前一组的倒数第二点和后一组的第二点连线的中点作为相邻两段曲线控制点的终点和起点。Bezier曲线的操作这样安排:用鼠标左键进行控制点选点,右键结束选控制点,显示一条Bezier曲线;再按左键选取一个控制点进行移动修改,右键结束一个控制点修改;当所有的修改完成以后,双击左键生成一条正式的Bezier曲线。因此首次布点和修改控制点位置,对鼠标的操作要求不同,必须区分开。B样条曲线和Hemite曲线的操作安排与Bezier曲线的操作安排一致,只是DOC.cpp中的核心算法不同而已。上图中,黑色为Bezier曲线,红色为B样条曲线,绿色为Hemite曲线15(3)圆:圆分为Bresenham圆、正负法圆。Bresenham圆的程序实现如下:由鼠标左键确定圆心,再定一点,使其与第一点的连线长度成为半径进行圆的绘制。先为Bresenham圆添加菜单响应函数确定MenuID,然后画圆的OnLButtonDown()响应:用鼠标确定圆心,再移动鼠标确定半径。在确定半径时,随着鼠标的移动,一个圆随着鼠标的移动半径发生变化。然后调用Bresanham算法完成圆的绘制。Bresenham圆的编程实现如下:首先编写菜单响应函数,对MenuID和PressNum两个变量赋初值;接下来建立相应的鼠标响应程序框架,Bresenham圆要求第一次点鼠标左键确定圆心,第二次点鼠标左键确定圆上一点,并由此确定半径,画出完整的圆;然后再在Doc.h头文件中声明必要变量和函数,并在Doc.cpp中完成Bresenham圆的生成数。正负画圆法的编程实现与Bresenham圆的相类似。上图中红色为Bresenham圆,绿色为正负法画圆法(4)字符:字符的表示有点阵表示和矢量表示两种。点阵表示指每个字符都有若干个点表示,矢量表示记录的是笔画信息。可先通过调用MFC对话框对16字的字体、粗细、大小进行调整,再点击文本,输入文本位置的其实坐标以及文本内容,相应文本内容则可出现在指定位置。(5)颜色设置:使用了MFC中的CcolorDialog类,该类是MS设计的专门用于颜色选择的对话框类:classCcolorDialog:publicCCommonDialog。4.图形显示:扫描线填充算法、边缘填充、种子填充扫描线填充算法运用了复杂的数据结构,且在填充过程中需要反复排序,编程难度较大。VC类库中的函数CDC::Polygon()实现了扫描线填充算法功17能。实际上我们所学的计算机图形学所有算法都能通过引用VC类库提供的函数(或函数组合)加以实现。边缘填充实质是以边缘与扫描线的交点为起点以“异或”的方式向右边最远点画点。如果一个像素经过偶数次异或画点,将还原为背景颜色;而经过奇数次异或画点的像素将显示画点颜色与背景颜色经过异或运算混合的颜色。所有的边缘都处理完后,多边形内部像素肯定经过了奇数次异或画点,因而显示画点颜色与背景颜色异或运算混合颜色;多边形外部像素肯定经过了偶数次异或画点,因而还原为背景颜色。种子填充的原理是从堆栈中取出一粒表示区域内部的种子,从种子点出发,沿扫描线分别向左向右边填充边寻找边界点;通过左右两边的边界点确定扫描线上的填充区域范围;根据该范围在上下相邻的两条扫描线上寻找新的未填充