c - 这种洪水填充算法有什么问题?

标签 c algorithm graphics flood-fill

我一直在使用基于堆栈的非递归品种的洪水填充算法,它似乎工作得很好除了一种恼人的情况:如果使用一条线将图像切成两半,然后淹没一半,淹没整个图像!然而,只有当我不在图像周围放置“边框”时,才会发生这种情况。如果我绘制一个封装图像的矩形(即在图像上放置边框),那么它就可以正常工作。很明显,代码的边界查找方面存在问题,但我一生都找不到问题。 (希望)比我更敏锐的人能发现问题吗?这让我疯狂! (p.s语言是C)

/** scanfill algorithm **/
/* the stack */
#define stackSize 16777218
int stack[stackSize];
int stackPointer;

static bool
pop(int * x, int * y, int h) 
{ 
    if(stackPointer > 0) 
    { 
        int p = stack[stackPointer]; 
        *x = p / h; 
        *y = p % h; 
        stackPointer--; 
        return true; 
    }     
    else 
    { 
        return false;
    }    
}    

static bool
push(int x, int y, int h) 
{ 
    if(stackPointer < stackSize - 1) 
    { 
        stackPointer++; 
        stack[stackPointer] = h * x + y; 
        return true;
    }     
    else 
    { 
        return false;
    }    
}     

static void
emptyStack() 
{ 
    int x, y; 
    while(pop(&x, &y, 0)); 
}

void
scan_fill_do_action(int x, int y, texture_info * tex, VALUE hash_arg,
                sync sync_mode, bool primary, action_struct * payload)
{
    action_struct cur;
    rgba old_color;
    int y1;
    bool spanLeft, spanRight;

    if(!bound_by_rect(x, y, 0, 0, tex->width - 1, tex->height - 1)) return;

    draw_prologue(&cur, tex, 0, 0, 1024, 1024, &hash_arg, sync_mode, primary, &payload);

    old_color = get_pixel_color(tex, x, y);

    if(cmp_color(old_color, cur.color)) return;

    emptyStack();

    if(!push(x, y, tex->width)) return;

    while(pop(&x, &y, tex->width))
    {    
        y1 = y;
        while(y1 >= 0 && cmp_color(old_color, get_pixel_color(tex, x, y1))) y1--;
        y1++;
        spanLeft = spanRight = false;
        while(y1 < tex->height  && cmp_color(old_color, get_pixel_color(tex, x, y1)) )
            {
                set_pixel_color_with_style(payload, tex, x, y1);

                if(!spanLeft && x > 0 && cmp_color(old_color, get_pixel_color(tex, x - 1, y1))) 
                    {
                        if(!push(x - 1, y1, tex->width)) return;
                        spanLeft = true;
                    }
                else if(spanLeft && x > 0 && !cmp_color(old_color, get_pixel_color(tex, x - 1, y1)))
                    {
                        spanLeft = false;
                    }


                if(!spanRight && x < tex->width && cmp_color(old_color,
                                                                 get_pixel_color(tex, x + 1, y1))) 
                    {
                        if(!push(x + 1, y1, tex->width)) return;
                        spanRight = true;
                    }

                else if(spanRight && x < tex->width && !cmp_color(old_color,
                                                                      get_pixel_color(tex, x + 1, y1)))
                    {
                        spanRight = false;
                    } 
                y1++;
            }
    }
   draw_epilogue(&cur, tex, primary);
}

最佳答案

我只看了一眼,但看起来你有一个边界包裹

if(!spanRight && x < tex->width && ...

'和

else if(spanRight && x < tex->width && ...

这些行应为

   if(!spanRight && x < tex->width-1 && ...
   else if(spanRight && x < tex->width-1 && ...

关于c - 这种洪水填充算法有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1270243/

相关文章:

c/你期望什么行为,最佳实践,信号,线程,进程?

javascript - 从表达式中提取变量

graphics - 关于webgl中glBufferData第二个参数的疑问

c - 在库和 GUI 之间传递事件的有效方法是什么?

c - 从单链表中删除节点

java - 我如何得到一个图来估计我的算法的性能?

c++ - 切片网格的算法或软件

image - 查看.bin文件(YCbCr 4 :2:2 format)

c - 卡在有关数组和移动数字的代码上

ruby - 生成对象数组重复排列的过滤子集(给定长度 k)