2009-08-13 7 views
2

J'ai utilisé un algorithme de remplissage de type non-récursif basé sur pile et il semble fonctionner parfaitement excepté pour une situation ennuyante: si vous utilisez une ligne pour couper une image en deux et ensuite remplir une moitié, cela inonde toute l'image! Cela ne se produit cependant que lorsque je ne place pas de «bordures» autour de l'image. Si je dessine un rectangle qui encapsule l'image (c'est-à-dire met des bordures sur l'image) alors cela fonctionne bien. Donc, évidemment, il y a quelque chose qui ne va pas avec l'aspect de la recherche de limites du code, mais je ne peux pas pour la vie de moi trouver le problème. Quelqu'un peut-il (avec un peu de chance) un œil plus clair que moi repérer le problème? ça me rend fou! (Ps la langue est C)Quel est le problème avec cet algorithme de remplissage?

/** 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); 
} 
+0

l'avez-vous résolu? Parce que c'est mon problème maintenant! – Farsheed

Répondre

3

Je n'ont seulement un court coup d'œil, mais il semble que vous avez une enveloppe limite à

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

'et

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

Le lignes devraient lire

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

j'ai déjà essayé ceci :(et il n'a pas résolu le problème: (( – horseyguy

Questions connexes