求区域填充算法(100分)

  • 主题发起人 主题发起人 RJU
  • 开始时间 开始时间
R

RJU

Unregistered / Unconfirmed
GUEST, unregistred user!
求区域填充算法
现在有一个宽 Width 高 height的图,在里面任点一点,
要求以 AColor填充与此点相连的所有相同颜色点,就是填充相同颜色的区域。

哪位大侠有效率高的算法啊,谢谢。
 
高效的没有,一个点一个点的遍历吧!
这让我想到02年初写扫雷的时候,当用户点击一个周围没有一个地雷的方块时,自动翻开周围的方块的代码!
 
http://www.wanfangdata.com.cn/qikan/Periodical.Articles/fdxb/fdxb2000/0001/000117.htm
 
那个网站的文章要付费?
 
直接Fill就可以了啊,这么简单滴。
 
Fill 不行的,现在需要的是 算法

有没有人帮忙啊?
 
最快区域种子点填充算法

#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,&quot; &quot;);
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<<&quot;MAX=&quot;<<max+1;
getch();
// floodfill(100,150,12);
getch();
cout<<&quot; times&quot;<<times/CLK_TCK
<<&quot; NUMofPIXEL=&quot;<<num<<&quot; NUMofOVER=&quot;<<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<<&quot;stack overflow&quot;;
exit(2);
}

}
x=x+1; //继续处理当前扫描线
color=getpixel(x,y);
}
}
}
 
上面是当初写论文
http://www.wanfangdata.com.cn/qikan/Periodical.Articles/fdxb/fdxb2000/0001/000117.htm
时的试验、验证程序。
 
非常感谢,马上试
 
谢谢 arhaha. [:D]
 

Similar threads

后退
顶部