ЧЕТЫРЕХсвязное заполнение области
От: Reunion  
Дата: 19.01.05 07:12
Оценка:
Всем привет!

Может быть у кого-нибудь есть или кто-нибудь где-нибудь видел нормальную реализацию ЧЕТЫРЕХсвязного заполнения области, заданной либо цветом границы, либо цветом области — без разницы (область может иметь дырки, большая — т.е. рекурсивный FloodFill не подайдет)? Очень нуно! Скорость не важна. А вот объем кода желательно поменьше.

Вот есть хороший алгоритм — но он ВОСЬМИсвязный (взят с codeproject). Как бы из него сделать ЧЕТЫРЕХсвязный...

// Fill background with given color
extern int nMinX, nMaxX, nMinY, nMaxY;
void LineFill_3(int x1, int x2, int y, 
        COLORREF fill_color, COLORREF seed_color)
{
    int xL,xR;
    if( y < nMinY || nMaxY < y )
        return;
    for( xL = x1; xL >= nMinX; --xL ) { // scan left
        if( GetPixel(xL,y) != seed_color )
            break;
        SetPixel(xL,y,fill_color);
    }
    if( xL < x1 ) {
        LineFill_3(xL, x1, y-1, fill_color, seed_color); // fill child
        LineFill_3(xL, x1, y+1, fill_color, seed_color); // fill child
        ++x1;
    }
    for( xR = x2;  xR <= nMaxX; ++xR ) { // scan right
        if( GetPixel(xR,y) !=  seed_color )
            break;
        SetPixel(xR,y,fill_color);
    }
    if(  xR > x2 ) {
        LineFill_3(x2, xR, y-1, fill_color, seed_color); // fill child
        LineFill_3(x2, xR, y+1, fill_color, seed_color); // fill child
        --x2;
    }
    for( xR = x1; xR <= x2 && xR <= nMaxX; ++xR ) {  // scan betweens
        if( GetPixel(xR,y) == seed_color )
            SetPixel(xR,y,fill_color);
        else {
            if( x1 < xR ) {
                // fill child
                LineFill_3(x1, xR-1, y-1, fill_color, seed_color);
                // fill child
                LineFill_3(x1, xR-1, y+1, fill_color, seed_color);
                x1 = xR;
            }
            // Note: This function still works if this step is removed.
            for( ; xR <= x2 && xR <= nMaxX; ++xR) { // skip over border
                if( GetPixel(xR,y) == seed_color ) {
                    x1 = xR--;
                    break;
                }
            }
        }
    }
}

void SeedFill_3(int x, int y, COLORREF fill_color)
{
    COLORREF seed_color = GetPixel(x,y);
    if( fill_color != seed_color )
        LineFill_3(x,x,y,fill_color,seed_color);
}



Заранее спасибо.
Re: ЧЕТЫРЕХсвязное заполнение области
От: DareDevil Грузия  
Дата: 21.01.05 13:40
Оценка:
Здравствуйте, Reunion, Вы писали:

R>Всем привет!


R>Может быть у кого-нибудь есть или кто-нибудь где-нибудь видел нормальную реализацию ЧЕТЫРЕХсвязного заполнения области, заданной либо цветом границы, либо цветом области — без разницы (область может иметь дырки, большая — т.е. рекурсивный FloodFill не подайдет)? Очень нуно! Скорость не важна. А вот объем кода желательно поменьше.


Уважаемы Reunion задачи подобного рода (заполнение области ) решаются и с помошью "волны" однако при этом приходится выделять не хилую памать (всё от конкретной задачи зависит конечно в общем случае порядка кол-ва точек области хотя при конкретных областях это может быть соизмеримо с периметром,поверхностью, области) под реализацию буфера для алгоритма
По этому алгоритму просматривается каждаия точка 4 раза в отличии от рекурсии в которой она рассматривается на несколько порядков больше раз (всё от реализации рекурсии зависит)
Реализация заливки "волной" производит операций порядка 4*N где N кол-во точек в области

залить область размерами 10,000 X 10,000 с процессором 1000МГц можно за 1~10с всё от качества реализации алгоритма и от конкретной области зависит

Описание реализации можеш найти во многих учебниках по програмированию (в разделе "динамическое решени задач" оно после "рекурсивного решения задач" всегда рассматривается как альтернатива рекурсии)
я не буду щас рассказывать что это за метод такой
там в книге будут обясняться на примерах так что оттуда ты лучше поймёш за метод

P.S. Если найду в интернете рессурс ,приличный, посвящённый этому вопросу опублекую в этой ветке
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.