此递归洪水填充实施的终止条件是什么?

时间:2018-07-29 18:11:05

标签: c recursion sdl flood-fill

我设置了一个递归泛洪填充算法,该算法由于达到(我认为)堆栈溢出/递归深度而保持段错误。我不想弄乱堆栈限制,并且创建这种特定算法的迭代版本超出了我的技术水平。因此,我只希望函数在经过这么多次循环后停止,因此它只会安全地填充较小的区域。

我创建了一个测试程序来处理终止条件的实现,但是我注意到尽管完成了工作,该功能仍在运行。例如,在下面的代码中,让它运行200,000次可以正确填充窗口,但300,000窗口也可以正确填充,当我让它运行400,000次时,它可以安全地在337977处停止循环。因此,我对于到底在什么时候将其停止在337977上以及如何使它停止在我可以用眼睛看到的洪水填充的实际末端感到困惑,不到200,000个循环。

#include <stdio.h>
#include <SDL2/SDL.h>
Uint32 myPixelColour(Uint32 *pixels, int x, int y, int windowWidth, int windowHeight)
{

    Uint32 thisPixelColour = 0;
    thisPixelColour = pixels[x + y * windowWidth];
    return thisPixelColour;
}

int mySameColour(Uint32 thisPixelColour, Uint32 thatPixelColour)
{
    return (thisPixelColour == thatPixelColour);
}

void myFill(Uint32 *pixels, int windowWidth, int windowHeight, int x, int y, Uint32 finColour, int *counter)
{
    if(!((x>=0) && (x<windowWidth) && (y>=0) && (y<windowHeight))) return;
    if(*counter == 400000) return;  /* 200000 fills the window, so does 300000 */
    printf("%d\n", *counter);
    *counter = *counter + 1;

    Uint32 ogColour = myPixelColour(pixels, x, y, windowWidth, windowHeight);
    if(mySameColour(ogColour, finColour)) return;
    pixels[x+y*windowWidth] = finColour;

    myFill(pixels, windowWidth, windowHeight, x, y+1, finColour, counter);
    myFill(pixels, windowWidth, windowHeight, x-1, y, finColour, counter);
    myFill(pixels, windowWidth, windowHeight, x, y-1, finColour, counter);
    myFill(pixels, windowWidth, windowHeight, x+1, y, finColour, counter);
}

int main(void)
{
    const int windowWidth = 400;
    const int windowHeight = 212;
    int counter;
    counter = 1;

    SDL_Window *window = SDL_CreateWindow("WindowTitle", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, windowWidth, windowHeight, SDL_WINDOW_SHOWN);
    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
    SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, windowWidth, windowHeight);

    Uint32 *pixels = NULL;
    pixels = (Uint32 *) malloc (sizeof(Uint32)*(Uint32)windowWidth*(Uint32)windowHeight);
    memset(pixels, 255, (Uint32)windowWidth*(Uint32)windowHeight*sizeof(Uint32));

    Uint32 finColour = 0x99FFCC;

    SDL_Point mouse_position;
    int success = 1;
    while(success)
    {
        SDL_Event userAction;

        SDL_GetMouseState(&mouse_position.x, &mouse_position.y);

        SDL_UpdateTexture(texture, NULL, pixels, (int)((Uint32)windowWidth * sizeof(Uint32)));

        while(SDL_PollEvent(&userAction))
        {
            switch(userAction.type)
            {
                case SDL_QUIT: success = 0; break;
                case SDL_KEYDOWN:
                    if(userAction.key.keysym.sym == SDLK_f)
                    {
                        myFill(pixels, windowWidth, windowHeight, 1, 1, finColour, &counter);
                    }
                    break;
            }
        }

        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, texture, NULL, NULL);
        SDL_RenderPresent(renderer);
    }
    free(pixels);
    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    return 0;
}

0 个答案:

没有答案