1

My goal was to create an efficient version of flood fill polygon filling algorithm. The code works correctly for filling rectangles but for some reason it jumps out of the circle while filling the South-East Pixels. Please check the output image of the leak here

The disadvantage of flood fill algorithm is that it does not work for really big shapes by causing a stack overflow because of many extra functions stored in the stack while recursively calling itself. TO overcome this, I have written this algorithm where I first fill all North,East,South and West pixels as they do not require the recursive function stack. Then, i call NorthEast, SouthEast , SouthWest and NorthWest pixels filling functions which make use of recursion stack. I have ensured that at any particular time, my recursion stack wont have more than 2 methods to avoid a stack overflow.

Please help me to fix the leak

#include<stdio.h>
#include<conio.h>
#include<graphics.h>
void northFill(int a,int b,int newcolor,int oldcolor){
    int current=getpixel(a,b);
    if(current==oldcolor){
        putpixel(a,b,newcolor);
        northFill(a,b+1,newcolor,oldcolor);
    }
}
void westFill(int a,int b,int newcolor,int oldcolor){
    int current=getpixel(a,b);
    if(current==oldcolor){
        putpixel(a,b,newcolor);
        westFill(a-1,b,newcolor,oldcolor);
    }
}
void southFill(int a,int b,int newcolor,int oldcolor){
    int current=getpixel(a,b);
    if(current==oldcolor){
        putpixel(a,b,newcolor);
        southFill(a,b-1,newcolor,oldcolor);
    }
}
void eastFill(int a,int b,int newcolor,int oldcolor){
    int current=getpixel(a,b);
    if(current==oldcolor){
        putpixel(a,b,newcolor);
        eastFill(a+1,b,newcolor,oldcolor);
    }
}
void northEastFill(int a,int b,int newcolor,int oldcolor){
    int current=getpixel(a,b);
    if(current==oldcolor){
        putpixel(a,b,newcolor);
        northFill(a,b+1,newcolor,oldcolor);
        eastFill(a+1,b,newcolor,oldcolor);
        northEastFill(a+1,b+1,newcolor,oldcolor);
    }
}
void southEastFill(int a,int b,int newcolor,int oldcolor){
    int current=getpixel(a,b);
    if(current==oldcolor){
        putpixel(a,b,newcolor);
        southFill(a,b-1,newcolor,oldcolor);
        eastFill(a+1,b,newcolor,oldcolor);
        southEastFill(a+1,b-1,newcolor,oldcolor);
    }
}
void northWestFill(int a,int b,int newcolor,int oldcolor){
    int current=getpixel(a,b);
    if(current==oldcolor){
        putpixel(a,b,newcolor);
        northFill(a,b+1,newcolor,oldcolor);
        westFill(a-1,b,newcolor,oldcolor);
        northWestFill(a-1,b+1,newcolor,oldcolor);
    }
}
void southWestFill(int a,int b,int newcolor,int oldcolor){
    int current=getpixel(a,b);
    if(current==oldcolor){
        putpixel(a,b,newcolor);
        southFill(a,b-1,newcolor,oldcolor);
        westFill(a-1,b,newcolor,oldcolor);
        southWestFill(a-1,b-1,newcolor,oldcolor);
    }
}
void fillPoint(int x,int y,int color){
    int pixelColor=getpixel(x,y);
    putpixel(x,y,color);
    northFill(x,y+1,color,pixelColor);
    eastFill(x+1,y,color,pixelColor);
    southFill(x,y-1,color,pixelColor);
    westFill(x-1,y,color,pixelColor);
    northEastFill(x+1,y+1,color,pixelColor);
    southEastFill(x+1,y-1,color,pixelColor);
    southWestFill(x-1,y-1,color,pixelColor);
    northWestFill(x-1,y+1,color,pixelColor);
}
void main(){
    int gd = DETECT , gm;
    int x,y;
    initgraph(&gd,&gm,"");
    circle(320,240,230);     //<- Doesnt work for this
    //rectangle(40,40,630,470); <-Works for this
    printf("Enter x,y: ");
    scanf("%d %d",&x,&y);
    fillPoint(x,y,GREEN);
    getch();
    closegraph();
}
genpfault
  • 51,148
  • 11
  • 85
  • 139
  • I don't see `circle`. How can we help without it? I don't see `getpixel`; how does your recursion terminate? – Paul Ogilvie Mar 03 '20 at 16:09
  • It doesn't look like your code handles the case where there's a different color to the south and a different color to the east when going south-east (similarly for other diagonal directions). It's hard to tell whether this is the problem from the image. – Kevin Mar 03 '20 at 16:09
  • Note: the compiler probably already optimizes your tail recursion to a loop. – Paul Ogilvie Mar 03 '20 at 16:11
  • Also, you don't need to worry about a stack overflow if you use a stack/queue data structure to track pixels to potentially fill and use a loop instead of recursion. – Kevin Mar 03 '20 at 16:12
  • 2
    Also... I don't think your code will fill a concave shape (such as an L shaped object) depending on where the fill starts. – Kevin Mar 03 '20 at 16:14
  • @PaulOgilvie I've used circle in void main() and getpixel for each filling function. – Yatharth Vyas Mar 03 '20 at 16:27
  • @Kevin I understood your point regarding the concave filling. Thanks , i will try to think over it. Also i use Turbo C++ to run my code and my college teacher told us that if we use regular flood fill algorithm for filling a big shape then it might cause a stack overflow due to many functions getting stored in the stack. Thats the reason why I attempted to implement this but i can make use of the stack data structure. Thanks again – Yatharth Vyas Mar 03 '20 at 16:31
  • 1
    You might notice at the "leak", two green pixels are touching diagonally. Your algorithm is doing what you told it to do, and going diagonally. Zoom in on the leak. Can you see it? – user253751 Mar 03 '20 at 16:39
  • @user253751 You are right, but is there any way to fix this? Any conditional statement? – Yatharth Vyas Mar 03 '20 at 16:42
  • @YatharthVyas Well, what do you want the code to do, if there are white pixels south and east but not southeast? – user253751 Mar 03 '20 at 17:12
  • 1
    @user253751 Actually i realised my issue and I'll try to solve it. Thanks a lot – Yatharth Vyas Mar 03 '20 at 17:38

0 Answers0