扫描线种子填充多边形算法实现(VC)
接着写那些狗血的算法,今天写的是扫描线种子填充的算法实现,还是老规矩,把算法封装成了一个函数,需要使用的话直接传参即可~
详细用法请看下面的使用说明,好累啊(修改别人的代码也不容易),不过看着这扫描线种子填充的算法为我所用,很是欣慰。
下面是在VS2008下的算法实现:
//××下面要进行的是扫描线种子填充的函数void S1GraphDbx::seedline(CPoint p,CDC *pDC)
{
//求多边形的最大最小值
int index=m_dbx.size();
int i;
COLORREF fill=RGB(255,0,0);
COLORREF boundary=RGB(0,0,0);
for (i=0;i<index;i++)
{
if (m_dbx.at(i).isSelect==1)
{
CPoint seed, newSeed;
int xLeft, xRight, x, y; //[xLeft, xRight]表示扫描线的区段,x,y表示当前的像素点左边
int needFill = FALSE;
my_Stack<CPoint>st;//自定义的栈
seed.x = p.x; //种子坐标
seed.y = p.y;
// 种子入栈
st.Add(seed);
while ( !st.IsEmpty() ) //栈非空
{
//* 种子出栈并给点上色
seed=st.Top();
st.Delete();
pDC->SetPixel(seed.x,seed.y,fill);
//* 填充当前扫描线位于种子左边的部分
x = seed.x - 1;
y = seed.y;
while ( pDC->GetPixel(x,y) != fill &&
pDC->GetPixel(x,y) != boundary )
{
pDC->SetPixel(x,y,fill);
x -= 1;
}
//* 记录最左侧的内点
xLeft = x + 1;
//* 填充当前扫描线位于种子右边的部分
x = seed.x + 1;
y = seed.y;
while ( pDC->GetPixel(x,y) != fill &&
pDC->GetPixel(x,y) != boundary )
{
pDC->SetPixel(x,y,fill);
x += 1;
}
///* 记录最右侧的内点
xRight = x - 1;
///* 上移一条扫描线
y = seed.y - 1;
x = xLeft;
//* 从左向右检测非边界、未填充的象素
while ( x < xRight )
{
while ( pDC->GetPixel(x,y) != fill &&
pDC->GetPixel(x,y) != boundary )
{
///* 存在未填充的像素,则需要填充
needFill = TRUE;
x += 1;
}
//* 最右侧像素入栈
if ( needFill == TRUE )
{
newSeed.x = x - 1;
newSeed.y = y;
st.Add(newSeed);
needFill = FALSE;
break;
}
x++;
}
needFill = FALSE;
///* 下移一条扫描线
y = seed.y + 1;
x = xLeft;
/////* 从左向右检测非边界、未填充的象素
while ( x < xRight )
{
while ( pDC->GetPixel(x,y) != fill &&
pDC->GetPixel(x,y) != boundary )
{
////* 存在未填充的像素,则需要填充
needFill = TRUE;
x += 1;
}
/////* 最右侧像素入栈
if ( needFill == TRUE )
{
newSeed.x = x - 1;
newSeed.y = y;
st.Add(newSeed);
needFill = FALSE;
break;
}
x++;
}
}
}
}
}
使用说明:
1.本例使用的源代码并非完全原创,收集于pudn、csdn等等。PS:累死我了~扫描线种子填充!2.参数说明,第一个CPoint p 为种子,第二个参数都懂的。
3.本例中是利用了我自己当初数据结构时写的栈,大家也可以使用系统自带的栈,使用系统栈的时候修改相应的函数,比如Add