Wypełnianie po brzegi polega na zamalowaniu wszystkich pikseli ograniczone przez pewne obramowanie (lub ograniczone krawędzią obrazu). Do tego potrzebny jest pewien punkt początkowy. Na stronie zostanie wyjaśnione jak napisać i wykorzystać taki algorytm.
Do rozpoczęcia procesu zamalowywania algorytm potrzebuje punktu początkowego (x, y), kolor obramowania oraz docelowy kolor na który zostaną zamalowane piksele. Następnie zamalowywanie piksela polega na sprawdzeniu czy nie jest koloru obramowania lub docelowego i jeśli warunek jest spełniony to jest zamalowywany, a proces jest powtarzany dla wszystkich jego sąsiadów.
Przypuśćmy, że dany jest obrazek opisany macierzą opisaną poniżej. Zadanie polega na zamalowaniu wszystkich pikseli ograniczonych wartością 0 na kolor 3 rozpoczynając od punktu (3, 2).
1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
1 | 1 | 0 | 0 | 0 | 4 | 0 | 0 |
1 | 0 | 2 | 2 | 2 | 4 | 4 | 0 |
1 | 0 | 2 | 2 | 2 | 4 | 4 | 0 |
1 | 1 | 0 | 2 | 2 | 4 | 0 | 1 |
1 | 1 | 1 | 0 | 0 | 0 | 1 | 1 |
Pierwszy krok polega na zamalowaniu punktu początkowego, a następnie zamalowywaniu kolejnych sąsiadów, sąsiadów sąsiadów.. itd.
1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
1 | 1 | 0 | 0 | 0 | 4 | 0 | 0 |
1 | 0 | 2 | 3 | 2 | 4 | 4 | 0 |
1 | 0 | 2 | 2 | 2 | 4 | 4 | 0 |
1 | 1 | 0 | 2 | 2 | 4 | 0 | 1 |
1 | 1 | 1 | 0 | 0 | 0 | 1 | 1 |
Końcowy efekt działania algorytmu wygląda jak poniżej:
1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
1 | 1 | 0 | 0 | 0 | 3 | 0 | 0 |
1 | 0 | 3 | 3 | 3 | 3 | 3 | 0 |
1 | 0 | 3 | 3 | 3 | 3 | 3 | 0 |
1 | 1 | 0 | 3 | 3 | 3 | 0 | 1 |
1 | 1 | 1 | 0 | 0 | 0 | 1 | 1 |
Jak można zauważyć obydwa kolory: 2 i 4, które były ograniczone przez czarny kolor 0 zostały zamalowane na ten sam kolor docelowy 3.
Algorytm wypełniania po brzegi działa na podobnej zasadzie jak algorytm wypełnianie przez podtapianie. Wykorzystują rekurencję otrzymuje się algorytm o bardzo wysokiej złożoności. W obu algorytmach ten sam piksel jest odwiedzany wielkokrotnie (choć zamalowany zostaje tylko raz).
Poniższa funkcja WypelnijMacierz(), która w macierzy dane zamienia wszystkie piksele ograniczone kolor obramowanie na nowy. Algorytm rozpoczyna zamalowywanie od punktu (x, y).
Przed pomalowaniem punktu są sprawdzane trzy warunki: czy punkt wogle istnieje, czy kolor jest różny od koloru obramowania oraz docelowego koloru. Jeśli warunek jest spełniony to punkt zostaje pomalowany, a algorytm rekurencyjnie wykonany dla jego sąsiadów.
Przetestowanie kodu jest możliwe dzięki poniższemu fragmentowi programu:
Oto przykładowa macierz obrazku podana na początku artykułu:
Napisz rekurencyjny algorytm, który będzie zamalowywał sąsiednie pola we wszystkich ośmiu kierunkach (czyli prócz punktów stykających się krawędziami to jeszcze te z którymi tylko rogami) zgodnie z zasadą zamalowywania po brzegi.
Jak będzie wyglądać obrazek po zamalowaniu jeśli wybierzemy dowolne pole prócz wybranego obramowanie o kolorze 0?
1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
1 | 1 | 0 | 0 | 0 | 4 | 0 | 0 |
1 | 0 | 2 | 2 | 2 | 4 | 4 | 0 |
1 | 0 | 2 | 2 | 2 | 4 | 4 | 0 |
1 | 1 | 0 | 2 | 2 | 4 | 0 | 1 |
1 | 1 | 1 | 0 | 0 | 0 | 1 | 1 |
Macierz będzie wyglądać następująco:
3 | 3 | 3 | 3 | 3 | 0 | 3 | 3 |
3 | 3 | 0 | 0 | 0 | 3 | 0 | 0 |
3 | 0 | 3 | 3 | 3 | 3 | 3 | 0 |
3 | 0 | 3 | 3 | 3 | 3 | 3 | 0 |
3 | 3 | 0 | 3 | 3 | 3 | 0 | 3 |
3 | 3 | 3 | 0 | 0 | 0 | 3 | 3 |
Brzegi zamalowywanego obszaru mają dużo "dziur". Nie sprawiają one problemu, gdy algorytm przechodzi jedynie po sąsiednich polach, które stykają się z aktualnym polem krawędzią. W tym przypadku problem należałoby rozwiązać robiąc grubsze obramowanie.