计算机图形学四连通区域种子填充算法实验上课讲义

合集下载

计算机图形学--区域填充算法的实现

计算机图形学--区域填充算法的实现

实验四区域填充算法的实现班级信计2班学号 20080502090 姓名张进分数一、实验目的和要求:1、理解区域的表示和类型,能正确区分四连通和八连通的区域2、了解区域填充的实现原理3、利用TurboC实现区域填充的递归算法二、实验内容:当给定种子点(x,y)时,首先填充种子点所在的扫描线上的位于给定区域的一个区段,然后确定与这一区段连通的上下两条扫描线上位于给定区域的区段依次保存下来。

反复这个过程,直到填充结束.三、实验结果分析1、种子填充算法假设在多边内有一像素已知,由此出发利用连通性找到区域内的所有像素2、设(x,y)为内点表示的四连通区域内的一点,oldcolor为区域的原色。

现取(x,y)为种子点,要将整个区域填充为显得颜色newcolor,递归填充过程如下:先判别像素(x,y)的颜色,若它的值不等于oldcolor,说明该像素或者位于区域之外或者已经被置于newcolor,不需要填充,算法结束,否则置该像素的颜色为newcolor,再对与其相邻上、下、左、右四个相邻像素分别作递归填充。

1、程序代码:#include "Conio.h"#include "graphics.h" /*for initgr()*/#include "stdio.h" /*for NULL */#define closegr closegraphvoid initgr(void) /* BGI初始化*/{int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同样效果*/ registerbgidriver(EGAVGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行*/initgraph(&gd, &gm, "");}enum BOOL{FALSE = 0, TRUE = 1};typedef struct{int y;int xLeft;int xRight;}Span;/*区段*/typedef struct stacknode{Span span;struct stacknode *next;}stacknode;typedef struct{stacknode *top;}linkstack;/*-----------------进栈操作----------------------------------------*/ void PushStack(linkstack *s, Span *span){stacknode *p=(stacknode*)malloc(sizeof(stacknode));p->span.y = span->y;p->span.xLeft = span->xLeft;p->span.xRight = span->xRight;p->next=s->top;s->top=p;}/*-----------------出栈操作------------------------------------------*/ void PopStack(linkstack *s,Span *span){int x;stacknode *p=s->top;span->y = p->span.y;span->xLeft = p->span.xLeft;span->xRight = p->span.xRight;s->top=p->next;free(p);}/*-----------------将栈清空------------------------------------------*/ void SetStackEmpty(linkstack *s){stacknode *p=s->top;while( s->top != NULL){free(p);s->top=p->next;}}/*--------------判断栈是否为空----------------------------------------*/ int IsStackEmpty(linkstack *s){if(s->top == NULL)return 1;elsereturn 0;}/*----------------核心程序开始----------------------------------------*/ void ScanLineFill4(int x,int y,int oldColor,int newColor){int xLeft,xRight;int i;enum BOOL isLeftEndSet, spanNeedFill;Span span;linkstack *s=(linkstack*)malloc(sizeof(linkstack));s->top = NULL;/*填充并确定种子点(x,y)所在的区段*/i = x;while(getpixel(i,y) == oldColor)/*向右填充*/{putpixel(i,y,newColor);i++;}span.xRight = i - 1; /*确定区段右边界*/i = x - 1;while(getpixel(i,y) == oldColor)/*向左填充*/{putpixel(i,y,newColor);i--;}span.xLeft = i + 1; /*确定区段左边界*//*初始化*/SetStackEmpty(s);span.y = y;PushStack(s,&span);/*将前面生成的区段压入堆栈*/while( ! IsStackEmpty(s) )/*终止判断*/{/*出栈*/PopStack(s, &span);/*处理上面扫描线*/y = span.y + 1;xRight = span.xRight;i = span.xLeft - 1;isLeftEndSet = FALSE;while(getpixel(i,y) == oldColor)/*向左填充*/ {putpixel(i, y, newColor);i--;}if( i != span.xLeft - 1)/*确定区段左边界*/{isLeftEndSet = TRUE;xLeft = i + 1;}i = span.xLeft;while( i < xRight){spanNeedFill = FALSE;while(getpixel(i,y) == oldColor) /*向右填充*/{if( ! spanNeedFill){spanNeedFill = TRUE;if( ! isLeftEndSet){isLeftEndSet = TRUE;xLeft = i;}}putpixel(i,y,newColor);i++;}if( spanNeedFill ){span.y = y;span.xLeft = xLeft;span.xRight = i - 1;PushStack(s, &span); /*将区段压入堆栈*/isLeftEndSet = FALSE;spanNeedFill = FALSE;}/* while(getpixel(i,y) != oldColor) */i++;}/*end of while( i < xRight) *//*处理下面一条扫描线,与处理上面一条扫描线完全类似*/ y = y - 2;xRight = span.xRight;i = span.xLeft - 1;isLeftEndSet = FALSE;while(getpixel(i,y) == oldColor)/*向左填充*/{putpixel(i, y, newColor);i--;}if( i != span.xLeft - 1)/*确定区段左边界*/{isLeftEndSet = TRUE;xLeft = i + 1;}i = span.xLeft;while( i < xRight){spanNeedFill = FALSE;while(getpixel(i,y) == oldColor) /*向右填充*/{if( ! spanNeedFill){spanNeedFill = TRUE;if( ! isLeftEndSet){isLeftEndSet = TRUE;xLeft = i;}}putpixel(i,y,newColor);i++;}if( spanNeedFill ){span.y = y;span.xLeft = xLeft;span.xRight = i - 1;PushStack(s, &span); /*将区段压入堆栈*/isLeftEndSet = FALSE;spanNeedFill = FALSE;}/* while(getpixel(i,y) != oldColor) */i++;}/*end of while( i < xRight) */delay(2000); /*延时*/}/*end of while( ! isStackEmpty() ) */}/*end of ScanLineFill4() *//*---------------------main()------------------------------------------*/ int main(){initgr(); /* BGI初始化*/setbkcolor(3);setcolor(5);moveto(50, 50); /*绘制4连通区域*/lineto(400, 50);lineto(400,300);lineto(150,300);lineto(150,400);lineto(50, 400);lineto(50, 50);ScanLineFill4(150,150,0,14); /*相与后oldColor == 0*/getch(); /* 暂停一下,看看前面绘图代码的运行结果*/ closegr(); /* 恢复TEXT屏幕模式*/return 0;}1.运行结果:。

计算机图形学四连通区域种子填充算法实验

计算机图形学四连通区域种子填充算法实验

计算机图形学四连通区域种子填充算法实验————————————————————————————————作者: ————————————————————————————————日期:ﻩ《计算机图形学实验》报告任课教师:钱文华2016年春季学期实验:四连通区域种子填充算法实验时间:2016年12月8日实验地点:信息学院2204实验目的:掌握种子填充算法的原理,并会用种子填充算法和opengl并结合使用c++语言编写程序绘制多边形。

实验原理:种子填充算法又称为边界填充算法。

其基本思想是:从多边形区域的一个内点开始,由内向外用给定的颜色画点直到边界为止。

如果边界是以一种颜色指定的,则种子填充算法可逐个像素地处理直到遇到边界颜色为止。

内点的检测条件:if(interiorColor!=bo rderColor&&interiorColor!=fillColor)。

种子填充算法常用四连通域和八连通域技术进行填充操作。

从区域内任意一点出发,通过上、下、左、右四个方向到达区域内的任意像素。

用这种方法填充的区域就称为四连通域;这种填充方法称为四向连通算法。

从区域内任意一点出发,通过上、下、左、右、左上、左下、右上和右下八个方向到达区域内的任意像素。

用这种方法填充的区域就称为八连通域;这种填充方法称为八向连通算法。

一般来说,八向连通算法可以填充四向连通区域,而四向连通算法有时不能填充八向连通区域。

四向连通填充算法:a)种子像素压入栈中;b)如果栈为空,则转e);否则转c);c) 弹出一个像素,并将该像素置成填充色;并判断该像素相邻的四连通像素是否为边界色或已经置成多边形的填充色,若不是,则将该像素压入栈;d)转b);e)结束。

四连通填充算法利用到了递归的思想。

本实验只包括四连通填充算法程序代码:#include<glut.h>#include<stdlib.h>#include<math.h>#include<windows.h>voidinit(void){ glClearColor(1.0,1.0,1.0,0.0);glMatrixMode(GL_PROJECTION);gluOrtho2D(0.0,300.0,0.0,300.0);}void setPixel(intx,inty,longfillColor){ glColor3f(fillColor<<16,fillColor<<8,fillColor);glBegin(GL_POINTS);glVertex2i(x,y);glEnd();}voidboundaryFill4(int x,inty,long fillColor,long borderColor){ unsignedchar params[3];long interiorColor;glReadPixels(x,y,1,1,GL_RGB,GL_UNSIGNED_BYTE,par ams);interiorColor=RGB(params[0],params[1],params[2]);if(interiorColor!=borderColor&&interiorColor!=fillColor){ setPixel(x,y,fillColor);boundaryFill4(x+1,y,fillColor,borderColor);boundaryFill4(x-1,y,fillColor,borderColor); boundaryFill4(x,y+1,fillColor,borderColor);boundaryFill4(x,y-1,fillColor,borderColor);} }voidlineSegment(void) {long borderColor=RGB(255,0,0);longfillColor=RGB(0,0,255);glClear(GL_COLOR_BUFFER_BIT); glColor3f(255,0,0); glBegin(GL_LINE_LOOP);glVertex2i(0,40);glVertex2i(20,0);glVertex2i(60,0);glVertex2i(80,40);glVertex2i(60,80);glVertex2i(20,80);glEnd();boundaryFill4(60,60,fillColor,borderColor);glFlush();}voidmain(int argc,char**argv){glutInit(&ar gc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowPosition(150,100);glutInitWindowSize(300,300);glutCreateWindow("种子填充");init();glutDisplayFunc(lineSegment);glutMainLoop();}上实验课时机房的实验结果:后来的实验结果:glVertex2i(0,40);glVertex2i(20,0);glVertex2i(60,0);glVertex2i(80,40);glVertex2i(60,80);glVertex2i(20,80);glEnd();boundaryFill4(60,60,fillColor,borderColor);以上这段程序改成如下glVertex2i(90,40);glVertex2i(120, 100);glVertex2i(90,160);glVertex2i(60, 160);glVertex2i(60, 40);glEnd();boundaryFill4(70,60,fillColor,borderColor); 改变参数后:再把glVertex2i(90,40);glVertex2i(120, 100);glVertex2i(90,160);glVertex2i(60, 160);glVertex2i(60, 40);glEnd();boundaryFill4(70,60,fillColor,borderColor);改成glVertex2i(100, 100);glVertex2i(200, 100);glVertex2i(150,150);//glVertex2i(60, 160);//glVertex2i(60, 40);glEnd();boundaryFill4(150,120,fillColor,borderColor);后的结果如下图:实验总结:通过多组数据的测试,知道了上面算法的正确,普适性。

案例8 四邻接点种子填充算法

案例8  四邻接点种子填充算法
计算机图形学实践教程(VisualC++版)(第2版)
案例8 四邻接点种子填充算法
孔令德 太原工业学院计算机工程系 2017.1.10
知识点


四邻接点种子填充算法。 判断种子像素位于多边形之内的方法。 种子像素四邻接点的访问方法。 堆栈操作函数。
案例描述
请使用四邻接点种子算法填充示例多边形。在1024×768的显
总结
本案例设计了CStackNode类用于执行堆栈操作。种子填 充算法一般要求填充色与边界色不同。 种子算法将太多的像素入栈,当图形较大时,栈内的数 据量庞大,填充效率很低。改进方法是使用扫描线种子填充
算法,这样入到明显改善。
pTop=pHead->pNext;
pHead->pNext=pTop->pNext; point=pTop->PixelPoint; delete pTop; } }
程序代码
(4)填充函数 void CTestView::FillPolygon(CDC *pDC) { COLORREF BoundaryClr=RGB(0,0,0); //边界色 COLORREF PixelClr; //当前像素的颜色 pHead=new CStackNode; //建立栈头结点 pHead->pNext=NULL; //栈头结点的指针域总为空 Push(Seed); //种子像素入栈 CP2 PopPoint; Pop(PopPoint); pDC->SetPixelV(Round(PopPoint->PixelPoint.x),Round(PopPoint>PixelPoint.y),SeedClr); PointLeft.x=PopPoint->PixelPoint.x-1; //搜索出栈结点的左方像素 PointLeft.y=PopPoint->PixelPoint.y; PixelClr=pDC->GetPixel(Round(PointLeft.x),Round(PointLeft.y)); if(BoundaryClr!=PixelClr && SeedClr!=PixelClr) Push(PointLeft); //左方像素入栈

计算机图形学实验扫描线种子填充算法

计算机图形学实验扫描线种子填充算法

实验二4-10一、实验题目扫描线种子填充算法是通过扫描线来填充多边形内的水平像素段,处理每条扫描线时仅需将其最右端像素入栈,可以有效提高填充效率。

请使用MFC编程填充图4-60所示的空心体汉字(四连通),填充效果如图4-61所示。

二、实验思想扫描线种子填充算法:先将种子像素入栈,种子像素为栈底像素,如果栈不为空,执行如下4步操作。

(1)栈顶像素出栈。

(2)沿扫描线对出栈像素的左右像素进行填充,直至遇到边界像素为止。

即每出栈一个像素,就对区域内包含该像素的整个连续区间进行填充。

(3)同时记录该区间,将区间最左端像素记为x left,最右端像素记为x right。

(4)在区间〔x left,x right〕中检查与当前扫描线相邻的上下两条扫描线的有关像素是否全为边界像素或已填充像素,若存在非边界且未填充的像素,则把未填充区间的最右端像素取作种子像素入栈。

三、实验代码void CTestView::OnLButtonDown(UINT nFlags, CPoint point)//左键按下函数{// TODO: Add your message handler code here and/or call defaultSeed=point;//选择种子位置CharFill();//进行填充CView::OnLButtonDown(nFlags, point);}void CTestView::CharFill()//文字填充函数{CRect Rect;GetClientRect(&Rect);CClientDC dc(this);COLORREF BoundColor;//边界色int Width=Rect.right-Rect.left;int Hight=Rect.bottom-Rect.top ;int Flag;int x0,y0,x,y;CPoint Point;std::vector<CPoint> FillBuffle;//定义CPoint类型的数组序列对象FillBuffle.reserve(10);//定义数组序列的大小FillBuffle.push_back(CPoint(Seed)); //把种子结点压入数组序列BoundColor=RGB(0,0,0);//定义边界色为黑色while(!FillBuffle.empty())//如果数组序列非空{Point=FillBuffle.front();//弹出数组序列头元素x=Point.x;y=Point.y;FillBuffle.erase(FillBuffle.begin());//清除数组序列内的元素dc.SetPixel(Point,Fillcolor);//绘制像素//判断像素的位置是否在图形内部x0=x+1;//右方判断while(dc.GetPixel(x0,y)!=BoundColor&&dc.GetPixel(x0,y)!=Fillcolor) {x0=x0+1;if(x0>=Width)//到达屏幕最右端{MessageBox("种子超出范围","警告");RedrawWindow();return;}}y0=y+1;//下方判断while(dc.GetPixel(x,y0)!=BoundColor&&dc.GetPixel(x,y0)!=Fillcolor) {y0=y0+1;if(y0>=Hight)//到达屏幕最下端{MessageBox("种子超出范围","警告");RedrawWindow();return;}}RightPoint.x=x0;//右边界内的左邻点x0=x-1;while(dc.GetPixel(x0,y)!=Fillcolor&&dc.GetPixel(x0,y)!=BoundColor){dc.SetPixel(x0,y,Fillcolor);x0=x0-1;if(x0<=0)//到达屏幕最左端{MessageBox("种子超出范围","警告");RedrawWindow();return;}}y0=y-1;while(dc.GetPixel(x,y0)!=BoundColor&&dc.GetPixel(x,y0)!=Fillcolor){y0=y0-1;if(y0<=0)//到达屏幕最上端{MessageBox("种子超出范围","警告");RedrawWindow();return;}}LeftPoint.x=x0+1;//左边界内的右邻点x0=LeftPoint.x;y=y+1;//下一条扫描线while(x0<RightPoint.x){Flag=0;while((dc.GetPixel(x0,y)!=Fillcolor)&&(dc.GetPixel(x0,y)!=BoundColor)) {if(Flag==0)Flag=1;x0++ ;}if(Flag==1){if((x0==RightPoint.x)&&(dc.GetPixel(x0,y)!=Fillcolor)&&(dc.GetPixel(x0,y)!=BoundColor))FillBuffle.push_back(CPoint(x0,y));//进入数组序列else{FillBuffle.push_back(CPoint(x0-1,y));}Flag=0;}PointNext.x=x0;while(((dc.GetPixel(x0,y)==Fillcolor)&&(x0<RightPoint.x))||((dc.GetPixel(x0,y)==BoundColor) &&(x0<RightPoint.x))){x0 ++;}}x0=LeftPoint.x;y=y-2;while(x0<RightPoint.x){Flag=0;while((dc.GetPixel(x0,y)!=Fillcolor)&&(dc.GetPixel(x0,y)!=BoundColor)&&(x0<RightPoint.x)) {if(Flag==0)Flag=1;x0++ ;}if(Flag==1){if((x0==RightPoint.x)&&(dc.GetPixel(x0,y)!=Fillcolor)&&(dc.GetPixel(x0,y)!=BoundColor))FillBuffle.push_back(CPoint(x0,y));else{FillBuffle.push_back(CPoint(x0-1,y));}Flag=0;}PointNext.x=x0;while((dc.GetPixel(x0,y)==Fillcolor&&x0<RightPoint.x)||(dc.GetPixel(x0,y)==BoundColor&&x 0<RightPoint.x)){x0++;}}}FillBuffle.clear();return;}void CTestView::OnMENUFill(){// TODO: Add your command handler code hereRedrawWindow();MessageBox("请在空心字体内部单击鼠标左键!","提示");}四、实验结果截图。

计算机图形学实验四 区域填充算法的实现

计算机图形学实验四   区域填充算法的实现

实验四区域填充算法的实现班级 08信计2班学号 20080502082 姓名分数一、实验目的和要求:1、理解区域的表示和类型。

2、能正确区分四连通和八连通的区域3、了解区域填充的实验原理。

4、利用C++实现区域填充的递归算法。

二、实验内容:1假设在多边形内有一像素已知,由此出发利用连通性找到区域内所有像素。

2 取(x,y)为种子点将整个区域填充为新的颜色。

3 进行递归填充。

三、实验结果分析区域填充属性包括填充样式,填充颜色和填充图案的类型。

C语言中定义了某种图形后,即可调用-floodfill函数,对指定区域进行填充. 程序代码#define pi 3.141592#define MAX(a,b) (a>b)? a:b#define MIN(a,b) (a<b)? a:b#include "graphics.h"#include "math.h"struct edge {int ymax;float x;float delat;struct edge * pedge; };struct point{int x;int y;} ;struct et { struct edge * pedge;int n;};struct edge g_aet[10];struct edge dge[10];struct et g_et[10];struct point point1,point2;int ZUO(float x){ if((int)x==x)return (int)x;return (int)x+1;}int YOU(float x){ if((int)x==x)return (int)x-1;return (int)x;}int k=400,l=0;void draw1(){int i,t,j,a,c,p,z; float b;struct edge temp;for(i=k;i<=l;i++){a=0;for(t=0;t<=9;t++){ if(g_et[t].n==i) break;}for(j=0;j<=9;j++){ if(g_aet[j].ymax==0) break;}if(t!=10){ g_aet[j].ymax=g_et[t].pedge->ymax;g_aet[j].x=g_et[t].pedge->x;g_aet[j].delat=g_et[t].pedge->delat;if(g_et[t].pedge->pedge!=0){g_aet[j+1].ymax=g_et[t].pedge->pedge->ymax;g_aet[j+1].x=g_et[t].pedge->pedge->x;g_aet[j+1].delat=g_et[t].pedge->pedge->delat; }}for(j=0;j<=9;j++){ if(g_aet[j].ymax==0) break; }j--;for(t=0;t<=j;t++){ for(z=0;z<=j-1;z++){if(g_aet[z].x>g_aet[z+1].x){ temp.ymax=g_aet[z].ymax;temp.x=g_aet[z].x;temp.delat=g_aet[z].delat;g_aet[z].ymax=g_aet[z+1].ymax;g_aet[z].x=g_aet[z+1].x;g_aet[z].delat=g_aet[z+1].delat;g_aet[z+1].ymax=temp.ymax;g_aet[z+1].x=temp.x;g_aet[z+1].delat=temp.delat;}}}for(j=0;j<=9;j++){ if(g_aet[j].ymax==0) break; }j--;for(p=0;p<=j;p++){ a++;if(a%2!=0)b=g_aet[p].x;else{for(c=ZUO(b);c<=YOU(g_aet[p].x);c++)putpixel(c,i,2);}}for(t=0;t<=j;t++){ if(g_aet[t].ymax==(i+1)){ g_aet[t].ymax=0;g_aet[t].x=0;g_aet[t].delat=0;}g_aet[t].x+=g_aet[t].delat;}for(t=0;t<=j;t++){ for(z=0;z<=j-1;z++){if(g_aet[z].x<g_aet[z+1].x){ temp.ymax=g_aet[z].ymax;temp.x=g_aet[z].x;temp.delat=g_aet[z].delat;g_aet[z].ymax=g_aet[z+1].ymax;g_aet[z].x=g_aet[z+1].x;g_aet[z].delat=g_aet[z+1].delat;g_aet[z+1].ymax=temp.ymax;g_aet[z+1].x=temp.x;g_aet[z+1].delat=temp.delat;}}}}}void generate(){int i,y,n=1,m,q,p;float x;for(i=0;i<=9;i++){if(n==1){ point2.x=point1.x=300;point2.y=point1.y=200;n++;}else{ if(n%2==0){ x=40*cos(i*pi/5)+200;y=40*sin(i*pi/5)+200;}else{ x=100*cos(i*pi/5)+200;y=100*sin(i*pi/5)+200;}if(point1.y==y) { n++; continue;}m=MIN(point1.y,y);if(x==point1.x){ dge[i-1].delat=0;dge[i-1].ymax=MAX(point1.y,y);dge[i-1].x=x;dge[i-1].pedge=0;for(q=0;q<=9;q++){ if(g_et[q].n==m) break;}if(q==10){g_et[i-1].pedge=&dge[i-1];g_et[i-1].n=m;}else{g_et[q].pedge->pedge=&dge[i-1];g_et[i-1].n=0;}}else{dge[i-1].delat=(float)(x-point1.x)/(y-point1.y);dge[i-1].ymax=MAX(point1.y,y);if(point1.y>y) dge[i-1].x=x;else {dge[i-1].x=point1.x; }dge[i-1].pedge=0;for(q=0;q<=9;q++){ if(g_et[q].n==m) break;}if(q==10){ g_et[i-1].pedge=&dge[i-1];g_et[i-1].n=m;}else{g_et[q].pedge->pedge=&dge[i-1];g_et[i-1].n=0;}}p=MAX(point1.y,y);k=MIN(k,m);l=MAX(l,p);point1.x=x;point1.y=y;n++;}}if(point1.y==point2.y) return;else{if(point2.x==point1.x){dge[i-1].delat=0;dge[i-1].ymax=MAX(point1.y,point2.y);dge[i-1].x=point2.x;}else{ dge[i-1].ymax=MAX(point1.y,point2.y);if(point1.y>point2.y) dge[i-1].x=point2.x;else {dge[i-1].x=point1.x;}dge[i-1].delat=(float)(point2.x-point1.x)/(point2.y-point1.y);}}m=MIN(point1.y,point2.y);k=MIN(k,m);l=MAX(l,dge[i-1].ymax);g_et[i-1].n=m;g_et[i-1].pedge=&dge[i-1];}void main(){ int driver=DETECT,mode; int i; registerbgidriver(EGA VGA_driver);initgraph(&driver,&mode,"\\tc");initgraph(&driver,&mode,"\\tc");for(i=0;i<=9;i++){ g_aet[i].ymax=0; g_aet[i].x=0; g_aet[i].delat=0;g_et[i].pedge=0;}generate();draw1();circle(200,200,100); circle(200,200,40);getch();closegraph();}。

计算机图形学--第四讲 区域填充算法

计算机图形学--第四讲   区域填充算法

任课教师:李陶深教授tshli@12直线生成算法圆与椭圆的绘制算法5图元的概念436区域填充算法裁剪反走样技术4.4 区域填充算法4.4 区域填充算法—基础知识(3)线框多边形物体:只需扫描转换线段填充多边形物体:要扫描转换多边形本质:点阵表示。

特点:面着色,画面明暗自然、色彩丰富。

4.4 区域填充算法4.4 区域填充算法—基础知识(4)图形学中多边形的两种表示方式顶点表示:用多边形的有序顶点序列表示多边形点阵表示:用位于多边形内部的像素集合来表示多边形4.4 区域填充算法多边形边界的矢量形式数据之上,可用于程序填色,也可用于交互填色。

形边界的图像形式数据之上,并还需提供多边形边界内一点的坐标。

概括地说,该算法先画边界,然后对内定义区域填充。

所以,它一般只能用于人机交互填色,而难以用于程序填色。

4.4 区域填充算法—多边形填色算法的问题多边形填色算法面临的一个首要问题,是判断一个像素是在多边形内还是多边形外。

Question1: How to Judge…?Question2: How to improve …?图4.14 射线法图4.15 转角法4.4 区域填充算法4.4 区域填充算法4.4 区域填充算法4.4 区域填充算法4.4 区域填充算法大量的求交、乘除运算4.4 区域填充算法—扫描线填色算法(1)基本思路:扫描线算法按扫描线的顺序计算出扫描线与多边形的相交区间,然后用要求的颜色填充这些区间内的像素。

该算法利用了扫描线的连续性和边的连续性,避免对像素的逐点判断和反复求交运算,减少了计算量,提高了算法速度。

具体处理过程:先求出扫描线与多边形边的交点,利用扫描线的连续性求出多边形与扫描线相交的连续区域,然后利用多边形边的连续性,求出下一条扫描线与多边形的交点,对所有扫描线由上到下依次处理。

4.4 区域填充算法—扫描线填色算法(2) 算法实现的步骤:对每一条扫描线执行如下四步:(1) 求交:求扫描线与多边形各边的交点;(2) 排序:将求得的交点按递增顺序进行排序;(3) 交点配对:确定相交区间;(4) 区间填色:将相交区间内的像素置成多边形色, 相交区间外的像素置成背景色。

计算机图形学 第四讲 区域填充

计算机图形学  第四讲  区域填充

活化边表
把与当前扫描线 相交的边称为活 化边,并把它们 按与扫描线交点 X坐标递增的顺 序存放在一个链 表中,形成活化 边表。
表结构
算法中采用较灵活的数据结构。它由边的分有序边 表ET(Edge Table)和边的活化边表AEL(Active Edge Table )两部分组成。 表结构ET和AET中的基本元素为多边形的边。边 的结构由以下四个域组成: ymax 边的上端点的y坐标; x 在ET中表示边的下端点的x坐标,在 AET中则表示边与扫描线的交点的坐标; Δx 边的斜率的倒数; next 指向下一条边的指针。
四个方向运动 八个方向运动
四连通区域
八连通区域
算法原理:
填充区域边界 以一种颜色指 定,从区域的 一个内部点开 始,由内至外 绘制直到填充算法
设(x,y)为内点表示的4连通区域内的一点,oldcolor为区域的 原色,要将整个区域填充为新的颜色newcolor。内点表示的 4连通区域的递归填充算法: void FloodFill4(int x,int y,int oldcolor,int newcolor) { if(GetPixel(x,y)==oldcolor) { SetPixel(x,y,newcolor); FloodFill4(x,y+1,oldcolor,newcolor); FloodFill4(x,y-1,oldcolor,newcolor); FloodFill4(x-1,y,oldcolor,newcolor); FloodFill4(x+1,y,oldcolor,newcolor); } }
i1
a
i1
i
a
其中 x
b 为常数, a
交点数的处理

实验三区域四连通填充算法

实验三区域四连通填充算法
课程已经过去了有些时间但是徐老师教给我们的东西却令我感到获益匪浅课程结束后明显感到自己的能力有了一些提高暑假留校培训时感觉自己用到了很多您教会我们的方法回过头去看看曾经敲过的c代码也感觉
实验三区域四连通填充算法
1. 课程名称:计算机图形学 2. 实验目的和要求: 目的:理解、掌握区域填充算法原理。 要求:读懂示范代码并对其改进。 3. 实验题目:区域四连通填充算法 4. 实验过程: (1) 复习区域填充算法原理; (2) 根据算法原理,读懂示范代码; (3) 尝试在示范代码的基础上,实现扫描线填充算法。 5. 实验结果 6. 实验分析 试比较扫描线填充算法与简单

Opengl的不规则图形的4联通种子递归填充和扫描线种子递归填充算法实现

Opengl的不规则图形的4联通种子递归填充和扫描线种子递归填充算法实现

Opengl的不规则图形的4联通种⼦递归填充和扫描线种⼦递归填充算法实现实验题⽬:不规则区域的填充算法实验⽬的:验证不规则区域的填充算法实验内容:利⽤VC与OpenGL,实现不规则区域的填充算法。

1、必做:实现简单递归的不规则区域填充算法。

2、选做:针对简单递归算法栈空间占⽤太⼤的缺点,进⾏改进,实现基于扫描线的种⼦填充算法实验要求:n 将坐标系⽹格在屏幕上画出来,每个像素点占据⼀个格点,⽤⼀个⼩实⼼圆圈表⽰。

n ⽤⿏标点击的⽅式,绘制不规则区域的边界。

n 种⼦填充算法,可⽤4联通或8联通任选⼀种。

以下是我⽤c++ 实现的⽅式去实现2种填充算法#include <iostream>#include <vector>#include <stack>#include <iterator>#include "glut.h"using namespace std;//////////////////////////#define WIDTH 400#define HEIGHT 400#define SUBWIDTH 20#define SUBHEIGHT 20/////////////////////////class tile // 基于open gl 的坐标系{public:enum _toolEnum{_sideLength=10}; // 边长tile(unsigned int x=0,unsigned int y=0):_x(x),_y(y){_state = 0;}void draw(){// 画出初始tile(根据不同_state,⽤不同的颜⾊)// glClear(GL_COLOR_BUFFER_BIT);if (_state == 0) // ⽆⾊{glColor3f(255 ,255 ,255);}else if(_state == 1) // 红⾊{glColor3f(255,0 ,0);}else if(_state == 2) // 绿⾊{glColor3f(0 ,255 ,0);}glBegin(GL_POINTS);glVertex2i(_x*20+10,_y*20+10);glEnd();glFlush();}inline void op_side() // 设置成边界红⾊{_state = 1;draw();}inline void op_padding() // 设置成填充绿⾊{_state = 2;draw();}public:unsigned int _x; // 瓷砖的横向索引unsigned int _y; // 瓷砖的纵向索引int _state; // 0代表⽆⾊初始状态,1代表红⾊边框,2代表绿⾊内填充容};class tileLayer{public:tileLayer(unsigned int h=20,unsigned int v=20):_hTileNum(h),_vTileNum(v){init();}void init(){for (int i=0;i<_vTileNum;i++){vector<tile> tmpVec;for (int j=0;j<_hTileNum;j++){tmpVec.push_back(tile(j,i)); // 注意是 j,icout<<j<<","<<i<<"\t";}_vecTile.push_back(tmpVec);cout<<endl;}}void recursive_pad(GLint index_X, GLint index_Y) // 参数是索引{// 在这计算是哪个为种⼦点。

第四讲 区域填充

第四讲 区域填充

多边形分为凸多边形、凹多边形、含内环的多边形。
4.1多边形的扫描转换
多边形的表示方法
顶点表示
点阵表示
顶点表示:用多边形顶点的序列来刻划多边形。 直观、几何意义强、占内存少;不能直接用于 面着色。 点阵表示:用位于多边形内的象素的集合来刻 划多边形。失去了许多重要的几何信息;便于 运用帧缓冲存储器表示图形,易于面着色。
=xi+(-b/a)= xi+1/m
因此,利用这种边的相关性,我们不需算出边线与各 扫描线的全部交点,只需以边为单位,对每条边建立 一个边记录即可,其内容如下(P35): 边记录 ymax xi 1/m next
奇点的处理
当扫描线与多边形P的交点是P的顶点时,则 称该交点为奇点。
多边形P的顶点可分为两类:极值奇点和非极值奇 点。如果(yi-1 - yi)(yi+1 - yi)≥0,则称顶点Pi 为极值点;否则称Pi为非极值点。 规定:奇点是非极值点时,该点按两个交点计算, 否则按一个交点计算。
点阵字符:存储量大,易于显示
矢量字符:存储量小,美观,变换方便; 但需 要光栅化后才能显示。
字符属性
字体 宋体 仿宋体 楷体 黑体 隶书
字高 宋体 宋体 宋体 宋体
字宽 大海 大海 大海 大海
字倾斜角
倾斜 倾斜
对齐 (左对齐、中心对齐、右对齐)
字色 红色、绿色、蓝色
3)按“右上左下”的顺序检查与出栈像素相邻的四个像素,若 其中某个像素不在边界上且未置成多边形色,则把该像素入栈。
(2)内点表示的四连通区域种子填充算法
基本思想:从多边形内部任一点(像素)出发,按照“右上左下” 的顺序判断相邻像素,若是区域内的像素,则对其填充,并重复 上述过程,直至所有像素填充完毕。

计算机图形学图形填充

计算机图形学图形填充
关键:寻找一种快速而通用的内部判断方法。
第6页,本讲稿共50页
扫描线:点阵图形在屏幕上的像素点,可以认为是由位于一条条
水平直线上的像素点构成的.
对每一条切割多边形的扫描线,决定扫描线上哪些像素点是 在多边形内部,并对这些相应的像素点赋以合适的值表示某 种颜色或灰度,就能对整个多边形进行扫描转换。
为止。因为交点个数是有限的, 这一过程是一定可以结束的。
第10页,本讲稿共50页
射线交点计数的方法:
从多边形外一点,引水平射线(即扫描线)穿过多边形,记录 扫描线与多边形边的交点个数情况,当交点数为奇数时,扫描线 处在多边形内部,当交点数为偶数时,扫描线处在多边形外部。 多边形与同一扫描线的交点按x方向大小顺序排列,并两两配对,则可
第20页,本讲稿共50页
❖ 如何计算下一条扫描线与边的交点。
直线方程:ax+by+c = 0
当前交点坐标:(xi, yi) 下一交点坐标:(xi+1,yi+1)
xi+1= ((-byi+1)-c)/a = ((-byi+1)-c)/a =xi-b/a=xi+1/mi
第21页,本讲稿共50页
扫描线算法特点
v e<0 环绕数-1
e=VB -VA
第31页,本讲稿共50页
区域填充—边界填充算法
❖ 边界表示法中,由于边界以特殊颜色指定,填充算法可逐个像素地向外处理,直到遇到边 界颜色为止。这种方法称为边界填充算法。
❖ 填充算法可以让艺术家或设计师首先勾画图的轮廓,选择填充颜色和填充模式,然后拾取 内部点,系统就可以自动给图的内部涂上所需的颜色和图案
❖ 特点:算法效率较高。
❖ 缺点:对各种表的维持和排序开销太大,适合软件实现而 不适合硬件实现。

第四讲 区域填充

第四讲 区域填充

点阵字符:存储量大,易于显示
矢量字符:存储量小,美观,变换方便; 但需 要光栅化后才能显示。
字符属性
字体 宋体 仿宋体 楷体 黑体 隶书
字高 宋体 宋体 宋体 宋体
字宽 大海 大海 大海 大海
字倾斜角
倾斜 倾斜
对齐 (左对齐、中心对齐、右对齐)
字色 红色、绿色、蓝色
条件:需提供多边形各顶点的坐标及填充色或图案
扫描线算法
扫描线算法
目标:利用相邻像素之间的连贯性,提高算 法效率 处理对象:非自交多边形 (边与边之间除 了顶点外无其它交点)
(1) 边的相关性及边记录 算法首先要求出扫描线与边界的交点
已知扫描线yi与AB边的交点是(xi,yi)则:
(1) 边的相关性及边记录 yi+1=yi+1, xi+1=xi+1/m m是这条边的斜率 m=1/dx 设ax+by+c=0 (1) 则 斜率m=-b/a 由(1)有 xi+1=-1/a(byi+1+c) 同时 yi+1=yi+1 则 xi+1=-1/a(b(yi+1)+c)=-1/a(byi +c)-b/a
条件: 要求给出边界颜色特征及区域内的一个点,并要 求区域是连通的
区域:分为4连通区域和8连通区域
四个方向运动 八个方向运动
表示内点
四连通区域 八连通区域
67 5 4S9
328
表示边界点
区域连通方式对填充结果的影响
4连通区域边界填 充算法的填充结果
8连通区域边界填 充算法的填充结果
常见的种子填充算法由边界表示的四连通区域种子填充算 法、内点表示的四连通区域种子填充算法、边界表示的八连通 区域种子填充算法、内点表示的八连通区域种子填充算法。

计算机图形学-4实区域填充

计算机图形学-4实区域填充

表5
4∧
3
2
1 0∧
P4P5
528 .
P5P6
5 -1.5 7 ∧
11 0 8 ∧ P3P4
2 0 7 ∧ P6P1
5 -3 2 . 5 3 3 ∧
P1P2
P2P3
P4P5
P3P4
y=7
9 2 8 . 11 0 8 ∧
更新边表,删除P6P1和P5P6,填充交点之间的区域
更新边表,删除P4P5和P3P4,有效边表为空,没有新边,填充算法结束
扫描线与多边形相交的边分处扫描线的两侧,则计 一个交点。设yi是扫描线,yi-1,yi+1分别是共享该顶 点的另外两个顶点,即 yi>yi-1,yi<yi+1,则计1个交 点,如P1。
扫描线与多边形相交的边分处扫描线同侧,且 yi<yi-1,yi<yi+1,则计2个交点(填色),如P2。
扫描线与多边形相交的边分处扫描线同侧,且 yi>yi-1,yi>yi+1,则计0个交点(不填色),如P6。
八向连通算法种子填充算法八向连通区域连通方式对填充结果的影响4连通区域填充算法的填充结果8连通区域填充算法的填充结果简单的种子填充算法4连通边界按右上左下顺序检查与出栈象素相邻的四象素若其中某象素不在边界上且未被置成填充色则将其入栈填充算法演示简单的种子像素入栈有些象素会入栈多次这样一方面降低了算法的效率另一方面还要求很大的存储空间以实现栈的结构解决这个问题的一个办法是在任意一个扫描线与多边形的相交区间含有若干个连续象素中只取一个种象素入栈相应的算法称为扫描线填充算法
扫描线填充算法规则
规则1: 边界上象素的取舍问题,避免填充扩大化。 解决方法: 边界象素:规定落在右上边界的象素不予填充。 具体实现时,只要对扫描线与多边形的相交区间左闭 右开,下闭上开。

计算机图形学四连通区域种子填充算法实验

计算机图形学四连通区域种子填充算法实验

计算机图形学四连通区域种子填充算法实验《计算机图形学实验》报告任课教师:钱文华2016年春季学期实验:四连通区域种子填充算法实验时间:2016年12月8日实验地点:信息学院2204实验目的:掌握种子填充算法的原理,并会用种子填充算法和opengl并结合使用c++语言编写程序绘制多边形。

实验原理:种子填充算法又称为边界填充算法。

其基本思想是:从多边形区域的一个内点开始,由内向外用给定的颜色画点直到边界为止。

如果边界是以一种颜色指定的,则种子填充算法可逐个像素地处理直到遇到边界颜色为止。

内点的检测条件:if(interiorColor!=borderColor&&interiorColor!=fillColor)。

种子填充算法常用四连通域和八连通域技术进行填充操作。

从区域内任意一点出发,通过上、下、左、右四个方向到达区域内的任意像素。

用这种方法填充的区域就称为四连通域;这种填充方法称为四向连通算法。

从区域内任意一点出发,通过上、下、左、右、左上、左下、右上和右下八个方向到达区域内的任意像素。

用这种方法填充的区域就称为八连通域;这种填充方法称为八向连通算法。

一般来说,八向连通算法可以填充四向连通区域,而四向连通算法有时不能填充八向连通区域。

四向连通填充算法:a)种子像素压入栈中;b)如果栈为空,则转e);否则转c);c)弹出一个像素,并将该像素置成填充色;并判断该像素相邻的四连通像素是否为边界色或已经置成多边形的填充色,若不是,则将该像素压入栈;d)转b);e)结束。

四连通填充算法利用到了递归的思想。

本实验只包括四连通填充算法程序代码:#include<glut.h>#include<stdlib.h>#include<math.h>#include<windows.h>void init(void) { glClearColor(1.0,1.0,1.0,0.0);glMatrixMode(GL_PROJECTION);gluOrtho2D(0.0,300.0,0.0,300.0);}void setPixel(int x,int y,long fillColor){ glColor3f(fillColor<<16,fillColor<<8,fillColor); glBegin(GL_POINTS);glVertex2i(x,y); glEnd();}void boundaryFill4(int x,int y,long fillColor,long borderColor){ unsigned char params[3];long interiorColor;glReadPixels(x,y,1,1,GL_RGB,GL_UNSIGNED_BYTE,params); interiorColor=RGB(params[0],params[1],params[2]);if(interiorColor!=borderColor&&interiorColor!=fillColor){ setPixel(x,y,fillColor);boundaryFill4(x+1,y,fillColor,borderColor);boundaryFill4(x-1,y,fillColor,borderColor);boundaryFill4(x,y+1,fillColor,borderColor);boundaryFill4(x,y-1,fillColor,borderColor);} }void lineSegment(void) { long borderColor=RGB(255,0,0); long fillColor=RGB(0,0,255);glClear(GL_COLOR_BUFFER_BIT); glColor3f(255,0,0); glBegin(GL_LINE_LOOP);glVertex2i(0,40);glVertex2i(20,0);glVertex2i(60,0);glVertex2i(80,40);glVertex2i(60,80);glVertex2i(20,80);glEnd();boundaryFill4(60,60,fillColor,borderColor);glFlush(); }void main(int argc,char** argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowPosition(150,100);glutInitWindowSize(300,300);glutCreateWindow("种子填充");init();glutDisplayFunc(lineSegment);glutMainLoop();}上实验课时机房的实验结果:后来的实验结果:glVertex2i(0,40); glVertex2i(20,0);glVertex2i(60,0);glVertex2i(80,40);glVertex2i(60,80);glVertex2i(20,80);glEnd();boundaryFill4(60,60,fillColor,borderColor); 以上这段程序改成如下glVertex2i(90, 40);glVertex2i(120, 100);glVertex2i(90, 160);glVertex2i(60, 160);glVertex2i(60, 40);glEnd();boundaryFill4(70,60,fillColor,borderColor); 改变参数后:再把glVertex2i(90, 40);glVertex2i(120, 100);glVertex2i(90, 160);glVertex2i(60, 160);glVertex2i(60, 40);glEnd();boundaryFill4(70,60,fillColor,borderColor); 改成glVertex2i(100, 100);glVertex2i(200, 100);glVertex2i(150, 150);//glVertex2i(60, 160);//glVertex2i(60, 40);glEnd();boundaryFill4(150,120,fillColor,borderColor);后的结果如下图:实验总结:通过多组数据的测试,知道了上面算法的正确,普适性。

计算机图形学--区域填充算法的实现

计算机图形学--区域填充算法的实现

计算机图形学--区域填充算法的实现实验四区域填充算法的实现班级 08信计二学号 64 姓名刘辉分数一、实验目的和要求:1、理解区域的表示和类型;2、能够正确区分四连通、八连通的区域;3、了解填充函数、区域填充的实现原理;4、了解掌握区域填充的各种算法(种子填充算法、扫描线算法、边填充算法等),并实现种子填充算法和扫描线算法;5、用种子填充算法实现四连同区域和八连通区域的填充,并观察他们之间的区别;6、分析对比种子填充算法和扫描线算法实现的像素逼近效果和程序执行速度;二、实验原理:用点阵方法表示的多边形区域,如果其内部像素具有同一种颜色,而边界像素具有另一种颜色,可以使用种子填充算法和扫描线算法等填充。

种子填充算法是从区域内任一个种子像素位置(x,y)开始,由内向外将填充色扩散到整个多边形区域的填充过程;扫描线填充算法是当给定种子点(x,y)时,首先填充种子点所在扫描线上位于给定区域的一个区段,然后确定与这一段相连通的上、下两条扫描线上位于给定区域内的区段,并依次保存下来的过程。

三、实验内容及步骤:3.1、实验内容:1.利用种子算法实现内点表示的四连通区域的填充。

如:设(x,y)为内点表示的四连通区域内的一点,oldcolor为区域的原色,要将整个区域填充为新的颜色newcolor;2.利用扫描线算法实现以上区域的填充。

如:填充以下图案,圆中填充蓝色,三角形中填充红色;3.2、实验步骤:种子填充算法的步骤:1.种子入栈;2.当栈非空时,进行下面的操作,否则结束;3.栈顶元素出栈,如果是未填充的内部点,则将其填充,继续考察与其连通的点,若是为填充的内部点,则该点入栈,返回2步。

扫描线填充算法的步骤:1.初始化,置栈为空,将种子点(x,y)入栈。

2.出栈,若栈空则结束;否则取栈顶元素(x,y),以y作为扫描线。

3.填充并确定种子点所在区段,从种子点(x,y)出发,沿当前扫描线向左、右两个方向填充,直到边界。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

计算机图形学四连通区域种子填充算法实

《计算机图形学实验》报告
任课教师:钱文华
2016年春季学期
实验:四连通区域种子填充算法
实验时间:2016年12月8日
实验地点:信息学院2204
实验目的:掌握种子填充算法的原理,并会用种子填充算法和opengl并结合使用c++语言编写程序绘制多边形。

实验原理:种子填充算法又称为边界填充算法。

其基本思想是:从多边形区域的一个内点开始,由内向外用给定的颜色画点直到边界为止。

如果边界是以一种颜色指定的,则种子填充算法可逐个像素地处理直到遇到边界颜色为止。

内点的检测条件:
if(interiorColor!=borderColor&&interiorColor!=fillColor)。

种子填充算法常用四连通域和八连通域技术进行填充操作。

从区域内任意一点出发,通过上、下、左、右四个方向到达区域内的任意像素。

用这种方法填充的区域就称为四连通域;这种填充方法称为四向连通算法。

从区域内任意一点出发,通过上、下、左、右、左上、左下、右上和右下八个方向到达区域内的任意像素。

用这种方法填充的区域就称为八连通域;这种填充方法称为八向连通算法。

一般来说,八向连通算法可以填充四向连通区域,而四向连通算法有时不能填充八向连通区域。

四向连通填充算法:
a)种子像素压入栈中;
b)如果栈为空,则转e);否则转c);
c)弹出一个像素,并将该像素置成填充色;并判断该像素相邻的四连通像素是否为边界色或已经置成多边形的填充色,若不是,则将该像素压入栈;
d)转b);
e)结束。

四连通填充算法利用到了递归的思想。

本实验只包括四连通填充算法
程序代码:#include<glut.h>
#include<stdlib.h>
#include<math.h>
#include<windows.h>
void init(void) { glClearColor(1.0,1.0,1.0,0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0,300.0,0.0,300.0);
}
void setPixel(int x,int y,long
fillColor){ glColor3f(fillColor<<16,fillColor<<8,fillColor); glBegin(GL_POINTS);
glVertex2i(x,y); glEnd();
}
void boundaryFill4(int x,int y,long fillColor,long borderColor)
{ unsigned char params[3];
long interiorColor;
glReadPixels(x,y,1,1,GL_RGB,GL_UNSIGNED_BYTE,params); interiorColor=RGB(params[0],params[1],params[2]);
if(interiorColor!=borderColor&&interiorColor!=fillColor)
{ setPixel(x,y,fillColor);
boundaryFill4(x+1,y,fillColor,borderColor);
boundaryFill4(x-1,y,fillColor,borderColor);
boundaryFill4(x,y+1,fillColor,borderColor); boundaryFill4(x,y-1,fillColor,borderColor);
} }
void lineSegment(void) { long borderColor=RGB(255,0,0); long fillColor=RGB(0,0,255);
glClear(GL_COLOR_BUFFER_BIT); glColor3f(255,0,0); glBegin(GL_LINE_LOOP);
glVertex2i(0,40);
glVertex2i(20,0);
glVertex2i(60,0);
glVertex2i(80,40);
glVertex2i(60,80);
glVertex2i(20,80);
glEnd();
boundaryFill4(60,60,fillColor,borderColor);
glFlush(); }
void main(int argc,char** argv) { glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(150,100);
glutInitWindowSize(300,300);
glutCreateWindow("种子填充"); init();
glutDisplayFunc(lineSegment); glutMainLoop();
}
上实验课时机房的实验结果:
后来的实验结果:
glVertex2i(0,40);
glVertex2i(20,0);
glVertex2i(60,0);
glVertex2i(80,40);
glVertex2i(60,80);
glVertex2i(20,80);
glEnd();
boundaryFill4(60,60,fillColor,borderColor); 以上这段程序改成如下
glVertex2i(90, 40);
glVertex2i(120, 100);
glVertex2i(90, 160);
glVertex2i(60, 160);
glVertex2i(60, 40);
glEnd();
boundaryFill4(70,60,fillColor,borderColor); 改变参数后:
再把glVertex2i(90, 40);
glVertex2i(120, 100);
glVertex2i(90, 160);
glVertex2i(60, 160);
glVertex2i(60, 40);
glEnd();
boundaryFill4(70,60,fillColor,borderColor); 改成glVertex2i(100, 100);
glVertex2i(200, 100);
glVertex2i(150, 150);
//glVertex2i(60, 160);
//glVertex2i(60, 40);
glEnd();
boundaryFill4(150,120,fillColor,borderColor);
后的结果如下图:
实验总结:通过多组数据的测试,知道了上面算法的正确,普适性。

种子填充的递归算法的优点是原理非常简单,容易理解,缺点是由于多次递归,费时,费内存,效率不高,需要大量栈空间来存储相邻的点,太大的区域会由于递归太深而无法运行。

为了减少递归次数,可采用扫描线种子算法。

扫描线填充算法就是它的改进的方法。

它是通过沿扫描线填充水平像素段,来处理四连通或八连通相邻点,这样就仅仅只需要将每个水平像素段的起始位置压入栈,
而不需要将当前位置周围尚未处理的相邻像素都压入栈,从而可以节省大量的栈空间。

相关文档
最新文档