算法原理:
种子元素入栈,如果栈不为空,执行以下三步:
(1)栈顶元素出栈
(2)按颜色绘制出栈元素
(3)按左,左上,上,右上,右,……八个方向顺序搜索与出栈像素相邻的像素,若该像素的颜色不是边界色,并且未被设置为填充色则入栈,否则丢弃。
实现:
MFC新建单文档工程Test,在TestView.h中的类定义中public中添加代码CPoint p[9];//定义多边形 CPoint seed;//种子 CPoint one,two,three,four,five,six,seven,eight;//邻接点 void Fill();//填充函数
TestView.cpp中加头文件
#include "Test.h"
#include<stack>
构造函数中初始化点p[0]=CPoint(300,300); p[1]=CPoint(401,300); p[2]=CPoint(401,201); p[3]=CPoint(500,201); p[4]=CPoint(500,100); p[5]=CPoint(400,100); p[6]=CPoint(400,200); p[7]=CPoint(300,200);
然后OnDraw函数中pDC->Polygon(p,8);//绘制多边形
然后实现Fill函数
void CTestView::Fill(){
CClientDC *dc;
dc=new CClientDC(this);
COLORREF fc,bc,pc;//填充色,边界颜色,像素点颜色
bc=RGB(0,0,0);//边界色为黑色
fc=RGB(0,0,255);//填充色为蓝色
CPoint head;
head=seed;
stack<CPoint> s;
s.push(head);
while(!s.empty())
{
CPoint base=s.top();//访问栈顶
s.pop();//栈顶元素出栈
dc->SetPixel(base,fc);
one.x=base.x-1;
one.y=base.y;
pc=dc->GetPixel(one.x,one.y);
if(pc!=bc&&pc!=fc)
{
s.push(one);
}
two.x=base.x-1;
two.y=base.y-1;
pc=dc->GetPixel(two.x,two.y);
if(pc!=bc&&pc!=fc)
{
s.push(two);
}
three.x=base.x;
three.y=base.y-1;
pc=dc->GetPixel(three.x,three.y);
if(pc!=bc&&pc!=fc)
{
s.push(three);
}
four.x=base.x+1;
four.y=base.y-1;
pc=dc->GetPixel(four.x,four.y);
if(pc!=bc&&pc!=fc)
{
s.push(four);
}
five.x=base.x+1;
five.y=base.y;
pc=dc->GetPixel(five.x,five.y);
if(pc!=bc&&pc!=fc)
{
s.push(five);
}
six.x=base.x+1;
six.y=base.y+1;
pc=dc->GetPixel(six.x,six.y);
if(pc!=bc&&pc!=fc)
{
s.push(six);
}
seven.x=base.x;
seven.y=base.y+1;
pc=dc->GetPixel(seven.x,seven.y);
if(pc!=bc&&pc!=fc)
{
s.push(seven);
}
eight.x=base.x-1;
eight.y=base.y+1;
pc=dc->GetPixel(eight.x,eight.y);
if(pc!=bc&&pc!=fc)
{
s.push(eight);
}
}
}
添加按下左键事件响应,初始化seed种子
步骤查看-》建立类向导-》Message-》WM_LBUTTONDOWN-Add Class
然后在TestView.cpp的以下函数中添加三行代码
void CTestView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
seed.x=point.x;//设置seed.x
seed.y=point.y;
Fill();//填充
CView::OnLButtonDown(nFlags, point);
}
总共要添加的代码就这六处