最快区域种子点填充算法
#include <graphics.h>
#include <time.h>
#include <math.h>
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#define MaxDepth 50
struct stack{ //区段的信息结构
int xleft;
int xright;
int y;
}st[MaxDepth];
static int max=0;
long num=0;
long num1=0;
int TOP=-1;
void SeedFill(int ,int ,int,int);
void main()
{ //下面的数组均定义了一个区域,测试时仅需选一部分
// int mult[][2]={{10,10},{15,30},{30,1},{30,30},{100,30},{400,100},{600,100},{600,200},{500,400},{500,300},{100,300},{20,450},{10,10}};
// int mult[][2]={{50,50},{600,50},{600,470},{50,470},{50,50}};
// int mult[][2]={{10,10},{600,10},{600,400},{10,400},{10,10}};
// int mult[][2]={{10,10},{520,10},{520,340},{10,340},{10,10}};
// int mult[][2]={{2,53},{26,22},{26,54},{50,22},{50,42},{74,1},{74,43},{86,22},{86,53},{110,12},{110,43},{134,22},{134,53},{170,1},{170,84},{2,84},{2,53}};
// int mult[][2]={{34,30},{22,81},{46,81},{34,30}};
int mult[48][2];
int mode,dr=DETECT,i,j,k;
initgraph(&dr,&mode," "
;
setcolor(12);
int ind=170,outd=230;
double rad=2.0*3.1415926/24.0;
for(i=0;i<25;i++)
{
mult[2*i+1][0]=240+ind*cos(i*rad+rad/2.0);
mult[2*i+1][1]=240+ind*sin(i*rad+rad/2.0);
mult[2*i][0]=240+outd*cos(i*rad);
mult[2*i][1]=240+outd*sin(i*rad);
}
for(i=1;i<(sizeof(mult)/sizeof(int)/2);i++)
line(mult[i-1][0],mult[i-1][1],mult
[0],mult[1]);
line(mult[47][0],mult[47][1],mult[0][0],mult[0][1]);
// for(i=1;i<(sizeof(mult)/sizeof(int)/2);i++)
// line(4.5*mult[i-1][0]+10,4.5*mult[i-1][1]+10,4.5*mult[0]+10,4.5*mult[1]+10);
// circle(4.5*50+10,4.5*50+10,4.5*50);
// circle(4.5*75+10,4.5*54+10,4.5*15);
// circle(240,240,200);
getch();
// exit(1);
double times=clock();
SeedFill(240,467,12,11);
times=clock()-times;
gotoxy(20,1);
cout<<"MAX="<<max+1;
getch();
// floodfill(100,150,12);
getch();
cout<<" times"<<times/CLK_TCK
<<" NUMofPIXEL="<<num<<" NUMofOVER="<<num1;
getch();
}
void SeedFill(int x,int y,int bc,int nc)
//(x,y)为种子点,bc是边界色 ,nc是填充色 。
{
int xl,xr,yp,xpl,xpr,color;
TOP=-1;
color=x;
while(getpixel(x,y)!=bc) //向左填充,直到边界。
{
putpixel(x,y,nc);
num++;
x=x-1;
}
xl=x+1; //xl是左边界点
x=color+1;
while(getpixel(x,y)!=bc) //向右填充,直到边界。
{
putpixel(x,y,nc);
num++;
x=x+1;
}
xr=x-1; //xl是右边界点
TOP++;
st[TOP].xleft=xl; //左右边界点入栈。
st[TOP].xright=xr;
st[TOP].y=-(y-1); //上面相邻的扫描线有待填充搜索
TOP++;
st[TOP].xleft=xl;
st[TOP].xright=xr;
st[TOP].y=(y+1); //下面相邻的扫描线有待填充搜索
while(TOP!=-1) //主循环,直到堆栈为空
{
xpl=st[TOP].xleft;
xpr=st[TOP].xright;
yp=st[TOP].y;
TOP=TOP-1; //出栈
// num1++; //计算出栈的次数
y=abs(yp);
x=xpl; //从左端点开始搜索填充
color=getpixel(x,y);
while(x<=xpr) //直到右端点
{
while((color==bc||color==nc) && x<=xpr) //(x<=xpr不可少)
//排除边界点和已经填充了的点(对于多连通图形才可能发生)
{
x=x+1;
color=getpixel(x,y);
}
//找到新的区段或已经越界
if(x<=xpr)
{
xl=x;
if(x==xpl) //假如是左端点,则应该先向左搜索填充到新的左端点
{
while(color!=bc)
{
putpixel(x,y,nc);
x=x-1;
color=getpixel(x,y);
}
xl=x+1;
x=xpl+1;
color=getpixel(x,y);
}
while(color!=bc) //搜索,填充完当前段
{
putpixel(x,y,nc);
x=x+1;
color=getpixel(x,y);
}
xr=x-1;
TOP++; //新的区段入栈
st[TOP].xleft=xl;
st[TOP].xright=xr;
st[TOP].y=yp+1;
if(xl<xpl-1) // 此时才需要搜索当前段的上面的扫描线的超长部分
{
TOP++;
st[TOP].xleft=xl;
st[TOP].xright=xpl-2;
st[TOP].y=-(yp-1);
}
if(xr>xpr+1) // 此时才需要搜索当前段的下面的扫描线的超长部分
{
TOP++;
st[TOP].xleft=xpr+2;
st[TOP].xright=xr;
st[TOP].y=-(yp-1);
}
if(TOP>max)max++; //堆栈深度过深
if(TOP>=MaxDepth)
{
cout<<"stack overflow";
exit(2);
}
}
x=x+1; //继续处理当前扫描线
color=getpixel(x,y);
}
}
}