扫描线种子填充

 

扫描线种子填充算法的基本过程如下:当给定种子点(x, y)时,首先分别向左和向右两个方向填充种子点所在扫描线上的位于给定区域的一个区段,同时记下这个区段的范围[xLeft, xRight],然后确定与这一区段相连通的上、下两条扫描线上位于给定区域内的区段,并依次保存下来。反复这个过程,直到填充结。

扫描线种子填充算法可由下列四个步骤实现:

(1) 初始化一个空的栈用于存放种子点,将种子点(x, y)入栈;

(2) 判断栈是否为空,如果栈为空则结束算法,否则取出栈顶元素作为当前扫描线的种子点(x, y),y是当前的扫描线;

(3) 从种子点(x, y)出发,沿当前扫描线向左、右两个方向填充,直到边界。分别标记区段的左、右端点坐标为xLeft和xRight;

(4) 分别检查与当前扫描线相邻的y - 1和y + 1两条扫描线在区间[xLeft, xRight]中的像素,从xLeft开始向xRight方向搜索,若存在非边界且未填充的像素点,则找出这些相邻的像素点中最右边的一个,并将其作为种子点压入栈中,然后返回第(2)步;

这个算法中最关键的是第(4)步,就是从当前扫描线的上一条扫描线和下一条扫描线中寻找新的种子点。并只检查新扫描线上区间[xLeft, xRight]中的像素

void fill(int x,int y,COLORREF color)
{
    std::stack<Point>s;
    s.push(Point(x,y));
    while(!s.empty())
    {
        Point seed=s.top();
        s.pop();
        putPixel(seed.x,seed.y,color);
        //左右填充
        int x1=seed.x-1,x2=seed.x+1;
        while(getColor(x1,seed.y)!=borderColor&&getColor(x1,sedd.y)!=color)
        {
            putPixel(x1,seed.y,color);
            x1--;
        }
        while(getColor(x2,seed.y)!=borderColor&&getColor(x2,sedd.y)!=color)
        {
            putPixel(x2,seed.y,color);
            x2++;
        }
        int left1=x1,right1=x2,
            left2=left1,right2=right1;
        //上下扫描
        bool findNewSeed=false;//处理无效点
        while(left1<=right1)
        {
            if(findNewSeed && (getColor(left1,seed.y-1)==borderColor || getColor(left1,sedd.y-1)==color)){
                s.push(Point(left1-1,seed.y-1));
                findNewSeed=false;
            }
            else if(!findNewSeed)
                findNewSeed=true;
            if(findNewSeed && left1==right1)
                s.push(Point(left1,seed.y-1);
            left1++;
        }
        findNewSeed=false;//处理无效点
        while(left2<=right2)
        {
            if(findNewSeed && (getColor(left2,seed.y+1)==borderColor || getColor(left2,sedd.y+1)==color)){
                s.push(Point(left2-1,seed.y+1));
                findNewSeed=false;
            }
            else if(!findNewSeed)
                findNewSeed=true;
            if(findNewSeed && left2==right2)
                s.push(Point(left2,seed.y+1);
            left2++;
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值