收藏 分享(赏)

有序边表算法.doc

上传人:pw17869 文档编号:4746256 上传时间:2019-01-10 格式:DOC 页数:7 大小:598.50KB
下载 相关 举报
有序边表算法.doc_第1页
第1页 / 共7页
有序边表算法.doc_第2页
第2页 / 共7页
有序边表算法.doc_第3页
第3页 / 共7页
有序边表算法.doc_第4页
第4页 / 共7页
有序边表算法.doc_第5页
第5页 / 共7页
点击查看更多>>
资源描述

1、实 验 报 告Experimentation Report of Taiyuan teachers College系 部 年 级 课 程 姓 名 同组者 日 期项 目 有序边表算法 1、实验目的:1、掌握有序边表算法填充多边形区域;2、理解多边形填充算法的意义;3、增强 C 语言编程能力。二、实验内容:根据多边形内部点的连续性知:一条扫描线与多边形的交点中,入点和出点之间所有点都是多边形的内部点。所以,对所有的扫描线填充入点到出点之间所有的点就可填充多边形。判断扫描线上的点是否在多边形之内,对于一条扫描线,多边形的扫描转换过程可以分为四个步骤:(1)求交:计算扫描线与多边形各边的交点;(2)排

2、序:把所有交点按 x 值递增顺序排序;(3)配对:第一个与第二个,第三个与第四个等等;每对交点代表扫描线与多边 形的一个相交区间;(4)着色:把相交区间内的象素置成多边形颜色,把相交区间外的象素置成背景色。报 告 内 容一、 实验目的 四、实验方法二、 实验原理 五、实验记录及数据处理三、 实验仪器及材料 六、误差分析及讨论太 原 师 范 学 院 实 验 报 告 续页如图所示 p1,p3,p4,p5 属于局部极值点,要把他们两次存入交点表中。 如扫描线 y=7 上的交点中,有交点(2,7,13),按常规方法填充不正确,而要把顶点(7,7)两次存入交点表中(2,7,7,13)。p2,p6 为非极

3、值点,则不用如上处理。为了提高效率,在处理一条扫描线时,仅对与它相交的多边形的边进行求交运算。把与当前扫描线相交的边称为活性边,并把它们按与扫描线交点 x 坐标递增的顺序存放在一个链表中,称此链表为活性边表(AET)。对每一条扫描线都建立一个与它相交的多边形的活性边表(AET) 。每个 AET 的一个节点代表一条活性边,它包含三项内容:1. x -当前扫描线与这条边交点的 x 坐标;2. x -该边与当前扫描线交点到下一条扫描线交点的 x 增量;3. ymax -该边最高顶点相交的扫描线号。每条扫描线的活性边表中的活性边节点按照各活性边与扫描线交点的 x 值递增排序连接在一起。当扫描线 y 移

4、动到下一条扫描线 y = y+1 时,活性边表需要更新,即删去不与新扫描线相交的多边形边,同时增加与新扫描线相交的多边形边,并根据增量法重新计算扫描线与各边的交点 x。当多边形新边表 ET 构成后,按下列步骤进行: 对每一条扫描线 i,初始化 ET 表的表头指针 ETi; 将 ymax = i 的边放入 ETi中; 使 y =多边形最低的扫描线号; 初始化活性边表 AET 为空; 循环,直到 AET 和 ET 为空。 将新边表 ET 中对应 y 值的新边节点插入到 AET 表。 遍历 AET 表,将两两配对的交点之间填充给定颜色值。 遍历 AET 表,将 ymax= y 的边节点从 AET 表

5、中删除,并将 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 值 *

6、/float dx; /*从当前扫描线到下一条扫描线之间的 x 增量*/struct tEdge *next; Edge;typedef struct pointint 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-xx) /*要插入的边的 x 较大不应该在当前插入*/p=NULL;else /*

7、要插入的边的 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 个顶点

8、 */j=0;elsej=k+1; /*当前顶点不是最后一个顶点,下一个顶点为数组下标加一*/while(ptsk.y=ptsj.y)/*扫描线扫过平行顶点,需分情况找到当前顶点下下个顶点*/if(j+1)(cnt-1)j=0;elsej+;return(ptsj.y); /*返回下一个顶点的 y 值 */太 原 师 范 学 院 实 验 报 告 续页/* 计算增量,修改 AET*/ /*生成边表结点,并插入到边表中的主体函数*/void MakeEdgeRec(POINT lower,POINT upper,int yComp,Edge *edge,Edge*edges)/*把边结点 edge

9、,放到 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 的最大值减一,向下移动*/elseedge-ymax=upper.y; /*不是奇点,不需改变 y 值 */insertEdge(edgeslower.y,edge); /*插入一个边缘扫描线,插入到列表 */ /*创建边表的主体函数*/void BuildEdgeList(i

10、nt cnt,POINT *pts,Edge *edges)/*建立新边表,cnt:多边形顶点个数+1,edges:指向活性边结点的指针数组*/Edge *edge;POINT v1,v2;int i,yPrev=ptscnt-2.y;/*当前顶点的前一个顶点的 y 值,在当前顶点不是奇点时使用该参数*/v1.x=ptscnt-1.x;v1.y=ptscnt-1.y;for(i=0;inext; /*查找当前扫描线对应的 y 桶*/while(p) /*y 桶不空*/q=p-next; /*找到最后一个边结点,插入*/InsertEdge(active,p); /*把更新后的边表重新插入边表中

11、保存*/p=q; /*填充一对交点的主体函数*/void FillScan(int scan,Edge *active,int color)/*填充扫描线:填充扫描线上,且在下一结点到再下一结点之间的点*/Edge *p1,*p2;int i;p1=active-next;while(p1)for(i=p1-x;ix;i+) putpixel(int)i,scan,color); /*画出图形内部的点*/ p1=p2-next; /*活性表的下一条边表 */ void DeleteAfter(Edge *q)/*删除链表中结点,删除边结点 q 的后续结点 p*/ Edge *p=q-next;

12、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

13、-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)/*填充函数

14、,输入:多边形顶点个数+1=cnt, 指向多边形顶点的指针数组 pts*/ Edge *edgesWINDOW_HEIGHT,*active;int i,scan,scanmax=0,scanmin=WINDOW_HEIGHT;for(i=0;iptsi.y)scanmin=ptsi.y;for(scan=scanmin;scannext=NULL;BuildEdgeList(cnt,pts,edges); /*建立有序边表 */ active=(Edge *)malloc(sizeof(Edge);active-next=NULL;for(scan=scanmin;scannext) /*活

15、性边表不为空*/ FillScan(scan,active,color); /*填充当前扫描线*/ UpdateActiveList(scan,active); /*更新活化边表*/ResortActiveList(active); /*重排活化边表*/ /*开始菜单*/void main()POINT pts7; /*保存数组*/ int gdrive=DETECT,gmode;pts0.x=100;pts0.y=40; /*多边形顶点 x、y 坐标*/ pts1.x=220;pts1.y=140;pts2.x=280;pts2.y=80;pts3.x=350;pts3.y=300;pts4.x=200;pts4.y=380;pts5.x=50;pts5.y=280;pts6.x=100;pts6.y=40; /*合并桶中的新边,按次序插入到 AET 中*/ initgraph( /*设置 graphic 模式*/ ScanFill(7,pts,2);getch();太 原 师 范 学 院 实 验 报 告 续页四、实验总结通过运用 C 语言环境下的图像显示设置,本次实验我学会了多边形区域扫描线填充的有序边表算法,设计相关的数据结构(如链表结构、结点结构等) ,并将实现的算法应用于任意多边形的填充,为深一步的学习做好了铺垫。

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

当前位置:首页 > 实用文档 > 统计图表

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报