北京工商大学.docx

上传人:b****5 文档编号:30748464 上传时间:2023-08-20 格式:DOCX 页数:14 大小:26.72KB
下载 相关 举报
北京工商大学.docx_第1页
第1页 / 共14页
北京工商大学.docx_第2页
第2页 / 共14页
北京工商大学.docx_第3页
第3页 / 共14页
北京工商大学.docx_第4页
第4页 / 共14页
北京工商大学.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

北京工商大学.docx

《北京工商大学.docx》由会员分享,可在线阅读,更多相关《北京工商大学.docx(14页珍藏版)》请在冰豆网上搜索。

北京工商大学.docx

北京工商大学

北京工商大学

计算机图形学实验报告

试验名称计算机图形学实验共10页

成绩实验日期2005年5月日

班级微机024班组别交报告日期2005年6月15日

学号0214020415姓名欧阳锦林

同组学生教师审批签字

 

图形学实验报告

——微机024班15号欧阳锦林

一、实验目的:

通过本实验,使自己了解计算机图形学的有关原理、算法及系统,掌握基本图形显示程序设计方法,及二维和三维图形变换程序设计方法,为进一步学习计算机辅助设计方面的技术知识打下基础。

二、实验内容和要求:

1、实验内容

1直线和圆的生成,设定屏幕图形工作方式,彩色象素的读写,直线和圆的扫描转换。

2多边形的裁剪和填充

3图形变换:

二维变换、及投影、透视变换

2、上机实验要求

上机实验是巩固课堂内容。

增强感性认识。

实验后要求学生认真编写实验报告,作为学生平时成绩的依据。

三、实验报告:

1、实验环境:

VStudio6.0的VC6.0,MFC

2、实现功能:

a)直线和圆的生成,直线和圆的扫描转换。

并且实现了用鼠标点击取点的交互功能。

b)多边形的裁剪和填充,实现了点扫描与直线扫描多边形。

c)直线剪裁,并可以自动判断与某条或某些条直线可剪裁,剪裁结果是一条线段生成两到三条线段,并可在文档中保存。

d)图形变换:

二维变换:

平移、旋转、缩放功能,其中平移已实现了鼠标点击取点的交互功能。

e)提供了用户对对象的选择,再在在被选择的对象上进行相应操作。

f)实现了文档存储与打开。

3、文件格式:

1、Graph1.txt文件格式是:

第一行表示有3种类形的图元数据,在本程序中为3,分别为直线,圆,多边形,第二行为第一个数据为类型,1表示为直线容器,第二个数据3表示此直线容器(用双链表实现)中有3条直线。

下面3行的格式相同,分别是颜色,起点、终点的x、y坐标。

第六行中3表示类型3是多边形,2表示多边形个数。

再下面就是各个多边形的信息的,0表示不用填充,15550是颜色值,3表示3边形。

下面三行是三个顶点的x、y坐标。

11-16行信息同理。

17行2表示类型2为圆,1表示1个,18行各个数据分别表示,是否填充、颜色、圆心x、y坐标、半径。

2、可以直接用记事等不带格式的文本编辑器按文件格式进行手工修改,注意:

一定要按格式,否则将不能生成你想要的图元。

4、所用数据结构:

1、GraphObject:

本程序得用一个数据结构把所有的图元装入了,并可以根据不同的类型,做不同的动作,类的定义如下:

//GraphObject是用来存放各种图形对象的,根据type的不同,

//object做不同的类型转换.

classGraphObject

{

private:

void*object;

inttype;

public:

GraphObject();

GraphObject(void*Object,intType);

virtual~GraphObject();

//根据type的不同,做不同的动作。

boolaction(CDC*pCDC);

//根据type的不同,保存不同为格式。

boolsave(ofstream&out);

};

再用CListGraphList;

容器把所有的对象都装入进去了。

当然,后来为了方便,再加了三个容器,这个容器的作用就不大了,可它却体现了大自然的面向对象的基本原理,值得关注。

2、Matrix:

#definePI3.1415926

//3*3矩阵类:

classMatrix

{

public:

Matrix();

Matrix(constMatrix&mat);

Matrix(inttx,intty);

Matrix(floattx,floatty);

virtual~Matrix();

floatarray[3][3];

voidSetIdentity();//设置对角为1,其余为0

Matrix&operator*(constMatrix&mat);//矩阵乘法.

Matrix&operator+(constMatrix&mat);//矩阵加法

//将点通过矩阵转换为另一个点.

POINT&pointTrans(POINT&point);

};

3、MidLine:

#definePrecision5//此为选择对象的精确度

//线段类:

classMidLine

{

public:

MidLine();

MidLine(intx0,inty0,intx1,inty1);

MidLine(POINTPoint0,POINTPoint1);

virtual~MidLine();

voidMidPointLine(CDC*pCDC);

voidsetColor(COLORREFColor);

boolSelectIt(POINTpoint);

//二维复合变换

voidmove(POINTpoint);

voidrotate(floata,CPointrefpt);

voidscale(floatsx,floatsy,CPointrefpt);

boolselect;

POINTpoint0,point1;

COLORREFcolor;

private:

voidMidPointLine0(intx0,inty0,intx1,inty1,intcolor,intindex,CDC*pCDC);

};

4、MidCircle:

#definePI3.1415926

//3*3矩阵类:

classMatrix

{

public:

Matrix();

Matrix(constMatrix&mat);

Matrix(inttx,intty);

Matrix(floattx,floatty);

virtual~Matrix();

floatarray[3][3];

voidSetIdentity();//设置对角为1,其余为0

Matrix&operator*(constMatrix&mat);//矩阵乘法.

Matrix&operator+(constMatrix&mat);//矩阵加法

//将点通过矩阵转换为另一个点.

POINT&pointTrans(POINT&point);

};

5、Polygon:

#include

#include

#include

#definePrecision5//此为选择对象的精确度

//扫描线算法中的“边”数据结构表示

structEdge{

inty;//边的上端点的y坐标

floatx;//AEL中当前扫描线与边的交点(或ET中边的下端点的x坐标)

floatdeltax;//边的斜率的倒数

//定义边类型的大小比较关系(用于排序)

friendbooloperator<(constEdge&,constEdge&);

};

//结点为边的链表的数据类型

typedefstd:

:

listEgList;

//Et表数据类型

typedefstd:

:

mapEtType;

//多边形类:

classpolygon

{

public:

//多边形数据结构表示

intcount;//多边形顶点数

POINT*pPointArray;//多边形顶点数组

COLORREFcolor;

boolFill;//是否填充

boolselect;//是否为当前选择对象

boolSelectIt(POINTpoint);//判断当前点是否选中多边形

EtTypeet;

EgListael;

//四个构造函数

polygon();

polygon(intCount,POINT*pPoint);

polygon&operator=(constpolygon&py);

virtual~polygon();

//下面四个函数为扫描填充多边形

inttoInt(floata,inttype);

voidinit();

voiddrawLine(intxLeft,intxRight,inty,CDC*pDC);

voidLineScan(CDC*pDC);

voidsetColor(COLORREFColor);

//画多边形,根据Fill是否填充.

voiddrawPoly(CDC*pCDC);

//二维复合变换

voidmove(POINTpoint);

voidrotate(floata,CPointrefpt);

voidscale(floatsx,floatsy,CPointrefpt);

private:

polygon(constpolygon&py);

};

5、调试经验:

我在调试这个程序的时候遇到了一些“低级”错误,也理解了关于C++的一些高级主题,为方便大家的交流,也方便自已以后的学习,我将这此经验都用注释写在相应的地方了。

试举几例:

(1)、polygon&polygon:

:

operator=(constpolygon&py){

//注意下面两行代码,是必须的,

//一定要释放对象以前指向的内存区。

//详细情况请看polygon:

:

polygon(constpolygon&py)的注释

if(pPointArray!

=NULL)

delete[]pPointArray;

count=py.count;

pPointArray=newPOINT[count];

color=15550;

Fill=py.Fill;

select=py.select;

for(inti=0;i

pPointArray[i]=py.pPointArray[i];

return*this;

}

polygon:

:

polygon(constpolygon&py)

{

//if(pPointArray!

=NULL)

//delete[]pPointArray;

//!

!

!

!

//当用polygonp(py)时,p.pPointArray不会自动设为空!

!

//此时用delete将会产生寻常!

!

!

//然而:

又如何保证在赋值前释放以前的空间呢!

!

?

?

//解答:

test类:

test.h,注意:

如果写成:

testc=a则会调用其拷贝构造函数

//只有写成testc;c=a;才会调用operator=

//基于此,可把拷贝构造函数设为私有,才可保证生成对象时一定会调用默认

//构造函数!

//但是,如果这样,则在使用这个类时会遇上很多"阻碍",那就是你要避免系统

//"自动"调用你的拷贝构造函数,比如当你的函数形参是对象而不是引用时,

//因此,这时你最好检查你的函数,使其用引用做为形参,如果不想因函数改变

//形参,则设为引用即可.

//也许,C++在扩充C时加入了一个引用这种奇怪的数值引用方式.

count=py.count;

pPointArray=newPOINT[count];

color=15550;

Fill=py.Fill;

select=py.select;

for(inti=0;i

pPointArray[i]=py.pPointArray[i];

}

polygon:

:

polygon(intCount,POINT*pPoint)

{

//由于用此种构造函数时,不会设置pPoint为NULL,

//故不用下面两行代码

//否则可能删除未初始化指针,产生异常。

//if(pPointArray!

=NULL)

//delete[]pPointArray;

……

(2)、//画多边形,根据Fill选择是否填充.

voidpolygon:

:

drawPoly(CDC*pCDC)

{

for(inti=0;i

{

MidLineline(pPointArray[i],pPointArray[i+1]);

line.setColor(color);

line.MidPointLine(pCDC);

}

MidLineline(pPointArray[count-1],pPointArray[0]);

line.setColor(color);

line.MidPointLine(pCDC);

if(Fill)

{

LineScan(pCDC);

//下面是用点填充算法实现填充!

//由于递归算法太过消耗资源,故将其注释掉

//改成线扫描

/*intx=0,y=0;

for(i=0;i

//!

!

一个count-1用了我1个半小时

//还是上厕所的时候突然想到,for语句控制错误!

!

//可见编程最是要头脑清醒!

!

…………

(3)、POSITIONpos=polygonList.GetHeadPosition();

//注意!

!

:

(CList*)object一定要用()号括起来!

!

6、程序特点:

(1)、由于本程序是为了实现图形学的各种算法,因此,哪怕是画直线这样的事也都没有调用MFC提供的函数来实现,全部都是自己编写的。

(2)、结构较严谨,在编写的过程中,我注意到了类的结构严谨,文档类视图类的分工合作明确。

但还是很遗留了很多冗繁的地方,因为有的一开始就没有注意,到后来也就没有改了。

(3)、保存了调试信息,我在编写代码是时候喜欢由接口到实现,由简单到复杂的顺序编写,最后我保存了那些有价值的调试代码做为注释,以便以后学习与修改。

(4)、纠正并完善了某些书上的算法:

我用的图形参考书是:

《计算机图形学》倪明田、吴良芝编著,北京大学出版社,但其中很多算法没有用

(1)、//此算法在这里有问题,可能是因为我们所用的坐标系

//原点在左上角而不是程序假设的左下角.

/*P0(x0,y0)P1(x1,y1)为待裁剪线段*/

/*rect为裁剪窗口*/

boolCGraphView:

:

CohenSutherlandLineClip(floatx0,floaty0,floatx1,floaty1,CutRect

*rect,POINT&point0,POINT&point1)

(2)、boolCGraphView:

:

CohenSutherlandLineClip(floatx0,floaty0,floatx1,floaty1,CutRect

*rect,POINT&point0,POINT&point1)函数中:

//注意,书上此行代码有问题!

!

//原句是:

x=x0+(x1-x0)*((float)rect->ymin-x0)/(y1-y0);

//书111面

(3)、在直线的中点算法中,voidMidLine:

:

MidPointLine0(intx0,inty0,intx1,inty1,intcolor,intindex,CDC*pCDC)

{

…………

d+=incrE;

x++;//注意:

书本47面的的程序少了这行代码,应该加上.

……

(4)、直线的中点算法书上只是实现1/8的区域,要以任意点画直线,需要自己做一些转化。

7、待扩充内容:

本程序还有很多地方值得改进,由于时间不够,先做到这里,但现在因为我采用了各种类来定义不同的图元,因此,要扩充是很容易的。

需要扩充的地方有:

图元变换的交互式实现(包括鼠标的变形)、图形类型的添加,如,椭圆,圆弧等,还有就是调色板对颜色的控制。

四、实验总结:

1、实验收获与体会:

比较起这个学期的其他课程来说,我这个图形实验上用的时间是最多的,当然收获也是最大的,做完实验后,不免清点一下:

a、对C++语言的进一步应用与理解,最大的收获便是引用,我以前一直对引用总是一知半解,知其然不知其所以然,现在明白了,在C++这种语言中,为什么要在C语言的基础上加入引用呢?

我觉得是基于以下几个方面的原因:

1、高效:

如果用对象做为函数的形参,不仅要支付构造函数析构函数的执行代价,当遇上大对象时更是空间的极大浪费,还有就是对象做为形参是不能改变函数体外的数据的;如果用指针,效率问题可以得到问题,却要承担更大的风险,如空指针、野指针引发的内存泄漏或异常;还有不能有效防止函数体内不影响函数体个的数据,引用用const修饰保证常量性,用声明时初始化来保证非空。

2、安全:

主要与指针相比,原因在1中说明。

3、可以避免在某些情况禁止拷贝构造函数。

关于拷贝构造函数的具体介绍见调试经验中的详细说明。

b、对MFC的学习。

利用这次实验的机会,我在以前C++语言的基础上学习了windows环境下的编程,先是API,后来就是MFC了,可以在这次实验后,我已可以基本了解windows以及MFC的编程机制了。

C、对图形理论的更深入的理解。

毕竟,从理论到实践还有那么一段距离,可是当你跨过去之后,也是对理论学习的一种补充与提高。

更重要的是,就像郝老师说的:

编程到了一定程度上时又要求理论知识的良好掌握。

是的,两者相辅相成,缺一不可。

D、最后,要感谢我的图形老师郝建强老师,他不仅在理论上帮助了我,更从编程方面给了我许多有益的启发。

参考书:

1、《计算机图形学》倪明田、吴良芝编著,北京大学出版社

2、《MFCwindows程序设计》(第2版)JeffProsise清华大学出版社

3、《windows图形编程》FengYuan机械工业出版社

4、《C++编程思想》Bruck著侯捷译机械工业出版社

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > 公务员考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1