线性扫描+种子填充算法 实现区域填充

来源:互联网 发布:古汉语 知乎 编辑:程序博客网 时间:2024/05/16 19:24

 学习计算机图形学,老师留给我的一个作业:实现种子填充算法。

     之前按书上讲的的种子填充(先填充一个点,再扫描这个种子点的4个方向的点,判断填充,然后递归),这种

在数学上是可行的方法,在实现中却有了问题,就是填充区过大的话,回使程序停止,问了CSDN上的朋友,说是递归过深。

书上还有一种方法是线性扫描的方法来实现填充,我看了下,蛮复杂的(不要砸我)。于是想了半天,就用两种方法结合起来试试。

方法如下:

用户在窗口客户区点击鼠标,将些时获得鼠标的坐标做为种子点,调用填充算法,实现填充。

种子填充算法:

(1)得到种子点后,如果种子点为旧色,则将这一点设为新色,并向右填充至边界(xmax)。些时效果如下:

 

(2)      然后从种子点向左填充,至边界(xmin)。效果如下:

(3)扫描这条线的上面和下面的点,如果有旧色,则将旧色做为新的种子点,递归调用自己,重复(1)、(2),直至填充完成。

实现如下:

void CGraphfillView::floodefill(int x, int y, int oldcolor, int newcolor)
{   CDC* pDC=GetDC();
    
int
 xmax,xmin,yy1,yy2;
    xmax
=x;xmin=x;yy1=y;yy2=
y;
    
//CDC* pDC;

    if(pDC->GetPixel(x,y)==oldcolor)
        
{
            
while(pDC->GetPixel(x,y)==
oldcolor)
            
{
                pDC
->
SetPixel(x,y,newcolor);
                x
++
;
            }

            xmax
=x;
            x
=xmin-1
;
            
while(pDC->GetPixel(x,y)==
oldcolor)
            
{
                pDC
->
SetPixel(x,y,newcolor);
                x
--
;
            }
;
            xmin
=x+1
;
            
for(int i=xmin;i<xmax;i++
)
            
{
                
if(pDC->GetPixel(i,y+1)==
oldcolor)
                    floodefill(i,y
+1
,oldcolor,newcolor);
                
if(pDC->GetPixel(i,y-1)==
oldcolor)
                    floodefill(i,y
-1
,oldcolor,newcolor);
            }
 
        }

}


 

效果如下: