种子填充算法相比较扫描线填充算要容易的多了。理解起来也很简单。
源码下载:点我下载哦
简单的说一下算法的原理:
种子填充算法都是进行区域填充的,而且一般都是指定给某个区域填充某种颜色。然后给出区域的范围,让种子在区域中任选一点,然后按照“4-联通算法”和“8-联通算法”进行填充,而区域填充算法分为区域填充的递归算法和区域填充的扫描线算法。
种子填充算法:
首先填充种子点所在扫描线上的位于给定区域的一个区段;
然后确定与这一区段相连通的上、下两条扫描线上位于给定区域内的区段,并依次保存下来;
反复这个过程,直到填充结束。
(1) 初始化:堆栈置空。将种子点(x,y)入栈。
(2) 出栈:若栈空则结束。否则取栈顶元素(x,y),以y作为当前扫描线。
(3) 填充并确定种子点所在区段:从种子点(x,y)出发,沿当前扫描线向左、右两个方向填充,直到边界。分别标记区段的左、右端点坐标为xl和xr。
(4) 并确定新的种子点:在区间[xl,xr]中检查与当前扫描线y上、下相邻的两条扫描线上的象素。若存在非边界、未填充的象素,则把每一区间的最右象素作为种子点压入堆栈,返回第(2)步。
上述算法对于每一个待填充区段,只需压栈一次;因此,扫描线填充算法提高了区域填充的效率。
算法的效果图如下:
首先创建了一个坐标的结构体Seed和相关的函数。
-
class ScanLineFill
-
{
-
public:
-
typedef struct
-
{
-
int x;
-
int y;
-
}Seed;
-
stack<Seed>Myseed;
-
void ScanLineFill4(int x,int y,COLORREF oldcolor,COLORREF newcolor,CDC *pDC,HDC hdc);
-
ScanLineFill();
-
virtual ~ScanLineFill();
-
};
然后给出核心的算法:
-
ScanLineFill::ScanLineFill()
-
{
-
while(!Myseed.empty())
-
{
-
Myseed.pop();
-
}
-
}
-
ScanLineFill::~ScanLineFill()
-
{
-
}
-
void ScanLineFill::ScanLineFill4(int x,int y,COLORREF oldcolor,COLORREF newcolor,CDC *pDC,HDC hdc)
-
{
-
int xl,xr;
-
bool spanNeedFill;
-
Seed pt;
-
pt.x=x;
-
pt.y=y;
-
Myseed.push(pt);
-
while(!Myseed.empty())
-
{
-
pt=Myseed.top();
-
Myseed.pop();
-
y=pt.y;
-
x=pt.x;
-
while(GetPixel(hdc,x,y)==oldcolor)
-
{
-
pDC->SetPixel(x,y,newcolor);
-
x++;
-
}
-
xr=x-1;
-
x=pt.x-1;
-
while(GetPixel(hdc,x,y)==oldcolor)
-
{
-
pDC->SetPixel(x,y,newcolor);
-
x--;
-
}
-
xl=x+1;
-
x=xl;
-
y=y+1;
-
while(x<=xr)
-
{
-
spanNeedFill=false;
-
while(GetPixel(hdc,x,y)==oldcolor)
-
{
-
spanNeedFill=true;
-
x++;
-
}
-
if(spanNeedFill)
-
{
-
pt.x=x-1;
-
pt.y=y;
-
Myseed.push(pt);
-
spanNeedFill=false;
-
}
-
while(GetPixel(hdc,x,y)!=oldcolor&&x<=xr)
-
x++;
-
}
-
x=xl;
-
y=y-2;
-
while(x<=xr)
-
{
-
spanNeedFill=false;
-
while(GetPixel(hdc,x,y)==oldcolor)
-
{
-
spanNeedFill=true;
-
x++;
-
}
-
if(spanNeedFill)
-
{
-
pt.x=x-1;
-
pt.y=y;
-
Myseed.push(pt);
-
spanNeedFill=false;
-
}
-
while(GetPixel(hdc,x,y)!=oldcolor&&x<=xr)
-
x++;
-
}
-
}
-
DeleteDC(hdc);
-
}
算法还是很简单的,主要了解算法的主要工作原理。
然后该打的说一下源码的使用:
1.点击“种子的填充算法”,
2.点击“开始”,在网格中点击那个点,虽然线会自己连接起来,但是最后一个点不要和第一个点试图进行连接,点击“停止”会自动换链接。
3.点击种子颜色进行种子的颜色选择,并按照提示在多边形区域内点击一个点。作为种子。
4.点击“Move”算法边运行起来。