正文内容
《计算机图形学》实验报告
来源:莲生三十二
作者:开心麻花
2025-09-18
1

《计算机图形学》实验报告(精选8篇)

《计算机图形学》实验报告 第1篇

实 验 报 告

一、实验目的

1、掌握有序边表算法填充多边形区域;

2、理解多边形填充算法的意义;

3、增强C语言编程能力。

二、算法原理介绍

根据多边形内部点的连续性知:一条扫描线与多边形的交点中,入点和出点之间所有点都是多边形的内部点。所以,对所有的扫描线填充入点到出点之间所有的点就可填充多边形。

判断扫描线上的点是否在多边形之内,对于一条扫描线,多边形的扫描转换过程可以分为四个步骤:

(1)求交:计算扫描线与多边形各边的交点;(2)排序:把所有交点按x值递增顺序排序;

(3)配对:第一个与第二个,第三个与第四个等等;每对交点代表扫描线与多边 形的一个相交区间;(4)着色:把相交区间内的象素置成多边形颜色,把相交区间外的象素置成背景色。

p1,p3,p4,p5属于局部极值点,要把他们两次存入交点表中。如扫描线y=7上的交点中,有交点(2,7,13),按常规方法填充不正确,而要把顶点(7,7)两次存入交点表中(2,7,7,13)。p2,p6为非极值点,则不用如上处理。

为了提高效率,在处理一条扫描线时,仅对与它相交的多边形的边进行求交运算。把与当前扫描线相交的边称为活性边,并把它们按与扫描线交点x坐标递增的顺序存放在一个链表中,称此链表为活性边表(AET)。

对每一条扫描线都建立一个与它相交的多边形的活性边表(AET)。每个AET的一个节点代表一条活性边,它包含三项内容

1.x-当前扫描线与这条边交点的x坐标;

2.Δx-该边与当前扫描线交点到下一条扫描线交点的x增量; 3.ymax-该边最高顶点相交的扫描线号。

每条扫描线的活性边表中的活性边节点按照各活性边与扫描线交点的x值递增排序连接在一起。

当扫描线y移动到下一条扫描线y = y+1时,活性边表需要更新,即删去不与新扫

描线相交的多边形边,同时增加与新扫描线相交的多边形边,并根据增量法重新计算扫描线与各边的交点x。

当多边形新边表ET构成后,按下列步骤进行:

① 对每一条扫描线i,初始化ET表的表头指针ET[i]; ② 将ymax = i的边放入ET[i]中;

③ 使y =多边形最低的扫描线号; ④ 初始化活性边表AET为空; ⑤ 循环,直到AET和ET为空。

 将新边表ET中对应y值的新边节点插入到AET表。 遍历AET表,将两两配对的交点之间填充给定颜色值。

 遍历AET表,将 ymax= y的边节点从AET表中删除,并将ymax> y的各边节点的x值递增Δx;并重新排序。 y增加1。

三、程序源代码

#include “graphics.h” #define WINDOW_HEIGHT 480 #define NULL 0 #include “alloc.h” #include “stdio.h” #include “dos.h” #include “conio.h” typedef struct tEdge /*typedef是将结构定义成数据类型*/ { int ymax;/* 边所交的最高扫描线号 */ float x;/*当前扫描线与边的交点的x值 */ float dx;/*从当前扫描线到下一条扫描线之间的x增量*/ struct tEdge *next;}Edge;

typedef struct point{int x,y;}POINT;/*将结点插入边表的主体函数*/

void InsertEdge(Edge *list,Edge *edge)/*活性边edge插入活性边表list中*/ { Edge *p,*q=list;p=q->next;/*记住q原来所指之结点*/ while(p!=NULL)/*按x值非递减顺序增加边表*/ {

if(edge->x

x)/*要插入的边的x较大不应该在当前插入*/

p=NULL;

else /*要插入的边的x较小应该在当前插入*/

{q=p;

p=p->next;

} } edge->next=q->next;/*使欲插入之结点edge指向q原来所指之结点*/ q->next=edge;/*使q指向插入之结点*/ }

int yNext(int k,int cnt,POINT *pts)/*对于多边形中的某个顶点序号k(0,1...6),返回下一顶点的纵坐标,如果这2个顶点所在边是 水平的,则顺延,即返回第(k+2)个顶点的纵坐标),cnt是顶点个数+1,pts指向多边形顶点结构体的指针*/

{ int j;if((k+1)>(cnt-1))/*当前顶点为最后一个顶点,则下一个顶点为第0个顶点 */

j=0;else

j=k+1;/*当前顶点不是最后一个顶点,下一个顶点为数组下标加一*/ while(pts[k].y==pts[j].y)/*扫描线扫过平行顶点,需分情况找到当前顶点下下个顶点*/ if((j+1)>(cnt-1))

j=0;

else

j++;return(pts[j].y);/*返回下一个顶点的y值 */ }

/* 计算增量,修改AET*/ /*生成边表结点,并插入到边表中的主体函数*/ void MakeEdgeRec(POINT lower,POINT upper,int yComp,Edge *edge,Edge *edges[])/*把边结点edge,放到lower.y扫描线所在的边结点指针数组edges[]中 */ {edge->dx=(float)(upper.x-lower.x)/(upper.y-lower.y);edge->x=lower.x;if(upper.yymax=upper.y-1;/*缩短上层顶点*/ /*奇点,应该把这点当作两个点而分开,所以把y的最大值减一,向下移动*/ else edge->ymax=upper.y;/*不是奇点,不需改变y值 */ insertEdge(edges[lower.y],edge);/*插入一个边缘扫描线,插入到列表 */ }

/*创建边表的主体函数*/ void BuildEdgeList(int cnt,POINT *pts,Edge *edges[])/*建立新边表,cnt:多边形顶点个数+1,edges[]:指向活性边结点的指针数组*/ { Edge *edge;POINT v1,v2;int i,yPrev=pts[cnt-2].y;/*当前顶点的前一个顶点的y值,在当前顶点不是奇点时使用该参数*/ v1.x=pts[cnt-1].x;v1.y=pts[cnt-1].y;for(i=0;i

edge=(Edge *)malloc(sizeof(Edge));

edge=(Edge*)malloc(sizeof(Edge));if(v1.y

yNext*/ MakeEdgeRec(v1,v2,yNext(i,cnt,pts),edge,edges);/*确定v1,v2边较高端点的开闭*/

else

MakeEdgeRec(v2,v1,yPrev,edge,edges);/*当前顶点

是奇点*/ } yPrev=v1.y;v1=v2;} }

/*建立活性边表的主体函数:建立第scan条扫描线的活性边表*/ void BuildActiveList(int scan,Edge *active,Edge *edges[])/*建立扫描线scan的活性边表,把活性边结点放入扫描线scan的结点指针数组 edges[scan]中*/ { Edge *p,*q;p=edges[scan]->next;/*查找当前扫描线对应的y桶*/ while(p)/*y桶不空*/

{q=p->next;/*找到最后一个边结点,插入*/

InsertEdge(active,p);/*把更新后的边表重新插入边表中保存*/

p=q;

} }

/*填充一对交点的主体函数*/ void FillScan(int scan,Edge *active,int color)/*填充扫描线:填充扫描线上,且在下一结点到再下一结点之间的点*/ { Edge *p1,*p2;int i;p1=active->next;while(p1){

p2=p1->next;

for(i=p1->x;i

x;i++)

putpixel((int)i,scan,color);/*画出图形内部的点*/ p1=p2->next;/*活性表的下一条边表 */ } }

void DeleteAfter(Edge *q)/*删除链表中结点,删除边结点q的后续结点p*/ { Edge *p=q->next;q->next=p->next;/*删除结点*/ free(p);} /* 删除 y=ymax 的边 */

/*填充完后,更新活动边表的主体函数*/ void UpdateActiveList(int scan,Edge *active)/*删除扫描线scan完成交点计算的活性边,同时更新交点x域*/ { Edge *q=active,*p=active->next;while(p)if(scan>=p->ymax)/*扫描线超过边的最大y值,此条边的节点应该删掉*/ { p=p->next;deleteAfter(q);} else /*扫描线未超过边的最大y值,相应的x值增加*/ { p->x=p->x+p->dx;q=p;p=p->next;} }

/*对活性边表结点重新排序的主体函数*/ void ResortActiveList(Edge *active)/*活性边表active中的结点按x域从小到大重新排序*/ { Edge *q,*p=active->next;active->next=NULL;while(p){q=p->next;InsertEdge(active,p);/*把更新后的边表重新插入边表中保存 */ p=q;} }

/*多边形填充的主体程序*/ void ScanFill(int cnt,POINT *pts,int color)/*填充函数,输入:多边形顶点个数+1=cnt, 指向多边形顶点的指针数组pts*/

{ Edge *edges[WINDOW_HEIGHT],*active;int i,scan,scanmax=0,scanmin=WINDOW_HEIGHT;for(i=0;i

{if(scanmax

if(scanmin>pts[i].y)scanmin=pts[i].y;

} for(scan=scanmin;scan<=scanmax;scan++)/*初始化每条扫面线的边链表*/ {edges[scan]=(Edge *)malloc(sizeof(Edge));/*建

edges[scan]->next=NULL;

} BuildEdgeList(cnt,pts,edges);/*建立有序边表*/ active=(Edge *)malloc(sizeof(Edge));“桶”*/ active->next=NULL;for(scan=scanmin;scan<=scanmax;scan++)/*扫描每条扫描线,求活性表*/ {

BuildActiveList(scan,active,edges);/*建立活性边表*/

if(active->next)/*活性边表不为空*/

{ FillScan(scan,active,color);/*填充当前扫描线*/ UpdateActiveList(scan,active);/*更新活化边表*/ ResortActiveList(active);/*重排活化边表*/

} } }

/*开始菜单*/ void main(){ POINT pts[7];/*保存数组*/ int gdrive=DETECT,gmode;pts[0].x=100;pts[0].y=40;/*多边形顶点x、y坐标*/ pts[1].x=220;pts[1].y=140;pts[2].x=280;pts[2].y=80;pts[3].x=350;pts[3].y=300;pts[4].x=200;pts[4].y=380;pts[5].x=50;pts[5].y=280;pts[6].x=100;pts[6].y=40;/*合并桶中的新边,按次序插入到 AET 中*/ initgraph(&gdrive,&gmode,“C:TC3.0BGI”);/*设置graphic模式*/ ScanFill(7,pts,2);getch();}

四、实验结果

图1 用有序边表算法生成的多边形

五、总结与体会

实验步骤

1)分析多边形区域扫描线填充算法的原理,确定算法流程

① 初始化:构造边表,AET表置空

② 将第一个不空的ET表中的边插入AET表

③ 由AET表取出交点进行配对(奇偶)获得填充区间,依次对这些填充区间着色

④ y=yi+1时,根据x=xi+1/k修改AET表所有结点中交点的x坐标。同时如果相 应的ET表不空,则将其中的结点插入AET表,形成新的AET表 ⑤ AET表不空,则转(3),否则结束。2)编程实现

① 首先确定多边形顶点和ET/AET表中结点的结构

② 编写链表相关操作(如链表结点插入、删除和排序等)

③ 根据1)中的算法结合上述已有的链表操作函数实现多边形区域扫描线填充的主体功能

④ 编写主函数,测试该算法 通过运用C语言环境下的图像显示设置,本次实验我学会了多边形区域扫描线填充的有序边表算法,设计相关的数据结构(如链表结构、结点结构等),并将实现的算法应用于任意多边形的填充,为深一步的学习做好了铺垫。

六、参考文献

[1]张家广 等编著.计算机图形学(第3版).北京:清华大学出版社,1998年9月.[2]陈传波,陆枫主编,《计算机图形学基础》,电子工业出版社,2002年3月.

《计算机图形学》实验报告 第2篇

计算机科学与技术学院

《计算机图形学》实验报告

班级: 211923班

学号: 21190928

姓名: 林星宇

2021-2022学年第1学期

实验项目1

边标志算法的实现

实验性质

□演示性实验 验证性实验

□操作性实验 综合性实验

实验地点

计算机楼B212

机器编号

一、实现的功能

编写应用程序,采用鼠标输入顶点的方法确定待填充多边形(多边形最后一点双击);实现边标志算法完成对该多边形的填充,要求 完成使用自己学号的后四位数字对多边形内部进行填充。

二、采用的图形学算法及实现

(算法的实现函数是什么(函数名,参数,返回值,函数功能等)以及采用了哪些数据结构(数组,链表等))

要求使用边标志算法的原理和实 现方法,所以使用了EdgeMarkFill函数,即边标志算法:

void CMFCDrawTestView::EdgeMarkFill(CDC* pDC, CArray* plist, COLORREF color)

pDC为设备环境变量指针,plist为多边形点表,color为传入的RGB()值。

int zima[16][32]为学号后4位二维数组。

X1,x2,y1,y2分别为多边形上的最小最小大,y值

三、采用的交互方式及实现

(采用了哪些交互方式来完成绘制,这些交互方式应用到了哪些系统消息,是如何实现的)

边填充的实现:编写应用程序,采用鼠标输入顶点的方法确定待填充多边形(多边形最后一点双击);实现边标志算法完成对该多边形的填充,要求 完成使用自己学号的后四位数字对多边形内部进行填充。

易知,在画完多边形后,即双击左键(OnLButtonUp)后,使用EdgeMarkFill函数。

Type=2时,在OnLButtonUp中,调用EdgeMarkFill(pDC,&(obj->points), RGB(r, 0, 0));

四、实验结果

(程序的运行结果)

应用程序运行后,标志算法完成对该多边形的填充的图形结果如下:

五、遇到的问题及解决办法

问题1:(在实现过程中遇到了什么样的问题,及采用了何种解决办法)

在获取下x1,x2,y1,y2时,因为Dos界面x、y大小颠倒的原因,获取时出现了问题。

首先,通过for(int i = 1;i < plist->GetSize();i++){

CPoint p = plist->GetAt(i);

if(x1 > p.x)x1 = p.x;

if(x2 < p.x)x2 = p.x;

if(y1 > p.y)y1 = p.y;

if(y2 < p.y)y2 = p.y;

}

获取x1,x2,y1,y2.在遍历多边形过程中:

int count = plist->GetSize();

for(int i = 0;i < count;i++){

CPoint p1 = plist->GetAt(i);

CPoint p2 = plist->GetAt((i + 1)% count);

if(p1.y == p2.y)

continue;

if(p1.y > p2.y)

{

CPoint p;p = p1;p1 = p2;p2 = p;

}

xs = p1.x;

dxs =(p2.x-p1.x)/(double)(p2.y-p1.y);

//dys = abs(p2.y-p1.y)/(p2.y-p1.y);

for(ys = p1.y;ys!= p2.y;ys += 1)

{

Ixs = int(xs + 0.5);

MARK[ys][Ixs] =!MARK[ys][Ixs];

xs = xs + dxs;

}

黄线处即为处理x1,x2,y1,y2的大小。

问题2:通过数组zima[][]来确定多边形区域填充学号后4位时,zima[y ][x ]未%其字长,即zima[y % 16][x % 32]。后改为:

for(y = y1;y <= y2;y++)

{

bool inside = false;

for(x = x1;x <= x2;x++)

{

if(MARK[y][x])

inside =!inside;

if(inside)

{

if(zima[y % 16][x % 32])

pDC->SetPixel(x, y, RGB(255, 0, 0));

}

}

}

实验项目2

立方体的比例、平移、旋转变换及投影显示

实验性质

□演示性实验 验证性实验

□操作性实验 综合性实验

实验地点

计算机楼B212

机器编号

一、实现的功能

建立立方体的数据模型;编写应用程序,利用菜单和键盘结合的方式完成对立方体的移动、比例和旋转变换,并显示透视或斜二测投影结果。要求应用程序具有如下功能:

1、通过菜单选择的方式,选择对三维空间中的立方体作斜二测投 影或透视投影;

2、通过键盘按键或鼠标移动的方式,完成对三维空间中的立方体 进行平移变换(上下左右前后),比例变换(放大或缩小)以及 旋转变换(绕 x,y,z 轴),并同时显示变换后的投影结果

3、创建对话框,通过对话框设置透视投影时候的投影中心,以及旋转变换时候的旋转轴(可以设置成分别绕 x 轴,y 轴,z 轴进 行旋转)

二、采用的图形学算法及实现

(算法的实现函数是什么(函数名,参数,返回值,函数功能等)以及采用了哪些数据结构(数组,链表等))

题目要求实现立方体的移动、比例和旋转变换,并显示透视或斜二测投影结果。

对要求1:在菜单选TY项中选择斜二测投影(斜二=1)或透视投影(透视=1)。然后在OnDraw中调用Draw_Cubic(CDC* pDC)画出立方体。

对要求2:在OnKeyDown中调用函数,即在键盘上按“S”使立方体变小,“B”使立方体变大,“←”“→”“↑”“↓”使立方体左右上下移动。

对要求3:在菜单XYZ中选择旋转的x,y,z轴,即x=1或y=1或z=1,然后在OnKeyDown中调用函数,即按键盘上的“T”或“P”.

三、采用的交互方式及实现

(采用了哪些交互方式来完成绘制,这些交互方式应用到了哪些系统消息,是如何实现的)

由题目要求1,易知需要一个函数Draw_Cubic(CDC* pDC)画出立方体的斜二测投影或透视投影并且建立一个菜单栏TY(投影)。即在菜单选TY项中选择斜二测投影(斜二=1)或透视投影(透视=1)。然后在OnDraw中调用Draw_Cubic(CDC* pDC)画出立方体。

由题目要求2:易知直接在OnKeyDown函数上添加使立方体变大变小,前后左右平移的功能。即即在键盘上按“S”使立方体变小,“B”使立方体变大,“←”“→”“↑”“↓”使立方体左右上下移动。

由题目要求3:建立一个菜单XYZ决定旋转的轴。

四、实验结果

(程序的运行结果)

斜二测投影:

斜二测投影平移到左上角:

斜二测投影平移到右下角:

斜二测投影变大:

斜二测投影变小:

斜二测投影变为透视投影:

斜二测投影绕z轴旋转:

五、遇到的问题及解决办法

(在实现过程中遇到了什么样的问题,及采用了何种解决办法)

问题1:一开始建立立方体时,没有建立边表,导致投影困难。

后来建立了点表和对应的边表。

问题2:一开始Draw_Cubic中x1, y1,z1, x2, y2,z2定义为了int型。

实验项目3

用矩形窗口对多边形进行裁剪

实验性质

□演示性实验 验证性实验

□操作性实验 综合性实验

实验地点

计算机楼B212

机器编号

一、实现的功能

编写应用程序实现多边形裁剪。要求首先采用鼠标确定裁剪区域(矩形区域),然 后用鼠标输入待裁剪的多边形(可分别使用鼠标左键和右键来确定裁剪区域和待裁剪 的多边形)。多边形绘制完毕后进行裁剪,以不同颜色显示被裁剪对象位于窗口内(此 部分应保证多边形的完整性)及外部的部分。

二、采用的图形学算法及实现

(算法的实现函数是什么(函数名,参数,返回值,函数功能等)以及采用了哪些数据结构(数组,链表等))

因为要编写应用程序实现多边形裁剪。要求首先采用鼠标确定裁剪区域(矩形区域),然 后用鼠标输入待裁剪的多边形(可分别使用鼠标左键和右键来确定裁剪区域和待裁剪 的多边形)。所以要使用多边形裁剪算法,即Cut_Top(),Cut_Bottom(),Cut_Left(),Cut_Right()四个函数。

Cut()函数为用绿色显示被裁剪对象位于窗口内部分。

存在int type的变量;

当type=1时,在OnLButtonUp中画出矩形框。

当type=2时,画出多边形,在左键双击后,在OnLButtonDblClk中调用如下函数:Cut_Top();Cut_Right();Cut_Bottom();Cut_Left();Cut();

裁剪多边形在,并标出在矩形内部的部分。

三、采用的交互方式及实现

(采用了哪些交互方式来完成绘制,这些交互方式应用到了哪些系统消息,是如何实现的)

编写应用程序实现多边形裁剪。要求首先采用鼠标确定裁剪区域(矩形区域),然 后用鼠标输入待裁剪的多边形(可分别使用鼠标左键和右键来确定裁剪区域和待裁剪 的多边形)。多边形绘制完毕后进行裁剪,以不同颜色显示被裁剪对象位于窗口内(此 部分应保证多边形的完整性)及外部的部分。

根据以上绘制方法,可知需要处理WM_OnLButtonDblClk(左键双击)及WM_LButtonUp(左键抬起)消息,为了绘制橡皮线,还需处理调用WM_MouseMove(鼠标移动)消息。

因为可以用鼠标画出矩形和多边形,所以这么规定,当type=1时画矩形,即:

DDALine(pDC,lx,by,lx,ty,RGB(r, g, b));

DDALine(pDC, lx, by, rx, by, RGB(r, g, b));

DDALine(pDC, rx, by, rx, ty, RGB(r, g, b));

DDALine(pDC, lx, ty, rx, ty, RGB(r, g, b));

当type=2时画多边形,而后裁剪,即:

for(int i = 0;i < pointList.GetSize();i++)

{

p1 = pointList.GetAt(i);

p2 = pointList.GetAt((i+1)% count);

DDALine(pDC, p1.x, p1.y, p2.x, p2.y, RGB(0,255,0));

}

四、实验结果

(程序的运行结果)

裁剪结果如下图所示,黑色为裁剪窗口,红色为多边形被裁剪的部分,绿色为多边形裁剪后的部分:

五、遇到的问题及解决办法

(在实现过程中遇到了什么样的问题,及采用了何种解决办法)

问题1:我在裁剪使一开始对多边形做上下左右裁剪时,这四个步骤是分别对原图形裁剪,而不是对图形接连进行裁剪。后来在裁剪函数上先除去之前图形,然后把已裁剪多边形重新构建。如下:

pointList.RemoveAll();

for(int i = 0;i < m;i++)

pointList.Add(CP[i]);

问题2:在多边形被矩形裁剪的部分显现不同颜色花费了挺多时间,后来我直接让裁剪的部分颜色被覆盖就可以了。如下:

for(int i = 0;i < pointList.GetSize();i++)

{

p1 = pointList.GetAt(i);

p2 = pointList.GetAt((i+1)% count);

DDALine(pDC, p1.x, p1.y, p2.x, p2.y, RGB(0,255,0));

计算机图形学实验课程改革探讨 第3篇

1 教学中存在的问题

图形学教学中会存在如下问题:一是实验教材选择不恰当;二是很多高校图形学实验都是基于Turbo C环境下的编程, 因编程界面不够友好, 使用不方便, 多数学生对它不感兴趣。三是过分注重理论教学, 实践教学的时间远比理论教学时间少;四是过分强调图形学的数学基础;五是实践课程设置合理, 但是实验内容有的过于简单, 而有的又太难。以上五方面都会导致学生学习兴趣不浓或厌学。针对此, 对实验课程进行改革是非常必要的。

2 图形学教学改革措施

如何针对本校学生实际制定适合其学习的实验方案尤其重要。通过笔者多年的教学实践, 我们可以通过计算机图形学实验的演示、验证和开发, 来巩固学生对计算机图形学所学知识的理解, 同时加强学生的动手操作能力。可以从以下几方面进行改革。

2.1 教材选取

目前, 图形学教材非常的多, 大部分的经典教材中讲解的知识较多、难度较大, 学生学习较吃力。如何选用教材, 使学生学到更多知识很重要。在教学的过程中, 针对地方高校的特点, 学生的基础较差。笔者在教学中, 把教学重点定位为二维知识的掌握;三维知识只作简单的了解和介绍, 以此来降低学生学习难度, 提高学习兴趣, 为以后的三维知识的学习打好基础。因此, 在选择教材时, 尽量考虑偏重二维知识的、包括程序代码的, 利于学生上机实验的教材。

2.2 编程环境选择

针对Turbo C编程环境存在的问题, 我们在实验过程中可以基于Visual C++的MFC编程。因为VC开发环境是可视化的, 编写的程序执行结果明显, 学生有成就感, 对完成实验更有自信[2,3]。通过实验, 学生不但可以学习实用的编程语言, 而且也促进其对新知识的学习。

2.3 实验教学改革

目前, 课程开展了九个实验, 实验内容如表1所示, 其中实验类型有验证性、设计性和综合性三种。验证性实验是让学生对理论课程学习的图形学基本算法进行编程验证;设计性实验是一种探索性的实验, 不但要求学生综合多种知识来设计实验方案, 而且要求学生能充分运用已学到的知识, 去发现问题、解决问题, 实验中, 学生自己选题、自己设计, 在教师的指导下进行, 以最大限度发挥学生学习的主动性;综合性实验是通过学生一段时间的学习, 具有一定的图形学综合知识和技能, 且实验内容涉及到这些知识和技能的实验[4]。

2.4 实验项目说明

实验1中, 关键是熟悉VC的MFC编程环境, 了解如何创建工程及添加消息以及MFC绘图函数的使用。

实验2中将验证直线生成算法。通过理论分析直接直线生成算法、DDA算法、Bresenham算法、中点画线算法等, 找到各算法的优缺点, 对比各种算法运行的速度;然后通过上机实现上述算法, 并比较各算法在生成同一直线时的效率。

实验3中对比中点画圆算法与Bresenham画圆算法的实现机制及运行效率。

实验4中主要是验证课本中内点表示、边界表示的4连通或8连通种子填充算法填充规则图形 (矩形、圆等) 及不规则图形 (任意形状各异的图形) 。实验中, 对于基础好的同学, 还可试着采用扫描线多边形填充算法 (选做) 来填充一个简单的图形内部。

实验5中主要是运用已学过的各种图形学的知识来填充圆的内部。A.点到圆心的距离小于等于半径;B.种子填充法;C.Bresenham画圆法;D.用改进的Bresenham画圆算法;E.中点画圆算法;F.改进的中点画圆算法等。并对比各种算法在填充圆的内部时的差异。 (见表2)

实验6主要是验证Cohen-Sutherland直线裁剪算法。实验主要是基于矩形窗口的直线裁剪, 对于三类型直线裁剪的正确性进行验证:一是直线完全在矩形窗口内;二是直线完全在矩形窗口外;三是直线与矩形窗口有交。其他直线裁剪算法的验证可选做。

实验7中, 可针对生成的一个简单图形实现其二维变换。例如三角形的比例、平移、旋转变换等。

实验8中, 主要是实现课本中的Bezier曲线生成算法。若能正确生成Bezier曲线, 可以结合图形变换知识和平面曲线知识实现的正叶线、正叶线蝴蝶结等图形的生成。

实验9中, 可以结合本学期的学习情况, 利用所学的图形学知识, 发挥想象力, 设计一个图形学作品。例如:雪人, 火车等。

3 结语

从文中的实验教材、实验教学环境以及实验教学内容的选取以及多年的教学经验, 可以看出在计算机图形学实验课程教学中, 首先要加强理论与实践相结合, 要进行培养方案修改, 加大实验课的比例;其次要针对学生的特点, 找到适合当前学生学习的方法和实验内容进行教学。经过改革后, 教学效果较好。

参考文献

[1]伏玉琛, 周洞汝.计算机图形学——原理、方法与应用[M].武汉:华中科技大学出版社, 2003.

[2]廖方茵, 丁凰.计算机图形学实验教学的改进[J].北京电力高等专科学校学报, 2009 (5) :2-3.

[3]陈莉.谈计算机图形学的教学与实验[J].计算机教育, 2014 (10) :51-54.

对计算机图形学的教学探讨 第4篇

关键词:计算机图形学;教学方法;算法;实践

一、认真组织课堂教学内容

计算机图形学这门功课,没有学习积极性和主动性是很难学好的。难学是学习积极性的主要障碍。因此在教学内容上,应注意以下两點:

1.充分注意学生的接受程度,教学内容要“精”。首先是注重基础,强调基本概念、基本原理,以如何“逼真”地模拟现实世界的物体为主线。其次也要突出重点,对一些要求掌握的算法要仔细分析,强调其基本思想、基本原理。只要算法的基本思想掌握了,算法的实现就容易理解,对相关算法就可举一反三、触类旁通。在教学内容上,也应注意“新”。教学内容的选取应跟上学科发展的步伐,介绍一些当前的研究热点及重要文献,使学生了解学科发展情况,也同时增加课堂教学的趣味性。

2.在教学内容上,还应注意理论与实用软件之间的关系。应介绍计算机图形学的理论、算法在流行的图形设计和动画制作软件(如AutoCAD、3DMAX等)中的应用,促进理论学习和实用软件使用形成互动。如:流行软件中对图形变换、裁剪、消隐等的操作与使用,有助于对图形变换理论、裁减算法、消隐算法等理论知识的学习。

二、注重教学方法和手段

在教学方法上,注意启发性。如在讲画线算法前,应思考:为什么在屏幕上画出直线段时,经常出现锯齿,如何解决,等等。这些问题可以引导学生预习和自学,减轻课堂负担,使课堂教学的目标清晰,任务简化。

强调对比学习方法,对解决同一问题的不同方法进行比较,如Bezier、B样条、NURBS曲线曲面间的比较,CSG树、边界表示法、八叉树表示等实体造型技术间的比较等。

在教学手段上,采用多媒体教学与传统的教学方式相结合,充分发挥图形图示、动画演示的作用,“一幅画胜过千言万语”。我们在教学中制作了多媒体教学课件,而且设计了典型算法(如Bezier曲线、B样条曲线、光线跟踪算法等)演示系统,这些工作对于提高学生学习兴趣、增强原理、算法的理解性具有很大的作用。

三、恰当设计课前、课后习题

习题应与课堂教学、上机实验等环节的工作结合起来。习题可分为课后习题和课前思考题。课前思考题具有一定的引导作用,帮助学生预习和自学,减轻课堂负担,使课堂教学的目标清晰,任务简化。课后习题是对课堂教学内容的消化、吸收、补充、完善和提高。

习题一定要精心设计和选择,特别要避免作业形式单一、难度较大,否则就会使学生产生畏难情绪。注意循序渐进、难易适度。注重基础,注意多层次(如基础知识、算法设计和综合应用题等)、多形式(如判断题、选择题、填空题、简答题、算法设计题、综合应用题等),使学生得到全面的训练。

四、充分重视实验教学

计算机图形学课程具有很强的实践性,上机实验是其重要环节。实验类型分为两部分:一是编程能力的训练,另一个是流行软件的使用。这两方面应有机地结合起来,相互促进,以有利于图形学理论和算法的掌握。学会一种或几种流行的图形设计和动画制作软件(如AutoCAD、3DMAX等)的使用,分析计算机图形学在这些软件中的具体应用,如图层、交互技术(如橡皮筋技术、引力场技术等)等,对学习计算机图形学的理论和学习这些软件本身都是非常有益的。

编程环境可以选择Visual C++/Visual Basic,由学生自己确定。实际上,Visual Basic相对简单易学,而且功能强大,也适合作为计算机图形学实验的编程工具。注意加强实验过程的管理:实验前认真准备,实验过程中认真完成,实验课后认真总结。根据实验过程及实验报告评定每次实验成绩。为确保实验教学的质量,上机实验既要有趣味性,又要有挑战性。

五、课程设计必不可少

课程设计是计算机图形学实践教学的另一个重要环节,是对学生计算机图形学课程以及相关知识的综合测试,课程设计在课程教学的中后期完成。课程设计的题目、要求在该课程的中期给出,题目也可自拟。课程设计任务不宜过难,最好在实验课的基础上进行,可以是实验的综合、改进、完善等。要求在规定的期限内完成所有的文档资料(包括源程序清单、可执行程序等),并评定课程设计成绩,作为课程总成绩的重要组成部分。

六、严格教学的过程化管理与考核

重视教学的过程化管理与考核是保证教学质量的重要手段。对课堂、作业、实验等环节进行有效的管理,及时发现和纠正每一环节中存在的问题。过程化考核体现在评定学生的课程成绩时,全面考核各重要教学环节,如上课、作业、实验、课程设计、期末考试等的学习情况。教师应充分重视学生平时的学习情况,鼓励他们在平时作业、实验、课程设计中独立思考,并有所创新。每次作业、实验都要给出等级,各环节的学习情况都要逐一评定成绩,并按比例记入到课程的总成绩中。

参考文献:

[1]孙家广,扬长贵.计算机图形学[M].北京:清华大学出版社,1996.

计算机图形学实验 第5篇

最近自己在学习如何在VC 6.0 开发环境下的使用MFC AppWizard(exe)来绘画一条直线,虽然比较简单,通过这样的练习可以帮助你熟悉MFC的开发环境以及其中的消息传递机制,希望对于像我一样初入MFC图形绘制学习的人有帮

第一步:构建MFC窗体

打开Visual C++ 6.0编译器 新建→工程→MFC AppWizard(exe),工程名以DrawLine为例,然后确定。为了方便,在MFC应用程序向导—步骤1当中选择“单文档”,其余所有的步骤都为默认值,直接“完成”。这样一个简单的MFC窗体就构建好了,自己不妨Compile—Build—BuildExecute一下。

第二步:编辑菜单项

选择ResourceView视窗展开Menu文件夹,左键双击IDR_DRAWLITYPE,右边就会出现菜单图形编辑界面,为了简化,我们只在添加帮助→DrawLine功能选择项。双击空白会弹出“菜单项目 属性”对话框。ID:ID_DRAW_LINE;标明:

DrawLine(&D),其它的为缺省。

第三步:建立消息命令

如果此时运行该程序,你会发现帮助—DrawLine的功能选项是灰色的,原因就在于我们还没有添加该功能的消息命令相应函数。通过“查看—Message Maps—Project:DrawLine—Class name:CDrawLineView—Object IDs:ID_DRAW_LINE—选定COMMAND—Add Function„”,其它为默认,最后确定完成。现在如果再重新运行该程序的话,会发现原来的灰色已经消除了。

第四步:添加鼠标消息响应

打开ClassView视窗,右键选定CDrawLineView,选择Add Windows Messsage Handler会弹出对话框,完成CDrawLineView类的WM_LBUTTONDOWN、WM_MOUSEMOVE、WM_LBUTTONUP三个Windows消息事件的新建。

第五步:添加响应代码

首先,在ClassView视窗中双击CDrawLineView会定位到“DrawLineView.h : interface of the CDrawLineView class”的文件,添加CDrawLineView类的成员:protected: int m_Drag;POINT m_pPrev;POINT m_pOrigin;三个成员变量。视窗中展开CDrawLineView类,双击定位OnLBUTTONDOWN()函数。在该函数消息响应

处添加如下代码:

//建立好绘图的设备环境

CClientDC dc(this);OnPrepareDC(&dc);

dc.DPtoLP(&point);

//获取起始点坐标 m_pPrev=point;m_pOrigin=point;

m_Drag=1;

然后,定位于OnMouseMove(),添加如下代码(其中关键用到了橡皮筋技术):

//建立好绘图的设备环境

CClientDC dc(this);

OnPrepareDC(&dc);dc.DPtoLP(&point);

dc.SetROP2(R2_NOT);//橡皮筋绘图技术

//判断是否BUTTONDOWN

if(m_Drag)

{

dc.MoveTo(m_pOrigin);dc.LineTo(m_pPrev);dc.MoveTo(m_pOrigin);dc.LineTo(point);

}

m_pPrev=point;

最后,在OnLBUTTONDOWN()添加代码: m_Drag=0;

程序运行效果图

实验4 实现圆的生成算法

一、实验目的

1.熟悉CDC图形程序库; 2.掌握中点画圆生成算法; 3.掌握Bresenham画圆算法。

二、实验内容

利用VisualC++6.0设计一个简易画圆绘图板,验证圆生成算法。

三、实验指导

1.生成绘图应用程序的框架,如下图所示。具体实现见第二次实验,过程不再详细说明。

2.在应用程序中增加菜单

完成相关菜单的设计,具体的效果如下图所示,并设置好相关菜单消息的映射,具体的实现在前面的实验中介绍过,再此不在详细说明。

3.在绘图函数中添加代码

通过以上步骤,得到了与菜单对应的消息映射,就可以在函数中添加代码绘制图形了。(1)利用中点画圆算法实现圆的生成(算法原理见教材)。void CDraw_CirView::OnMid(){ // TODO: Add your command handler code here CDC*pDC=GetDC();//得到绘图类指针

RedrawWindow();//重绘窗口

int x,y,x0=200,y0=200,r=100;//圆的圆心为(x0,y0),半径为r float d;x=0;y=r;d=1.25-r;

pDC->SetPixel(x+x0,y+y0,RGB(255,0,0));pDC->SetPixel(y+x0,x+y0,RGB(255,0,0));pDC->SetPixel(y+x0,-x+y0,RGB(255,0,0));pDC->SetPixel(x+x0,-y+y0,RGB(255,0,0));pDC->SetPixel(-x+x0,-y+y0,RGB(255,0,0));pDC->SetPixel(-y+x0,-x+y0,RGB(255,0,0));pDC->SetPixel(-y+x0,x+y0,RGB(255,0,0));pDC->SetPixel(-x+x0,y+y0,RGB(255,0,0));while(x<=y){

if(d<0)

{

d=d+2*x+3;

x++;

}

else

{

d=d+2*(x-y)+5;

x++;

y--;}

pDC->SetPixel(x+x0,y+y0,RGB(255,0,0));

pDC->SetPixel(y+x0,x+y0,RGB(255,0,0));

pDC->SetPixel(y+x0,-x+y0,RGB(255,0,0));

pDC->SetPixel(x+x0,-y+y0,RGB(255,0,0));

pDC->SetPixel(-x+x0,-y+y0,RGB(255,0,0));

pDC->SetPixel(-y+x0,-x+y0,RGB(255,0,0));

pDC->SetPixel(-y+x0,x+y0,RGB(255,0,0));

pDC->SetPixel(-x+x0,y+y0,RGB(255,0,0));} } 由以上代码绘出的图形如下:

(2)利用Bresenham算法生成圆(算法原理见教材)。void CDraw_CirView::OnBre(){ // TODO: Add your command handler code here CDC*pDC=GetDC();//得到绘图类指针

//RedrawWindow();//重绘窗口

int x,y,x0=200,y0=200,r=50;//圆的圆心为(x0,y0),半径为r int delta,delta1,delta2,direction;x=0;y=r;delta=2*(1-r);while(y>=0){

pDC->SetPixel(x+x0,y+y0,RGB(0,0,255));

pDC->SetPixel(x+x0,-y+y0,RGB(0,0,255));

pDC->SetPixel(-x+x0,y+y0,RGB(0,0,255));

pDC->SetPixel(-x+x0,-y+y0,RGB(0,0,255));

if(delta<0)

{

delta1=2*(delta+y)-1;

if(delta<=0)direction=1;

else direction=2;

}

else if(delta>0)

{

delta2=2*(delta-x)-1;

if(delta2<=0)direction=2;

else direction=3;

}

else direction=2;

switch(direction)

{

case 1:x++;

delta+=2*x+1;

break;

case 2:x++;y--;

delta+=2*(x-y+1);

break;

case 3:y--;

delta+=(-2*y+1);

break;

} } }

由以上代码绘出的图形如下:

(3)以上是本次实验的基本部分,利用中点画圆和Bresenham画圆算法实现的基本图形的绘制。能不能利用该算法,完成一些复杂图形的生成,比如利用基本的画圆算法绘制一个奥运五环。甚至根据画圆算法,实现二次曲线的生成,如椭圆的生成等等。请同学们认真考虑,完成这部分的内容,上机调试。

四、思考

计算机图形学实验教学研究论文 第6篇

关键词:计算机图形学;分层次实验;虚拟实验;实验设计;数字媒体技术

1引言

3D游戏图形学实验一 第7篇

实验指导书

浙江理工大学 二0一五年十月

数字图像处理实验指导书

课程实验指导

一、实验总体方案

1.教学目标与基本要求

1)掌握本书所介绍的图形算法的原理。

2)掌握通过具体的平台实现图形算法的方法,培养学生使用现代图形系统API的能力。

3)通过实验培养具有开发一个基本图形软件包的能力。2.实验平台

实验主要结合OpenGL设计程序,实现各种课堂教学中讲过的图形算法。程序设计语言主要以C/C++为主,开发平台是Visual C++。

3.实验步骤

1)预习教材与实验指导的实验具体方案部分相关的算法理论及原理。2)仿照教材与实验指导提供的算法,利用VC++ OpenGL进行实验。

3)调试、编译、运行程序,运行通过后,可考虑对程序进行修改或改进。

二、实验预备知识

OpenGL作为当前主流的图形API之一,在一些场合具有比DirectX更优越的特性。

(1)与C语言紧密结合

OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL很容易理解和学习。

(2)强大的可移植性

微软的Direct3D虽然也是十分优秀的图形API,但它只适用于Windows系统,而OpenGL不仅适用于Windows,还可以用于Unix/Linux等其他系统,它甚至在大型计算机、各种专业计算机上都有应用。并且,OpenGL的基本命令都做到了硬件无关,甚至是平台无关。

(3)高性能的图形渲染

OpenGL是一个工业标准,它的技术紧跟时代,现今各个显卡厂家无一不对OpenGL提供强力支持,激烈的竞争中使得OpenGL性能一直领先。

总之,OpenGL是一个非常优秀的图形软件接口。

下面对Windows下的OpenGL编程进行简单介绍。以下几点是学习OpenGL前的准备工作。

1.选择一个编译环境

现在Windows系统的主流编译环境有Visual C++,C++Builder,Dev-C++等,它们都支持OpenGL。这里选择Visual C++作为学习OpenGL的实验环境。

2.安装OpenGL工具包

1)将OpenGL工具包dll文件夹中的*.dll文件放到操作系统目录下面的system32文件夹(其路径一般为:C:WindowsSystem32)。

2)打开VC,在VC中选择Tools→Options→Directories,然后在Show directories for中选择Include files,在下面添加OpenGL工具包中Include文件夹的路径,如下图所示:

数字图像处理实验指导书

3)类似地,在Show directories for中选择library files,在下面添加OpenGL工具包中lib文件夹的路径,然后按OK。如下图所示:

3.建立一个OpenGL工程

打开VC后,在VC中选择File→New→Project,然后选择Win32 Console Application, 选择一个名字,然后按“OK”。在弹出的对话框中点An empty project,选择Finish。然后向该工程添加一个源文件,选择一个名字。

三、实验报告要求

(1)有实验报告封面

(2)给出简要的设计思路(原理)。(3)给出实现代码。

(4)给出实验结果的屏幕截图。(5)实验的心得体会或建议。

数字图像处理实验指导书

实验一VC++6.0+OpenGL绘图环境及基本图形学算法

实验项目性质:验证性实验 所属课程名称:3D游戏图形学 实验计划学时:3学时

一. 实验目的

1、熟悉OpenGL的主要功能;

2、掌握OpenGL的绘图流程和原理;

3、掌握OpenGL核心函数的使用;

4、理解基本图形元素光栅的基本原理;

5、掌握直线和圆的多种生成算法。

二. 实验内容

1、创建一个OpenGL工程,利用OpenGL库函数进行简单图形设计与绘制;

2、编程实现DDA算法和Bresenham算法生成直线;

3、编程实现中点算法生成圆。

三. 实验原理

1、基本语法(C版本下的OpenGL语法)

OpenGL基本函数均使用gl作为函数名的前缀,如glClearColor();实用函数则使用glu作为函数名的前缀,如gluSphere()。OpenGL基本常量的名字以GL_开头,如GL_LINE_LOOP;实用常量的名字以GLU_开头,如GLU_FILL。一些函数如glColor*()(定义颜色值),函数名后可以接不同的后缀以支持不同的数据类型和格式,如glColor3b()、glColor3d()、glColor3f()和glColor3bv()等,这几个函数在功能上是相似的,只是适用于不同的数据类型和格式,其中3表示该函数带有三个参数,b、d、f分别表示参数的类型是字节型、双精度浮点型和单精度浮点型,v则表示这些参数是以向量形式出现的。

OpenGL定义了一些特殊标识符,如GLfloat、GLvoid,它们其实就是C中的float和void。

2、程序的基本结构

OpenGL程序的基本结构可分为三个部分: 第一部分是初始化,主要是设置一些OpenGL的状态开关,如颜色模式(RGBA或ALPHA)的选择,是否作光照处理(若有的话,还需设置光源的特性),深度检验、裁剪等。这些状态一般都用函数glEnable(„)、glDisable(„)来设置,数字图像处理实验指导书

“„”表示特定的状态。

第二部分设置观察坐标系下的取景模式和取景框位置大小,主要利用了三个函数:

函数void glViewport(left, top, right, bottom)设置在屏幕上的窗口大小,四个参数描述屏幕窗口四个角上的坐标(以像素表示);

函数void glOrtho(left, right, bottom, top, near, far)设置投影方式为正交投影(平行投影),其取景体积是一个各面均为矩形的六面体;

函数void gluPerspective(fovy, aspect, zNear, zFar)设置投影方式为透视投影,其取景体积是一个截头锥体。

第三部分是OpenGL的主要部分,是使用OpenGL的库函数构造几何物体对象的数学描述,包括点线面的位置和拓扑关系、几何变换、光照处理等。

3、OpenGL状态机制

OpenGL的工作方式是一种状态机制,它可以进行各种状态或模式设置,这些状态或模式在重新改变它们之前一直有效。例如,当前颜色就是一个状态变量,在这个状态改变之前,绘制的每个像素都将使用该颜色,直到当前颜色被设置为其他颜色为止。OpenGL中大量地使用了这种状态机制,如颜色模式、投影模式、单双显示缓存区的设置、背景色的设置、光源的位置和特性等。许多状态变量可以通过glEnabel()、glDisable()这两个函数来设置成有效或无效状态,如是否设置光照、是否进行深度测试等;在被设置成有效状态之后,绝大部分状态变量都有一个缺省值。

四. 实验代码

1、如预备知识所述,安装OpenGL工具包,创建一个OpenGL工程,在源文件上输入如下代码: #include #include //初始化OpenGL场景 void myinit(void){ glClearColor(0.0, 0.0, 0.0, 0.0);glMatrixMode(GL_PROJECTION);gluOrtho2D(0.0,200.0,0.0,150.0);glShadeModel(GL_FLAT);//设置明暗处理 } //用户的绘图过程 void display(void)

//将背景置成黑色

数字图像处理实验指导书

{ glClear(GL_COLOR_BUFFER_BIT);//清除缓存

glBegin(GL_LINES);

//开始画一根白线

glColor3f(1.0f, 1.0f, 1.0f);//设置颜色为白色

//设置第一根线的两个端点,请注意:OpenGL坐标系的原点是在屏幕左下角 glVertex2f(10.0f, 50.0f);glVertex2f(110.0f, 50.0f);glColor3f(1.0f, 0.0f, 0.0f);//设置颜色为红色 //设置第二根线的两个端点 glVertex2f(110.0f, 50.0f);glVertex2f(110.0f, 150.0f);glEnd();//画线结束

glFlush();//绘图结束 } // //主过程:

// 初始化Windows的窗口界面 // 并初始化OpenGL场景,绘图 int main(int argc, char** argv){ glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);//初始化窗口的显示模式 glutInitWindowSize(400,300);//设置窗口的尺寸 glutInitWindowPosition(100,120);//设置窗口的位置 glutCreatWindow(“”); //创建一个名为“”的窗口 glutDisplayFunc(Display);//设置当前窗口的显示回调函数 myinit(); //完成窗口初始化

glutMainLoop();//启动主GLUT事件处理循环

数字图像处理实验指导书

return(0);}

glaux.lib glu32.lib glut32.lib opengl32.lib

注:glShadeModel选择平坦或光滑渐变模式。GL_SMOOTH为缺省值,为光滑渐变模式,GL_FLAT为平坦渐变模式。

该程序是在一个黑色的窗口中画两条线,分别用白色和红色绘制。首先,需要包含头文件#include ,这是GLUT的头文件。本来OpenGL程序一般还要包含,但GLUT的头文件中已经自动将这两个文件包含了,不必再次包含。然后是main函数,其使用GLUT库实现窗口管理。我们关注的是display()函数,它是我们真正绘图的地方。

函数glColor3f()以RGB方式设置颜色,格式为:glColor3f(red,green,blue),每种颜色值在(0.0, 1.0)之间。函数glVertex2f(x, y)设置二维顶点。函数glBegin(UINT State)、glEnd()是最基本的作图函数,下面对它作一介绍。

如上所述,OpenGL是一个状态机,glBegin(UINT State)可以设定如下状态: GL_POINTS GL_LINES

画点

画线,每两个顶点(Vertex)为一组

画线,把若干个顶点顺次连成封闭折线 画三角形,每三个顶点为一组 画多边形 GL_LINE_STRIP 画线,把若干个顶点顺次连成折线 GL_LINE_LOOP GL_TRIANGLES GL_QUADS GL_POLYGON 画四边形,每四个顶点为一组

还有GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS_STRIP 等等。大家把每一种状态都试一试。另外,程序可以有多组glBegin()、glEnd()并列的形式,如:

......数字图像处理实验指导书

glBegin(GL_LINES);

glBegin(GL_QUADS);......glEnd();......除了上述的基本图元外,函数glRectf(x1, y1, x2, y2)可以画一个矩形,但这个函数不能放在glBegin()和glEnd()之间,下面的两句程序是画一个蓝色的矩形。

glColor3f(0.0f, 0.0f, 1.0f);glRectf(10.0f, 10.0f, 50.0f,50.0f);......glEnd();要求:利用OpenGL库函数绘制基本图形,输出绘制结果。

数字图像处理实验指导书

void display(void){

} glColor3f(0.0f, 0.0f, 1.0f);glRectf(10.0f, 10.0f, 50.0f, 50.0f);//画线结束 glFlush();//绘图结束 glClear(GL_COLOR_BUFFER_BIT);//清除缓存

glBegin(GL_LINES);

//开始画一根白线

glColor3f(1.0f, 1.0f, 1.0f);//设置颜色为白色

//设置第一根线的两个端点,请注意:OpenGL坐标系的原点是在屏幕左下角 glVertex2f(10.0f, 50.0f);glVertex2f(110.0f, 50.0f);glColor3f(1.0f, 0.0f, 0.0f);//设置颜色为红色 //设置第二根线的两个端点 glVertex2f(110.0f, 50.0f);glVertex2f(110.0f, 150.0f);glEnd();

2、创建一个新的OpenGL工程,在源文件上输入如下代码: //DDA算法

# include

数字图像处理实验指导书

void LineDDA(int x0, int y0, int x1, int y1){

}

void myDisplay(void){

glPointSize(5);glBegin(GL_POINTS);glColor3f(0.0f,1.0f,0.0f);glVertex2f(0.0f,0.0f);int x, dy, dx, y;float m;dx=x1-x0;dy=y1-y0;m=dy/dx;y=y0;glColor3f(1.0f, 1.0f, 0.0f);glPointSize(1);for(x=x0;x<=x1;x++){

} glBegin(GL_POINTS);glVertex2i(x,(int)(y+0.5));glEnd();y+=m;glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0f,0.0f,0.0f);glRectf(25.0,25.0,75.0,75.0);

数字图像处理实验指导书

} glEnd();LineDDA(0,0,200,300);glBegin(GL_LINES);glColor3f(1.0f,0.0f,0.0f);glVertex2f(100.0f,0.0f);glColor3f(0.0f,1.0f,0.0f);glVertex2f(180.0f,240.0f);glEnd();glFlush();void Init(){

}

void Reshape(int w, int h){

}

int main(int argc, char * argv[])glClearColor(0.0,0.0,0.0,0.0);glShadeModel(GL_FLAT);glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);

数字图像处理实验指导书

{

} 介绍一下glutReshapeFunc()函数:

首次打开窗口、移动窗口和改变窗口大小时,窗口系统都将发送一个事件,以通知程序员。如果使用的是GLUT,通知将自动完成,并调用向glutReshapeFunc()注册的函数。该函数必须完成下列工作:

a. 重新建立用作新渲染画布的矩形区域; b. 定义绘制物体时使用的坐标系。如:

void Reshape(int w, int h){ glViewport(0, 0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0,(GLdouble)w, 0.0,(GLdouble)h);

} 在GLUT内部,将给该函数传递两个参数:窗口被移动或修改大小后的宽度和高度,单位为像素。glViewport()调整像素矩形,用于绘制整个窗口。接下来三个函数调整绘图坐标系,使左下角位置为(0,0),右上角为(w,h)。glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);glutInitWindowPosition(100,100);glutInitWindowSize(400,400);glutCreateWindow(“Hello World!”);Init();glutDisplayFunc(myDisplay);glutReshapeFunc(Reshape);glutMainLoop();return 0;要求:

1)根据所给的直线光栅化的示范源程序,在计算机上编译运行,输出正确结果(示范代码有错误,指出并改正);

数字图像处理实验指导书

示范代码展示:

void LineDDA(intx0, inty0, intx1, inty1){

} float x, dy, dx, y;float m;dx = x1y0;m = dy / dx;y = y0;glColor3f(1.0f, 1.0f, 0.0f);glPointSize(1);for(x = x0;x <= x1;x++){

} glBegin(GL_POINTS);glVertex2i(x,(int)(y + 0.5));glEnd();y += m;

数字图像处理实验指导书

2)根据示范程序采用的算法,以此为基础将其改造为Bresenham算法,写入实验报告;

void Bresenhamline(intx0, inty0, intx1, inty1, intcolor){

int x, y, dx, dy;float k, e;dx = x1y0, k = dy / dx;e =-0.5, x = x0, y = y0;for(int i= 0;i <= dx;i++){

glPointSize(2.0f);glBegin(GL_POINTS);glColor3f(1.0f, 1.0f, 1.0f);glVertex2f(x, y);glEnd();

数字图像处理实验指导书

} } x = x + 1,e = e + k;if(e >= 0){ } y++, e = e4 * radius;float deltaE = 12;float deltaSE = 20-8 * radius;

glPointSize(3);glBegin(GL_POINT);glColor3f(0.0, 1.0, 0.0);glVertex2i(x, y);glEnd();while(y>x){

if(d <= 0){ d += deltaE;

数字图像处理实验指导书

deltaSE += 8;

}

else

{

d += deltaSE;

deltaSE += 16;

y--;

}

deltaE += 8;

x++;

glBegin(GL_POINTS);

glVertex2i(x, y);

glVertex2i(x,-y);

glVertex2i(-x, y);

glVertex2i(-x,-y);

glVertex2i(y, x);

glVertex2i(y,-x);

glVertex2i(-y, x);

glVertex2i(-y,-x);

glEnd();}

《计算机图形学》实验报告 第8篇

计算机图形学是计算机科学研究领域中的一门重要学科, 同时也是建立在传统图学理论、应用数学及计算机科学基础上的一门交叉学科[1]。它利用计算机处理图形信息, 主要包括图形信息的表示、输入输出与显示、图形的几何变换及人机交互绘图等方面的技术[2]。在过去的几十年里, 图形学不仅在理论研究方面取得较大的进步, 在实际应用领域如计算机辅助设计与制造、计算机动画艺术、虚拟现实等方面均得到了广泛的应用与推广。基于计算机图形学领域内出现的巨大变化及本校数字媒体技术专业人才培养目标的确立, 有必要对目前的计算机图形学实验教学过程进行进一步改革, 从而提升这门课程的实验教学水平。

1 实验教学现状

由于计算机图形学是一门建立在多门学科之上的综合性交叉学科, 它所涉及到的算法基本以数学为基础, 其中部分算法为了追求高效的运算速度及优化的存储空间, 在教材中的描述与实现也相对较为复杂。考虑到这些因素, 教师们通常会避开讲解过多依赖数学基础的算法或者描述及实现起来较为复杂的算法, 仅仅从对一些简单算法进行编程实现的角度来组织实验教学, 这样做势必会影响到最终的实践教学效果。

同时, 在设计实验课程的环节中, 很多教师并没有充分考虑到实验项目的应用背景。他们只要求学生对一些自己认为重要的算法进行简单的编程实现, 这样做使得原本很重要的实验环节变成了理论学习的辅部助分, 学生很难将所掌握的基本理论知识与相关应用领域建立起联系, 更谈不上灵活应用与创新。

2 实验教学方法改进

由于计算机图形学是一门实践性、应用性较强的学科, 所以在日常的教学过程中需要不断强化实验环节[3], 要求学生把所学的基础理论知识应用到操作实践中, 并在操作实践过程中不断地发现、分析和解决新问题[4]。为了实现上述目标, 教师在教学过程中必须要结合图形学理论教学过程, 努力改进教学方法。

2.1 上好第一堂实验课

在本学科的第一次实验课堂上用1课时的时间适当引入虚拟现实技术、计算机三维动画等较前沿的应用领域。以《冰河世纪》、《阿凡达》等经典3D影片为例, 向学生展示计算机图形学应用成果, 并简单介绍实现这些成果所用到的图形软件及实现这些软件所涉及到的图形学技术 (如三维建模、材质、渲染等) , 最后向学生详细介绍本学科的实验课程设置。这一举措将有助于激发学生浓厚的学习兴趣, 同时也将克服长久以来植根于学生心中“图形学学而无用”的心理障碍。

2.2 算法讲解与算法演示相结合

为了让艰涩难懂的算法讲解变得生动并易于理解, 可以将算法原理通过Flash软件制作成动画演示给学生看[5], 如图1所示为使用Flash制作的直线剪裁算法演示动画。但是由于Flash编程能力有限, 仅能呈现简单算法的演示效果, 对于一些复杂的算法 (如真实感图形显示) , 则可以采用微软图形库OpenGL并结合VC++6.0进行演示[6], 在演示的过程中还可以灵活修改参数观察不同的实验结果。如图2所示为使用OpenGL制作的具备真实感图形效果的茶壶模型。实践证明, 以上所采用的讲授方式直观并易于理解, 可以充分激发学生的实验兴趣。

2.3“编程实践”、“图形软件应用”和“理论学习”三结合

计算机图形学的学习目标是要求学生掌握及应用本课程相关算法解决实际问题。基于这一目标, 教师可以采用“编程实践”、“图形软件应用”和“理论学习”三结合的方法组织实验教学内容。譬如, 在讲解“光照处理”这一理论知识点之前, 首先在实验课堂上给学生演示如何在图形软件3D Max中制作光源, 让学生通过修改参数观察光照效果, 在此过程中, 学生会产生诸如“各参数具备何含义”、“不同参数的设置具备何作用”等疑问。接着, 教师让学生使用微软图形库OpenGL结合VC++6.0编程实现预定的光照效果, 再提出相同的疑问。带着这些疑问, 教师在课堂上为学生讲解图形学中“光照处理”这一理论知识点, 引导学生回到光照模型的理论学习阶段。教学实践证明, 通过上述方法及实验过程, 学生可以将理论和实践很好地融合到一起, 真正解决了长久以来存在于他们心中诸如“学这个知识有什用”、“参数到底表示什么”、“为什么要那样设置”等疑问, 从而进一步明确了学生的学习目标, 极大地提高了其学习兴趣及学习效率。

2.4 教学与科研相结合

科研是提高课程教学质量的源动力, 高校教师可以将本课程相关的科研成果引入课堂, 这样既丰富了教学内容, 也提高了学生的学习兴趣。教师在课外可以将学生组织起来, 成立科技创新小组, 通过阅读文献、参与科研讲座等方式将其逐步引入到科研创新过程中来[7]。作者曾指导一个本科生科技创新小组, 主要工作是实现基于二维灰度图像的形体三维重建, 这一部分内容源于图形学课程中的“从二维图像信息构造三维形体”, 通过一学期的努力, 学生们利用所掌握的图形学知识, 设计算法并编程实现了如图3所示的“基于旋转轴的形体三维重建”。目前, 该科技小组的成员已经进入毕业设计阶段, 在本阶段他们将会继续探索“如何基于形体的轮廓线实现三维重建”。显而易见, 通过采用如上所述的教学与科研相结合的方法, 真正地实现了教师“教学与引导”、学生“学习与创新”的双重结合。

2.5 注重实验教学过程考核

在计算机图形学的教学过程中应当注重课程的考核管理, 它是保证教学质量的重要手段。教师可以将考核过程分为两个阶段:平时阶段和期末阶段。期末阶段可以沿用传统“笔试成绩+平时成绩”的模式, 而平时阶段的考核力度需要进一步加大。在教学改革的过程中, 将实验课堂的上机考核作为主要的平时成绩记入学习过程, 每次实验都给出等级, 并按比例记入到课程的总成绩中。借助于上机考核这一手段, 充分调动起学生动手实践的积极性, 提升学生在实践过程中独立思考、独立解决问题的能力。通过对不同教学实践过程的考核成果进行对比分析, 发现以上考核方法的实施的确起到了显著的效果。

3 实验教学内容设置

实验内容的合理设置在教学过程中是一个非常重要的环节, 每一个实验项目的设置都应当与实际应用背景相联系, 让学生感觉到“所学即所用”, 这样会极大提高学生的学习积极性。

3.1 实验环境设置

传统的实验过程采用Visual C++6.0作为开发环境, 在这种环境下, 只能进行一些简单的图形算法编程 (如二维图形生成、区域填充、图形变换等) 。针对以上情况, 在图形学实验中引入了OpenGL, 所有的实验项目都要求在安装了GLUT的Visual C++6.0环境下进行。OpenGL是独立于操作系统和硬件环境的三维图形软件库, 其所具备的功能基本上涵盖了计算机图形学所要包括的各方面内容。利用OpenGL开展图形学实验, 有益于提高学生在计算机图形学方面的程序开发能力[8,9]。

3.2 实验环节设置

本课程的实践过程主要包含如下3个环节:基础算法的OpenGL实现、OpenGL提高实验、图形学软件产品体验。

(1) 基础算法的OpenGL实现环节。采用OpenGL结合Visual C++6.0实现图形的绘制、变换及真实感显示等基本功能, 这一过程的设置使学生从繁琐的算法编程中摆脱出来, 让其更多地接触实际开发所使用的工具与开发环境。

(2) OpenGL提高实验环节。通过调用及组织OpenGL库函数来完成某一具体案例 (如三维场景中人物模型的真实感显示) , 使学生直接面向图形学的实际应用过程。

(3) 图形学软件产品体验环节。以图形学软件产品3D Max作为建模工具, 结合OpenGL和图像处理软件Photoshop, 根据可选课题设计相关应用案例。通过对3D Max的使用, 让学生感受到计算机图形学的实际应用背景, 分析图形学在诸如此类软件产品中的具体应用。

3.3 实验项目设置

根据上述实验过程的设置, 将实验项目安排如表1所示。其中, 验证性实验属于基础算法的OpenGL实现环节;综合性实验是对学生实验技能和方法进行综合训练的一种复合型实验, 属于OpenGL提高实验环节;而设计性实验属于图形学软件产品体验环节, 要求学生自主选题、设计实验方案, 充分利用所学知识结合图形学软件产品完成案例的制作。

4 结语

基于本校数字媒体技术专业计算机图形学实验教学实际情况, 立足于“应用型人才培养”模式, 对实验教学方法及内容设置进行了改革。同时, 对实验的环境、内容及实验项目重新作出设置与安排。实践表明, 本文提出的方法对加深课程理解、培养学生兴趣和提高教学质量有显著的效果。

参考文献

[1]李春雨.计算机图形学理论与实践[M].北京:北京航空航天大学出版社, 2004.

[2]倪明田, 吴良芝.计算机图形学[M].北京:北京大学出版社, 1999.

[3]刘晋钢, 孔令德, 王进忠.“计算机图形学”课程新教学模式的研究与实践[J].计算机教育, 2010 (3) :63-65.

[4]何援军.论计算机图形学的若干问题[J].上海交通大学学报, 2008 (4) :514-517.

[5]伍军云, 徐少平, 占传杰.基于OpenGL的计算机图形学辅助教学课件[J].计算机与现代化, 2007 (9) :114-119.

[6]费广正, 乔林.Visual C++6.0高级编程技术——OpenGL篇[M].北京:中国铁道出版社, 2000.

[7]黄琼.在计算机应用类课程中开展研究性学习的探索[J].南宁职业技术学院学报, 2005 (1) :42-44.

[8]杜利峰, 李竹林.基于OpenGL的计算机图形学教学改革探索[J].电子设计工程, 2012 (13) :6-8.

相关文章
c实验报告总结

c实验报告总结

c实验报告总结(精选8篇)c实验报告总结 第1篇c语言实验报告分析总结在这个星期里,我们专业的学生在专业老师的带领下进行了c语言程序实践...

1
2025-10-11
财务管理模拟实验报告

财务管理模拟实验报告

财务管理模拟实验报告(精选8篇)财务管理模拟实验报告 第1篇财务管理模拟实验报告12级注会一班13组 学号:30 姓名:唐敏一、实验过程财...

1
2025-10-11
哈工大电路实验报告范文

哈工大电路实验报告范文

哈工大电路实验报告范文第1篇一、 实验目的1、掌握用门电路设计组合逻辑电路的方法。2、掌握组合逻辑电路的调试方法。二、 实验器材数字...

1
2025-10-11
fpga流水灯实验报告

fpga流水灯实验报告

fpga流水灯实验报告(精选5篇)fpga流水灯实验报告 第1篇单片机流水灯实验一、任务让8个LED灯轮流亮起来,实现流水灯的功能。二、思路让接...

1
2025-10-11
eda的实验报告

eda的实验报告

eda的实验报告(精选6篇)eda的实验报告 第1篇实验一:QUARTUS II 软件使用及组合电路设计仿真实验目的:学习QUARTUS II 软件的使用,...

1
2025-10-11
erp实验助理实验报告

erp实验助理实验报告

erp实验助理实验报告(精选10篇)erp实验助理实验报告 第1篇冠军,痛并快乐着工商1112班201111551207洪晓茵摘要:五天的erp培训,让我们这...

1
2025-10-11
第三方物流实验报告

第三方物流实验报告

第三方物流实验报告(精选6篇)第三方物流实验报告 第1篇实验实训中心 实验报告实验名称第三方物流企业网上调查班级 学号 姓名 同...

1
2025-10-11
第五周化学实验报告

第五周化学实验报告

第五周化学实验报告(精选14篇)第五周化学实验报告 第1篇课题组周汇报一、本周计划1、文献阅读:《海藻多糖的结构、提取和生物活性研究新...

1
2025-10-10
付费阅读
确认删除?