计算机图形学区域填充的扫描线算法分析.docx
- 文档编号:2940156
- 上传时间:2022-11-16
- 格式:DOCX
- 页数:10
- 大小:44.87KB
计算机图形学区域填充的扫描线算法分析.docx
《计算机图形学区域填充的扫描线算法分析.docx》由会员分享,可在线阅读,更多相关《计算机图形学区域填充的扫描线算法分析.docx(10页珍藏版)》请在冰豆网上搜索。
计算机图形学区域填充的扫描线算法分析
计算机图形学——区域填充的扫描线算法
1.实验名称:
区域填充的扫描线算法
2.实验目的:
1、理解区域填充扫描线算法的原理;
2、实现区域填充的扫描线算法并测试;
3.算法原理:
算法基本思想:
首先填充种子点所在扫描线上位于区域内的区段,然后确定与该区段相邻的上下两条扫描线上位于区域内的区段,并依次将各区段的起始位置保存,这些区段分别被用区域边界色显示的像素点所包围。
随后,逐步取出一开始点并重复上述过程,直到所保存各区段都填充完毕为止。
借助于栈结构,区域填充的扫描线算法之步骤如下:
Step1.初始化种子点栈:
置种子点栈为空栈,并将给定的种子点入栈;
Step2.出栈:
若种子点栈为空,算法结束;否则,取栈顶元素(x,y)为种子点;
Step3.区段填充:
从种子点(x,y)开始沿纵坐标为y的当前扫描线向左右两个方向逐像素点进行填色,其颜色值置为newcolor
直至到达区域边界。
分别以xl和xr表示该填充区段两端点的横坐标;
Step4.新种子点入栈:
分别确定当前扫描线上、下相邻的两条扫描线上位于区段[xl,xr]内的区域内的区段。
若这些区段内的像素点颜色值为newolor,则转至Step2;否则以区段的右端点为种子点入种子点栈,再转至Step2。
4.原程序代码:
/*****************************************/
/*4-ScanLineFill区域填充的扫描线算法实现*/
/*****************************************/
#include
#include
#include
#include
#defineStack_Size100//栈的大小常量
//定义结构体,记录种子点
typedefstruct{
intx;
inty;
}Seed;
//定义顺序栈(种子点)
typedefstruct
{
SeedPoint[Stack_Size];
inttop;
}SeqStack;
//初始化栈操作
voidInitStack(SeqStack*&S)
{
S=(SeqStack*)malloc(sizeof(SeqStack));
S->top=-1;
}
//种子点栈置空;
voidsetstackempty(SeqStack*S)
{
S->top==-1;
}
//种子点栈状态检测函数
intisstackempty(SeqStack*S)
{
if(S->top==-1)
returntrue;//空栈返回true
else
returnfalse;//非空栈返回false
}
//种子点入栈;
intstackpush(SeqStack*&S,Seedpoint)
{
if(S->top==Stack_Size-1)//栈已满,返回false
returnfalse;
S->top++;//栈未满,栈顶元素加1
S->Point[S->top]=point;
returntrue;
}
//取栈顶元素;
intstackpop(SeqStack*&S,Seed&point)
{
if(S->top==-1)//栈为空,返回false
returnfalse;
point=S->Point[S->top];
S->top--;//栈未空,top减1
returntrue;
}
//画圆
voidCirclePoints(intxc,intyc,intx,inty,intColor)
{
putpixel(xc+x,yc+y,Color);
putpixel(xc+x,yc-y,Color);
putpixel(xc-x,yc+y,Color);
putpixel(xc-x,yc-y,Color);
putpixel(xc+y,yc+x,Color);
putpixel(xc+y,yc-x,Color);
putpixel(xc-y,yc+x,Color);
putpixel(xc-y,yc-x,Color);
}
//中点画圆算法
voidMidpointCircle(intradius,intColor)
{
intx,y;
floatd;
x=0;
y=radius;
d=5.0/4-radius;
CirclePoints(250,250,x,y,Color);
while(x { if(d<0) { d+=x*2.0+3; } else { d+=(x-y)*2.0+5; y--; } x++; CirclePoints(250,250,x,y,Color); } } //四连通扫描线算法 voidScanLineFill4(intx,inty,intoldcolor,intnewcolor) { intxl,xr,i; boolSpanNeedFill; Seedpt;//种子点 SeqStack*S;//定义顺序栈 InitStack(S);//定义了栈之后必须把栈先初始化 setstackempty(S);//种子点栈置空; pt.x=x; pt.y=y; stackpush(S,pt);//种子点(x,y)入栈 while(! isstackempty(S)) { stackpop(S,pt);//取种子点 y=pt.y; x=pt.x; while(getpixel(x,y)==oldcolor) {//从种子点开始向右填充 putpixel(x,y,newcolor); x++; } xr=x-1; x=pt.x-1; while(getpixel(x,y)==oldcolor) {//从种子点开始向左填充 putpixel(x,y,newcolor); x--; } xl=x+1; x=xl; y=y+1;//处理上面一条扫描线 while(x { SpanNeedFill=false; while(getpixel(x,y)==oldcolor) { SpanNeedFill=true; x++; }//待填充区段搜索完毕 if(SpanNeedFill) {//将右端点作为种子点入栈 pt.x=x-1; pt.y=y; stackpush(S,pt); SpanNeedFill=false; }//继续向右检查以防遗漏 while((getpixel(x,y)! =oldcolor)&&(x x++; }//上一条扫描线上检查完毕 x=xl; y=y-2;//处理下面一条扫描线 while(x { SpanNeedFill=false; while(getpixel(x,y)==oldcolor) { SpanNeedFill=true; x++; } if(SpanNeedFill) { pt.x=x-1; pt.y=y; stackpush(S,pt); SpanNeedFill=false; } while((getpixel(x,y)! =oldcolor)&&(x x++; } } } //主函数检测 voidmain() { intradius,color; intx,y;//种子点 intoldcolor,newcolor;//原色与填充色 //输入参数值 printf("inputradiusandcolor: \n");//画圆参数 scanf("%d,%d",&radius,&color); printf("inputxandy: \n");//读入内点 scanf("%d,%d",&x,&y); printf("inputoldcolorandnewcolor: \n");//读入原色与填充色 scanf("%d,%d",&oldcolor,&newcolor); intgdriver=DETECT,gmode; initgraph(&gdriver,&gmode,"c: \\tc"); //用背景色清空屏幕 cleardevice(); //设置绘图色为红色 setcolor(RED); MidpointCircle(radius,color);//用中点画圆算法画圆 rectangle(150,150,350,350);//再画一个矩形区域 ScanLineFill4(x,y,oldcolor,newcolor);//扫描线区域填充 getch(); closegraph(); } 5.运行结果与讨论: 测试结果1: 测试结果2: 6.实验分析与讨论: 1.通过借助栈这一数据结构,完成了区域填充的扫描线算法的实现,并利用以前所学的画圆等算法,进行综合运用,在此基础上进行扩充,设计多种图案,进行扫描线填充算法的检测,都得到了理想的结果,体现了算法的有效性; 2.栈的数据结构给种子点的操作带来了极大的方便,为算法的实现提供了便利,同时还提高了算法的复用性和可靠性; 3.此扫描线填充算法能够对多种图案进行填充,展现了算法的实用性。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机 图形学 区域 填充 扫描 算法 分析