计算机图形学实验指导书vc++版.docx
- 文档编号:9494880
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:101
- 大小:441.90KB
计算机图形学实验指导书vc++版.docx
《计算机图形学实验指导书vc++版.docx》由会员分享,可在线阅读,更多相关《计算机图形学实验指导书vc++版.docx(101页珍藏版)》请在冰豆网上搜索。
计算机图形学实验指导书vc++版
实验指导书
刘文涛
2013
目录
第一章图形学实验环境和要求4
1.1VC++实验环境4
1.1.1基本环境4
1.1.1开发图形程序的一般流程7
1.1.3基本绘图函数介绍11
1.2OpenGL19
1.2.1OpenGL介绍19
1.2.2OpenGL开发环境20
1.2.3OpenGL函数21
1.2.4回调函数22
1.2.4一个典型OpenGL例程23
1.3实验要求26
1.3.1实验内容26
1.3.2实验方法26
1.3.3实验效果27
第二章直线生成算法27
2.1实验原理27
2.1.1DDA算法27
2.1.2Bresenham算法27
2.2实验内容27
2.3参考示例程序27
第三章圆和椭圆生成算法29
3.1实验原理29
3.2实验内容29
3.3参考示例程序129
3.4参考示例程序230
第四章裁剪算法32
4.1实验原理32
4.2实验内容32
4.3示例程序32
4.3.1参考例子132
4.3.2参考例子235
第五章二维变换37
5.1实验原理37
5.2实验内容37
5.3示例程序37
5.3.1参考例子137
第六章三维变换41
6.1实验原理:
41
6.2实验内容42
6.3示例程序42
第七章填充算法44
7.1实验原理:
44
7.2实验内容44
7.3示例程序44
第八章曲线曲面47
8.1实验原理47
8.2实验内容47
8.3示例程序48
8.3.1参考例子
(1)48
8.3.2参考例子
(2)49
8.3.3参考例子(3)51
8.3.4参考例子(4)53
第九章真实感图形绘制56
9.1实验原理56
9.2实验内容56
9.3示例程序56
9.3.1参考例子
(1)56
9.3.2参考例子
(2)58
9.3.3参考例子(3)60
第十章动画63
10.1实验原理63
10.2实验内容63
10.3示例程序63
10.3.1参考例子63
参考文献:
69
第一章图形学实验基础
1.1VC++实验环境
1.1.1基本环境
MicrosoftVisualC++6.0是微软推出的功能强大的可视化C/C++语言编译器,运行在Windows9x/2000/NT等平台上,可以建立32位应用程序。
运用这个强大的工具,可以很快地建立具有图形界面、能够运行于Windows操作系统上、有很复杂的功能的程序。
在VC中提供了Windows编程所需的WindowsAPI,以及建立在其基础之上的类库--MicrosoftFoundationClasses(MFC),前者是编写32位Windows程序所必需的应用程序接口,而后者提供了建立较大规模软件的解决方案,正逐渐成为许多C++编译器进行Windows软件开发的工业标准。
另外,VisualC++还提供了可视化的编辑工具,使无论是源代码的编辑,还是应用程序界面设计,都变得十分简单。
VC还具有强大的Debug功能,对于调试程序来说,使用VC的Debug工具将使工作量大大降低。
而在其提供的各种功能中,与图形学直接相关的部分,是其提供的设备无关性和丰富的绘图功能。
Windows是图形界面的操作系统,Windows程序可以使用系统提供的图形设备界面(GraphicsDeviceInterface,GDI)绘制比TurboC中美观、丰富得多的图形,而且其实现十分的简单。
另外,VisualC++中还提供了对OpenGL图形编程的支持,可以简单快速的实现3维场景的渲染,为其加上光照、纹理、雾效等等。
后面还要详细介绍OpenGL相关内容。
在Windows这样一个图形界面操作系统中,图形操作是十分重要的。
图形是Windows的主体。
所有的信息,包括文本,最终都是由图形来实现的。
在Windows程序中,并不是把图形直接画到硬件上去,而是使用一个与硬件无关的设备环境来表示逻辑的设备。
在绘图工作开始之前,必须申请一个设备环境。
Win32API提供了4种设备环境:
显示器环境:
支持图形在视频显示器上绘制
信息环境:
用于检索设备数据
内存环境:
支持在位图上进行图形操作
打印机环境:
支持在打印机或绘图仪上进行图形操作
Windows体系结构的一个重要组件是图形设备界面(GraphicsDeviceInterface,GDI)。
GDI为Windows提供了所有的基本绘图函数。
在Windows的GDI函数中,使用设备环境来作为一个参数。
GDI通过调用相应设备的驱动程序来响应Windows绘图函数的调用。
这种机制实现了硬件无关性,即无需自己编写底层驱动程序代码,因为Windows本身已经包含了这些驱动程序。
Microsoft基础类库(MicrosoftFoundationClasses,MFC)是专门用来为Windows开发C++图形界面应用程序的类库。
它是随着面向对象的编程技术的产生而产生的。
WindowsAPI是一种过程接口,当面向对象的编程技术出现之后,就需要为Win32程序建立一种面向对象的接口。
1992年,Microsoft公司开发了面向对象的应用程序框架(ApplicationFrameworks,AFX),后来演变成了MFC。
实际上,MFC的内部大部分仍然是通过WindowsAPI来实现的。
使用MFC提供的基于对话框程序的模版,我们可以迅速建立一个适于绘图而且具有较好的交互性的应用程序框架。
图形设备接口(GDI)是一个可执行程序,它接受Windows应用程序的绘图请求(表现为GDI函数调用),并将它们传给相应的设备驱动程序,完成特定于硬件的输出,象打印机输出和屏幕输出。
GDI负责Windows的所有图形输出,包括屏幕上输出像素、在打印机上输出硬拷贝以及绘制Windows用户界面。
三种图形输出类型
应用程序可以使用GDI创建三种类型的图形输出:
矢量输出、光栅图形输出和文本输出。
矢量图形输出
矢量图形输出指的是创建线条和填充图形,包括点、直线、曲线、多边形、扇形和矩形的绘制。
光栅输出
光栅图形的输出是指光栅图形函数对以位图形式存储的数据进行操作,它包括各种位图和图标的输出。
在屏幕上表现为对若干行和列的像素的操作,在打印机上则是若干行和列的点阵的输出。
光栅图形输出的优点是速度很快,它是直接从内存到显存的拷贝操作。
缺点是需要额外的内存空间。
Windows在绘制界面时使用了大量的光栅输出。
文本输出
与DOS字符方式下的输出不同,Windows是按图形方式输出的。
这样,在输出文本时,必须以逻辑坐标为单位计算文本的输出位置,而不是象DOS下以文本行为单位输出文本。
这比DOS下的文本输出要难一些。
但是,按图形方式输出文本也给文本输出带来很大的灵活性。
用户可以通过调用各种GDI函数,制造出各种文本输出效果,包括加粗、斜体、设置颜色等。
Windows还提供了一种TrueType(写真字体)。
TrueType字体用一组直线和曲线命令及一些参数来描述字体的轮廓。
Windows可以通过参数来调整直线的长度和曲线的形状,从而实现对字体的自由缩放。
介绍MFC中与GDI有关的类:
为了支持GDI绘图,MFC提供了两种重要的类:
设备上下文类,用于设置绘图属性和绘制图形;绘图对象类,封装了各种GDI绘图对象,包括画笔、刷子、字体、位图、调色板和区域。
1)设备上下文类
设备上下文类包括CDC和它的派生类CClientDC、CPaintDC、CWindowDC、CMetaFileDC。
CDC是设备上下文类的基类,除了一般的窗口显示外,还用于基于桌面的全屏幕绘制和非屏幕显示的打印机输出。
CDC类封装了所有图形输出函数,包括矢量、光栅和文本输出。
CClientDC(客户区设备上下文)用于客户区的输出,它在构造函数中封装了GetDC(),在析构函数中封装了ReleaseDC()函数。
一般在响应非窗口重画消息(如键盘输入时绘制文本、鼠标绘图)绘图时要用到它。
用法是:
CClientDCdc(this);//this一般指向本窗口或当前活动视图
dc.TextOut(10,10,str,str.GetLength());
//利用dc输出文本,如果是在CScrollView中使用,还要注意调
//用OnPrepareDC(&dc)调整设备上下文的坐标。
CPaintDC用于响应窗口重绘消息(WM_PAINT)是的绘图输出。
CPaintDC在构造函数中调用BeginPaint()取得设备上下文,在析构函数中调用EndPaint()释放设备上下文。
EndPaint()除了释放设备上下文外,还负责从消息队列中清除WM_PAINT消息。
因此,在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消息队列中清除,将引起不断的窗口重画。
CPaintDC也只能用在WM_PAINT消息处理之中。
CWindowDC用于窗口客户区和非客户区(包括窗口边框、标题栏、控制按钮等)的绘制。
除非要自己绘制窗口边框和按钮(如一些CD播放程序等),否则一般不用它。
CMetaFileDC专门用于图元文件的绘制。
图元文件记录一组GDI命令,可以通过这一组GDI命令重建图形输出。
使用CMetaFileDC时,所有的图形输出命令会自动记录到一个与CMetaFileDC相关的图元文件中。
2)图形对象类
图形对象类包括CGdiObject、画笔、刷子、字体、位图、调色板、区域等。
CGdiObject是图形对象类的基类,但该类不能直接为应用程序所使用。
要使用GDI对象,必须使用它的派生类:
画笔、刷子、字体、位图、区域等等。
使用图形对象要注意两点:
1.同其他MFC对象一样,GDI对象的创建也要分为两步:
第一步,是定义一个GDI绘图对象类的实例;第二步调用该对象的创建方法真正创建对象。
2.创建对象:
使用该对象,首先要调用CDC:
:
SelectObject()将它选入到设备上下文中,同时保存原来的设置到一个GDI对象指针比如说pOldObject中。
在使用完后,再用SelectObject(pOldObject)恢复原来的设置。
但是,如果该设备上下文是用户自己创建的,则不必恢复原来设置,因为框架会在该设备上下文生存期结束时删除该设备上下文,同时也就删除了原来存放于该设备上下文中的绘图对象设置。
下面介绍各种对象的用法:
画笔(CPen):
封装GDI画笔,可被选中设备上下文中当前所用得笔。
画笔用于绘制对象的边框以及直线和曲线。
缺省画笔画一条与一个像素等宽的黑色实线。
要使用画笔,首先要定义一个画笔:
CPenpen;
然后创建画笔。
创建画笔有两种方法:
一是使用CPen:
:
CreatePen(intnPenStyle,intnWidth,DWORDcrColor)进行初始化。
第一个参数是笔的风格。
nPenStyle可选值有:
PS_SOLID实线
PS_DOT虚线
PS_INSIDEFRAME在一个封闭形状的框架内画线,若设定的颜色不能在调色板种找到且线宽大于1,Windows会使用一种混色。
PS_NULL空的画笔,什么也不画
第二个参数是线的宽度,按逻辑单位。
若线宽设为0,则不管是什么映射模式下,线宽始终为一个像素。
第三个参数是线的颜色,可以选16种VGA颜色中的一种。
颜色的设置用一个RGB宏来指定。
RGB宏形式如下
COLORREFRGB(cRed,cGreen,cBlue)
cRed、cGreen、cBlue分别代表颜色的RGB三个分量,它们的取值在0-255之间。
可以使用RGB组合成各种色彩。
这样,要指定一个淡黄色的宽度为逻辑单位1的实心笔,可以调用:
pen.CreatePen(PS_SOLID,1,BR_YELLOW);
创建笔的另一个方法是使用库存对象。
SelectStockObject可从以下库存笔中选择一个:
BLACK_PEN黑笔
NULL_PEN空笔(不画线或边框)
WHITE_PEN白笔
注:
库存对象是由操作系统维护的用于绘制屏幕的常用对象,包括库存画笔、刷子、字体等。
刷子(CBrush):
封装GDI刷子,可用作设备上下文中当前刷子。
刷子用来填充一个封闭图形对象(如矩形、椭圆)的内部区域。
缺省的刷子将封闭图形的内部填充成全白色。
我们以前所创建的窗口内部都是白色就是窗口使用缺省刷子填充的结果。
可以用以下几种方法创建刷子:
(1)CreateSolidBrush(DWORDcrColor)创建一个实心刷子,用一种颜色填充一个内部区域。
(2)CreateHatchBrush(intnIndex,DWORDcrColor);创建一个带阴影的刷子,nIndex代表一种影线模式:
(3)用CreatePatternBrush(CBitmap*pBitmap)
用一个位图作刷子,一般采用8X8的位图,因为刷子可以看作8X8的小位图。
当Windows桌面背景采用图案(如weave)填充时,使用的就是这种位图刷子。
(4)同样可以使用SelectStockObject()从库存刷子中选取一个:
BLACK_BRUSH黑色刷子
WHITE_BRUSH白色刷子
DKGRAY_BRUSH暗灰刷子
GRAY_BRUSH灰色刷子
LTGRAY_BRUSH淡灰色刷子
NULL_BRUSH空刷子,内部不填充
字体(CFont):
封装了GDI字体对象,用户可以建立一种GDI字体,并使用CFont的成员函数来访问它。
关于CFont类,我们在前面已经作了一些介绍,这里不再赘述,读者可以参见前一章内容。
位图(CBitmap):
封装一GDI位图,它提供成员函数装载和操作位图。
调色板(CPalette):
封装GDI调色板,它保存着系统可用的色彩信息,是应用程序和彩色输出设备上下文的接口。
区域CRgn类:
封装GDI区域。
区域是窗口内的一块多边形或椭圆形的区域。
CRgn用于设备环境(通常是窗口)内的区域操作。
CRgn通常与CDC的有关剪裁(clipping)的成员函数配合使用。
1.1.1开发图形程序的一般流程
我们以一个最简单的例子来讲解,本例子是画一条直线和一个圆。
1.创建一个新的工程
【file】->【new】->【projects】->【MFCAppWizard[exe]】,新建一个工程名字为test。
如图所示
图
然后点击【ok】,选择【SingleDocument】,如图所示
再点击【finish】按钮即可,显示新建工程的信息窗口,如图所示
点击【ok】即可,此时一个新的工程就建立了,但是一个空的工程,没有实际内容,我们要实现绘图功能,只需要在类CtestView的函数OnDraw()中添加绘图语句即可,我们添加下列三行语句,如图所示:
pDC->SetPixel(250,250,RGB(0,0,0));//画一个象素点
pDC->LineTo(300,200);//画直线线
pDC->Ellipse(100,100,150,150);//画圆
此时编译并运行此工程,运行结果如图所示:
1.1.3基本绘图函数介绍
(1)画点
SetPixel()函数可以在指定的坐标位置按指定的颜色画点。
函数原型说明如下:
COLORREFCDC:
:
SetPixel(intX,intY,COLORREFcrColor);
其中,(X,Y)为点的坐标位置,crColor参数为点的颜色值。
如果函数调用成功,则函数返回像素的颜色值,否则返回值为-1。
颜色值通过RGB(Red,Green,Blue)来设置,其中三个参数取值0~255。
例如,在VcAPP项目中,在CVcAppView类中的OnDraw()函数中加入下列画点语句:
//绘制一组彩色点
//绘制一组彩色点
pDC->TextOut(20,20,"point:
");
pDC->SetPixel(100,20,RGB(255,0,0));
pDC->SetPixel(110,20,RGB(0,255,0));
pDC->SetPixel(120,20,RGB(0,0,255));
pDC->SetPixel(100,20,RGB(255,255,0));
pDC->SetPixel(100,20,RGB(255,0,255));
pDC->SetPixel(100,20,RGB(0,255,255));
pDC->SetPixel(100,20,RGB(0,0,0));
pDC->SetPixel(100,20,RGB(255,255,255));
(2)画直线和折线
画直线需要LineTo()和MoveTo()两个函数的配合使用。
LineTo()函数以当前位置所在的点为直线的起点,另指定一个点为直线的终点,画出一段直线。
直线的颜色通过画笔的颜色来设定,在后面介绍。
LineTo()函数原型说明如下:
BOOLCDC:
:
LineTo(intnXEnd,intnYEnd);
直线的终点位置由(nXEnd,nYEnd)指定。
如果函数调用成功,那么该点就成为当前位置,并返回TRUE,否则返回FALSE。
MoveTo()函数只是将当前位置移动到指定位置,它并没有画出直线,其函数说明为:
BOOLCDC:
:
MoveTo(intX,intY);
示例:
在CVcAppView类中的OnDraw()函数中加入下列画点语句:
//绘制直线
pDC->TextOut(20,60,"Line:
");
pDC->MoveTo(20,90);
pDC->LineTo(160,90);
Polyline()函数用来画一条折线,而PolyPolyline()函数则用来画多条折线,它们的函数原型说明如下:
BOOLCDC:
:
Polyline(COUSTPOINT*lppt,intcPoints);
BOOLCDC:
:
PolyPolyline(COUSTPOINT*lppt,COUSTDWORD*lpdwPolyPoints,
DWORDcCount);
在Polyline()函数中,lppt是指向折线顶点数组的指针,而cPoints是折线顶点数组中的顶点数。
例如,绘制一条具有4个顶点的折线,程序如下:
POINTpolylinepoint[4]={{70,240},{20,190},{70,190},{20,240}};
pDC->Polyline(polylinepoint,4);
在PolyPolyline()函数中,lppt是指向保存顶点数组的指针,而各条折线的顶点数则保存在lpdwPolyPoints参数所指向的数组中,最后的cCount参数指定折线的数目。
例如:
POINTpolypolylinePt[9]={{95,160},{120,185},{120,250},{145,160},{120,185},
{90,185},{150,185},{80,210},{160,210}};
DWORDdwPolyPoints[4]={3,2,2,2};//分四段折线,分别占用3,2,2,2个顶点
pDC->PolyPolyline(polypolylinePt,dwPolyPoints,4);
注:
由于一条折线至少需要2个顶点,因此dwPolyPoints数组中的数不应该小于2。
(3)画弧线和曲线
通过Arc()函数画弧线或整个椭圆。
椭圆限定在一个矩形内,称为外接矩形。
Arc()函数的圆形说明如下:
BOOLCDC:
:
Arc(intnLeftRect,intnTopRect,intnRightRect,intnBottomRect,
intnXStartArc,intnYStartArc,intnXEndArc,intnYEndArc);
其中,(nLeftRect,nTopRect)是外接矩形的左上角坐标值,(nRightRect,nBottomRect)是外接矩形的右下角坐标值。
而椭圆中心与点(nXStartArc,nYStartArc)所构成的射线与椭圆的交点成为弧线的起点,椭圆中心与点(nXEndArc,nYEndArc)所构成的射线与椭圆的交点成为弧线的终点。
椭圆上从始点到终点就形成一条弧线。
在Windows系统中,弧线从始点到终点的方向是逆时针方向,但可以通过SetArcDirection()函数将绘制弧线方向设置为顺时针方向。
示例,用Arc()绘制圆、圆弧和椭圆,程序如下:
for(i=0;i<6;i++)
{
pDC->Arc(260-5*i,70-5*i,260+5*I,70+5*i,260+5*i,70,260+5*i,70);
}
for(i=3;i<6;i++)
{
pDC->Arc(260-10*i,70-10*i,260+10*i,70+10*i,
(int)260+10*i*cos(60*3.1415926/180),
(int)70+10*i*sin(60*3.1415926/180),
(int)260+10*i*cos(60*3.1415926/180),
(int)70-10*i*sin(60*3.1415926/180));
pDC->Arc(260-10*i,70-10*i,260+10*i,70+10*i,
(int)260-10*i*cos(60*3.1415926/180),
(int)70-10*i*sin(60*3.1415926/180),
(int)260-10*i*cos(60*3.1415926/180),
(int)70+10*i*sin(60*3.1415926/180));
}
Bezier曲线是最常见的非规则曲线之一。
Bezier曲线属于三次曲线,需要四个控制顶点来确定一条Bezier曲线,其中曲线通过第一点和最后一点,并且第一条边和最后一条边是曲线在起点和终点处的切线,从而确定了曲线的走向。
PolyBezier()函数可以画出一条或多条Bezier曲线,其函数原型说明如下:
BOOLCDC:
:
PolyBezier(CONSTPOINT*lppt,DWORDcPoints);
其中,lppt参数是曲线控制顶点所组成的数组,cPoints参数表示lppt数组中的顶点数,一条Bezier曲线需要四个控制顶点。
如果lppt数组用于画多条Bezier曲线,第二条以后的曲线只需要三个控制顶点,因为后面的曲线总是把前一条曲线的终点作为自己的起点。
示例,给出四个控制顶点,画出一条Bezier曲线和特征多边形。
//绘制Bezier曲线
POINTpolyBezier[4]={{20,310},{60,240},{120,300},{160,330}};
pDC->Polyline(polyBezier,4);
pDC->PolyBezier(polyBezier,4);
(4)画封闭曲线
Windows中提供了一组画封闭曲线的函数,包括绘制矩形、多边
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机 图形学 实验 指导书 vc
![提示](https://static.bdocx.com/images/bang_tan.gif)