第一篇:《计算机图形学》实验报告
吉林大学
计算机科学与技术学院
《计算机图形学》实验报告
班级: 211923班
学号: 21190928
姓名: 林星宇
2022-2022学年第1学期
实验项目1
边标志算法的实现
实验性质
□演示性实验 验证性实验
□操作性实验 综合性实验
实验地点
计算机楼B212
机器编号
一、实现的功能
编写应用程序,采用鼠标输入顶点的方法确定待填充多边形(多边形最后一点双击);实现边标志算法完成对该多边形的填充,要求 完成使用自己学号的后四位数字对多边形内部进行填充。
二、采用的图形学算法及实现
(算法的实现函数是什么(函数名,参数,返回值,函数功能等)以及采用了哪些数据结构(数组,链表等))
要求使用边标志算法的原理和实 现方法,所以使用了EdgeMarkFill函数,即边标志算法:
void CMFCDrawTestView::EdgeMarkFill(CDC* pDC, CArray
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));
}
第二篇:计算机图形学实验报告
实 验 报 告
一、实验目的
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.y
/*创建边表的主体函数*/ 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]陈传波,陆枫主编,《计算机图形学基础》,电子工业出版社,2022年3月. 0908141020 试验092 尤洋 实验1-1: 通过循环画线,实现了画四边形的功能 实验1-2: 通过循环设置顶点坐标,循环画线,实现了画7个顶点的金刚石 实验1-3: 通过填充实现了画三彩多边形 实验2-1: 实现了画各种范围不同斜率的直线 实验3-1: 通过Cohen-Sutherland算法和清屏重画实现了金刚石的区域裁剪 实验4-1: 通过不断地清屏重画实现了北极星的平移、比例、旋转、对称 实验5-1: 通过矩阵变换实现了三维图形的三视图、正轴测投影 计算机图形学实验报告 0900213 38 8 郭佩佩 实验一 建立计图实验环境 1. 实验目的 为了体现面向对象的程序设计思想,本实验采用基于 Visual C 十十集成环境的 MFC 编程方法,从开发 windows 应用程序的角度,来建立一个菜单交互式绘图基本环境,为后续的实验打基础。 2. 实验内容 1) 建立菜单交互式绘图基本环境的工程文件 Vcad,运行后如图: 2)在绘图菜单的下拉子菜单下有如下菜单项: 直线 ----用弹性线方法输入直线的起止点后,调用 bresenham 算法替换原来 的 moveto/lineto 算法画直线 圆/圆弧 ----在该菜单选择后,可分别画圆或圆弧。 直线段裁剪----输入矩形域左上角及右下角后,产生裁剪区域;然后可输入若干条直线段,矩形域作为主裁剪域对其裁剪之。 面区填充 ----输入多边形的若干顶点后,调用面区填充算法对多边形域的内部填充 之。 贝塞尔曲线----输入四顶点后,调用三次贝塞尔曲线生成算法生成贝塞尔曲线。 实验二 园和园弧的绘制算法 1.实验目的 通过园和椭圆弧生成算法的上机调试,掌握: 1) VC 图形函数的使用方法; 2) 圆和椭圆弧的生成原理。 2.实验内容 1)以函数形式编写圆的生成算法,然后在 VCAD 绘图小系统中的绘图----圆子菜单下找到合适的程序修改点,将本实验要求你编写的画圆算法插入工程文件中,通过调试来验证你编写的画圆算法的正确性。 2) 以函数形式编写角度 DDA 椭圆弧生成算法,然后在 VCAD 绘图小系统中的绘图----圆弧子菜单下找到合适的程序修改点,将本实验要求你编写的画圆弧算法插入工程文件中,通过调试来验证你编写的画圆弧算法的正确性。 Arc(int xc,int yc,doubli r,double ts,double te){ double rad,ts1,tel,deg,dte,ta,ct,st; int x,y,n,I; rad=0.0174533; tsl=ts*rad; tel=te*rad; if(r<5.08) deg=0.015; else if(r<7.62) deg=0.06; else if(r<25.4) deg=0.075; else deg=0.15; dte=deg*25.4/r; if(tel tel =6.28319; n=(int)((tel-tsl)/dte 0.5);if(n==0) n=(int)(6.28319/dte 0.5); ta=tsl; x=xc r*cos(tsl); y=yc r*sin(tsl); moveto(x,y); for(i=1;i<=n;i ) { ta =dte;ct=cos(ta);st=sin(ta);x=xc r*ct;y=yc r*st;lineto(x,y);} x=xc r*cos(tel); y=yc r*sin(tel); lineto(x,y); return(0);} 实验三 直线的裁剪(编码裁剪算法) 1. 实验目的 通过编码裁剪算法的设计与调试,了解二维线段的裁剪过程,提高程序设计能力与上机调试能力,达到理论与实践有机结合之目的。注:此实验已有可运行的中点裁剪算法作为参考实例,做实验时,可将中点裁剪算法替换为你编写的编码裁剪算法。 2. 实验内容 1) 以函数形式编写编码裁剪算法及相关子算法; Var xl,xr,yb,yt:real;…… procedure clip(x1,y1,x2,y2:real);label:return;type edge=(L,R,B,T); outcode=set of edge;Var c,c1,c2:outcode;x,y:real;Procedure code(x,y:real;Var c:outcode); Begin c:=[ ]; If x Else if x>xr then c:=[R]; If y Else if y>yt then c:=c [T]; End {end of code} Begin {main} Code(x1,y1,c1);code(x2,y2,c2);While(c1<>[])or(c2<>[])do Begin if c1*c2<>[] then return;{显然不可见} c:=c1;if c=[] then c:=c2; If L in c then begin x:=xl;y:=…end;{对左边界求交} If R in c then begin x:=xr;y:=…end;{对右边界求交} If B in c then begin x:=…;y:=yb end;{对底边界求交} If T in c then begin x:=…;y:=yt end;{对顶边界求交} If c=c1 then begin x1:=x;y1:=y; code(x,y,c1)end Else begig x2:=x,y2:=y; code(x,y,c2)end End;{End of while} Line(x1,y1,x2,y2); Return: end;{end of clip} 2) 交互产生矩形裁剪框,并输入不同斜率的直线段的始、终点,先画出此直线段,然后调用裁剪算法,画出裁剪后保留的可见线段部分。 3) 在 VCAD 绘图小系统中的绘图----直线裁剪子菜单下找到合适的修改点,将本实验要求你编写的编码裁剪算法替换掉工程文件中的中点裁剪算法,通过调试来验证你编写的编码裁剪算法的正确性。 实验四 面区填充(Y-X 算法) 1. 实验目的 通过 Y-X 面区填充算法的调试,掌握: 1) 多边形面区填充算法的数据组织; 2) 利用相关性提高算法效率; 3) 奇异点的处理方法; 4) 提高程序设计能力。 2. 实验内容 1) 以函数形式编写 Y-X 面区填充算法; 2) 在 VCAD 绘图小系统中的绘图----面区填充子菜单下找到合适的修改点,将本实验要求你编写的面区填充算法插入工程文件中,通过调试来验证你编写的面区填充算法的正确性。操作时,用鼠标交互给出多边形的若干顶点,画出此多边形,然后调用你编写的 Y-X 面区填充算法填充,以自选的颜色填充多边形。 实验五 贝塞尔曲线生成算法的设计与调试 一、实验目的 在掌握曲线、曲面数学理论的基础上,通过调试,绘制 Bezier 曲线。加深同学 对数学理论的理解。通过二条 Bezier 曲线的拼接设计,掌握自由曲线的拟合方法。 二、内容和要求 1、由三次 Bezier 曲线的公式:P(t)=∑P i B i,3(t) 出发,编写生成 Bezier i=0 曲线的程序,要求如下: a) 用鼠标输入特征多边形的四点。然后调用 Bezier 曲线生成算法绘出曲线。 b) 重复上步 3—4 遍,验证你编写的算法的正确性。 typedef cptype float[4][4];float cc(int n,int i)//计算 n!/(i!(n-i)!) {int j; float a; a=1; for(j=i 1;j<=n;j )a*=j; for(j=2;j<=n-i;j )a/=j; return a; } float b_lend(Int i,int n,float t2)//计算 B i,n(t) {float v; v=cc(n,i);for(j= 1;j<=i;j )v*=t2; for(j=1;j<=n-i;j )v*=(1-t2); return v; } void bezier(float x0,float y0,float z0,float t0,int n,cptype cp2)//给定 t0,计算 f(t0){int i; float b1,g; for(i=0;i<=n;i ){b1=b_lend(i,n,t0); x0=x0 cp2[i,1]*b1;y0=y0 cp2[i,2]*b1;z0=z0 cp2[i,3]*b1;}} void draw_curv(int k,cptype cp1)//将 t 分成 k 等份,循环迭代,绘出曲线。 {int i,j,x1,y1,z1; float x,y,z,delt; delt=1.0/k; t=0; for(i=1;i<=k;i ) {x=y=z=0; bezier(x,y,z,t,3,cp1); if(t==0)moveto(x,y); else lineto(x,y); t =delt;}} 2、将特征多边形改为五个控制点,修改程序后绘出四次曲线。 3、实现二条三次 Bezier 的拼接,并使连接点处保持一阶连续。 实验小结: 实验的过程是辛苦的,特别是处理大量的数据,大量的临时变量,很容易出错,需要极大的耐心。一些计算时,例如DDA 算法画圆时,需要强制类型转换一些数据,因为遗漏导致程序出了许多奇怪的错误,调试很久才发现。另外,贝塞尔曲线的算法编写中,一些数学函数的调用也很复杂,因为不常用,所以经常翻阅 API 文档。 最困难的是因为对该图形系统的不熟悉,导致处理鼠标操作时遇到一些难题,仔细比对才得以解决。 通过本次实验,对整个图形系统有了比较透彻的了解,同时对一些数学函数的使用再次加深了印象,更重要的是掌握了许多实用的计算机图形学的算法,对 MFC 的使用有了很大提升。 这次实验中积累的经验在今后的软件开发中将使我受益匪浅。 2022 年 1 月 3 日 工欲善其事,必先利其器 ——浅析计算机图形学及其作用 本学期学校开设了计算机图形学,一开始不知计算机图形学为何物的我不是很理解为什么要有这门课,但是经过一学期的洗礼过后,我对计算机图形学有了一定的理解。我知道了计算机图形学(Computer Graphics,简称CG)是一种使用数学算法将二维或三维图形转化为计算机显示器的栅格形式的科学。简单地说,计算机图形学的主要研究内容就是研究如何在计算机中表示图形、以及利用计算机进行图形的计算、处理和显示的相关原理与算法。图形通常由点、线、面、体等几何元素和灰度、色彩、线型、线宽等非几何属性组成。从处理技术上来看,图形主要分为两类,一类是基于线条信息表示的,如工程图、等高线地图、曲面的线框图等,另一类是明暗图,也就是通常所说的真实感图形。计算机图形学一个主要的目的就是要利用计算机产生令人赏心悦目的真实感图形。对于我们将来从事景观设计的人来说,为了使自己的方案获得更多人的欣赏,必须创建图形所描述的场景的几何表示,再用某种光照模型,计算在假想的光源、纹理、材质属性下的光照明效果。所以计算机图形学与另一门学科计算机辅助几何设计有着密切的关系。事实上,图形学也把可以表示几何场景的曲线曲面造型技术和实体造型技术作为其主要的研究内容。同时,真实感图形计算的结果是以数字图象的方式提供的,计算机图形学也就和图像处理有着密切的关系。 谈到图形和图像时,现如今图形与图像两个概念间的区别越来越模糊,但还是有区别的:图像纯指计算机内以位图形式存在的灰度信息,而图形含有几何属性,或者说更强调场景的几何表示,是由场景的几何模型和景物的物理属性共同组成的。 计算机图形学的研究内容非常广泛,如图形硬件、图形标准、图形交互技术、光栅图形生成算法、曲线曲面造型、实体造型、真实感图形计算与显示算法、非真实感绘制,以及科学计算可视化、计算机动画、自然景物仿真、虚拟现实等。 自1963年,伊凡·苏泽兰(Ivan Sutherland)在麻省理工学院发表了名为《画板》的博士论文,标志着计算机图形学的正式诞生起,至今已有四十多年的历史。此前的计算机主要是符号处理系统,自从有了计算机图形学,计算机可以部分地表现人的右脑功能了,所以计算机图形学的建立具有重要的意义。通过课堂上的学习以及网上的介绍,我发现近年来,计算机图形学在如下几方面有了长足的进展: 在智能CAD方面,就目前流行的大多数CAD软件来看,主要功能是支持产品的后续阶段一一工程图的绘制和输出,产品设计功能相对薄弱,利用AutoCAD 最常用的功能还是交互式绘图,如果要想进行产品设计,最基本的是要其中的AutoLisp语言编写程序,有时还要用其他高级语言协助编写,很不方便。而新一代的智能CAD 系统可以实现从概念设计到结构设计的全过程。 在计算机美术与设计方面,自1952年.美国的Ben·Larose用模拟计算机做了预示着电脑美术的开始得具有历史性意义的波型图《电子抽象画》开始,以微机和工作站为平台的个人计算机图形系统逐渐走向成熟,大批商业性美术设计软件如雨后春笋般纷纷面市; 以苹果公司的MAC 机和图形化系统软件为代表的桌面创意系统被广泛接受,CAD成为美术设计领域的重要组成部分。而计算机设计学包括三个方面:即环境设计(建筑、汽车)、视觉传达设计(包装)、产品设计。CAD对艺术的介入,分三个应用层次:(1)计算机图形作为系统设计手段的一种强化和替代; 效果是这个层次的核心(高精度、高速度、高存储)。(2)计算机图形作为新的表现形式和新的形象资源。 (3)计算机图形作为一种设计方法和观念。 同时,计算机图形学、计算机绘画、计算机音乐、计算机辅助设计、电影技术、电视技术、计算机软件和硬件技术等众多学科的最新成果都对计算机动画技术的研究和发展起着十分重要的推动作用。计算机动画的一个重要应用就是制作电影特技 可以说电影特技的发展和计算机动画的发展是相互促进的。比如广受欢迎的终结者系列中便大量运用了电脑特技,而在影片《阿凡达 》中几乎成为了电影特效的天下,电影特技的运用丰富了人们的视觉效果,是电影卖座的重要保证。我国的计算机动画技术起步较晚。1990年的第11届亚洲运动会上,首次采用了计算机三维动画技术来制作有关的电视节目片头。从那时起,计算机动画技术在国内影视制作方面得到了讯速的发展,继而以3D Studio 为代表的三维动画微机软什和以Photoshop等为代表的微机二维平面设计软件的普及,对我国计算机动画技术的应用起到了推波助谰的作用。计算机动画的应用领域十分宽广 除了用来制作影视作品外,在科学研究、视觉模拟、电子游戏、工业设计、教学训练、写真仿真、过程控制、平面绘画、建筑设计等许多方面都有重要应用。 科学计算的可视化是发达国家八十年代后期提出并发展起来的一门新兴技术,它将科学计算过程中及计算结果的数据转换为几何图形及图象信息在屏幕上显示出来并进行交互处理,成为发现和理解科学计算过程中各种现象的有力工具。它涉及到下列相互独立的几个领域:计算机图形学、图象处理、计算机视觉、计算机辅助设计及交互技术等。科学计算可视按其实现的功能来分,可以分为三个档次:(1)结果数据的后处理;(2)结果数据的实时跟踪处理及显示;(3)结果数据的实时显示及交互处理。 “虚拟现实”(Virtual Reality)一词是由美国喷气推动实验室(VPL)的创始人拉尼尔(Baron Lanier)首先提出的 在克鲁格(Algren Krueger)70年 代中早期实验里.被称为 人工现实”(Artificial reality);而在吉布森(William Gibson)l984 年出版的科幻小说Necromancer里,又被称为“可控空间”(Cyberspace)。虚拟现实是美国国家航空和航天局及军事部门为模拟而开发的一门高新技术 它利用计算机图形产生器,位置跟踪器,多功能传感器和控制器等有效地模拟实际场景和情形,从而能够使观察者产生一种真实的身临其境的感觉。虚拟环境由硬件和软件组成,硬件部分主要包括:传感器(Sensors)、印象器(Effecter)和连接侍感器与印象器产生模拟物理环境的特殊硬件。利用虚拟现实技术产生虚拟现实环境的软件需完成以下三个功能:建立作用器(Actors)以及物体的外形和动力学模型:建立物体之间以及周围环境之间接照牛顿运动定律所决定的相互作用;描述周围环境的内容特性。 在工程设计方面,计算机图形学的作用主要表现在(1)建筑设计,包括方案设计、三维造型、建筑渲染图设计、平面布景、建筑 构造设计、小区规划、日照分析、室内装潢等各类CAD应用软件。 (2)结构设计,包括有限元分析、结构平面设计、框/排架结构计算和分析、高层结构分析、地基及基础设计、钢结构设计与加工等。 (3)设备设计,包括水、电、暖各种设备及管道设计。 (4)城市规划、城市交通设计,如城市道路、高架、轻轨、地铁等市政工程设 计。 (5)市政管线设计,如自来水、污水排放、煤气、电力、暖气、通信(包括电 话、有线电视、数据通信等)各类市政管道线路设计。 (6)交通工程设计,如公路、桥梁、铁路、航空、机场、港口、码头等。 (7)水利工程设计,如大坝、水渠、河海工程等。 (8)其他工程设计和管理,如房地产开发及物业管理、工程概预算、施工过程 控制与管理、旅游景点设计与布置、智能大厦设计等。 那么如何学好计算机图形学呢? 除了计算机图形学的基础知识以外,我们还需要相关知识,懂得越多,才能学的越好。 英语,如果要学好计算机图形学的话,我认为需要阅读大量的英文书籍和资料,毕竟国外相关研究更加深入,好的英文功底有助于紧跟国际潮流。 数学,计算机图形学里面经常会遇到数学方面的知识,比如高等数学中的数值分析,微分几何,拓扑,差值概论以及微分方程等。 物理,如果要进行基于物理的建模,一些物理理论是要学习的。如力学,光学,有限元„„ 编程语言,C语言或C 是计算机图形学中通用的语言。 数据结构,当需要用数据结构来描述图形形象时,除了通用的链表、树等数据结构外,图形学还有自己特殊的数据结构。 所以说,一门学科可能会和许多学科发生穿插,不能希望只通过一本教科书就能学好一门学科,一定要在掌握教科书内容的基础上与其他学科融会贯通才能获得更大的收获。这就是我学习计算机图形学的心得,可能不够成熟,希望在以后的进一步学习中获得更多的经验,为自己未来的职业生涯打下坚实的基础。第三篇:计算机图形学实验报告
第四篇:计算机图形学实验报告(例文)
第五篇:计算机图形学论文