Algorytm Bresenhama rysowania linii
Algorytm Bresenhama rysujący linię i bazujący na współrzędnych jej początku (x1,y1) i końca (x2,y2) można podzielić na pięć fragmentów:
przygotowanie danych do rysowania,
rysowanie linii poziomej,
rysowanie linii pionowej,
(1)
rysowanie linii, dla której spełniony jest warunek:
,
(2)
rysowanie linii, dla której spełniony jest warunek:
.
Każde uruchomienie procedury powoduje narysowanie linii poprzez jeden z fragmentów 2-5. Punkty 2,3 nie wymagają specjalnego wyjaśnienia. Powinien wystarczyć komentarz zamieszczony obok kodu źródłowego. Wyjaśnienia mogą wymagać punkty 4,5. W niniejszej instrukcji szczegółowo zostanie omówiony przypadek 4. Przypadek 5 jest analogiczny do 4. Załóżmy, że na rysunku 1 zaprezentowano w powiększeniu fragment ekranu monitora. Szara siatka reprezentuje układ pikseli. Każdy piksel reprezentowany jest przez kwadrat o boku
2 cm, ograniczony ciągłą linią. Środek każdego piksela wyznacza punkt będący przecięciem linii przerywanych. Przykładowe środki pikseli znaczone na rysunku to punkty: A0, Ai-1, Ai, Bi-1, Bi, An. Zadanie algorytmu to narysowanie linii od piksela A0 = (x0, y0) do piksela
An = (xn, yn). Na rysunku czerwonym kolorem narysowano linię o początku w punkcie
A0 = (x1, y1) i końcu w punkcie An = (xn, yn). Linia ta reprezentuje pewien wzorzec do którego powinien dążyć algorytm. Niestety, ze względu na dość duże rozmiary pikseli, w prezentowanym przykładzie, rysowana przez algorytm linia będzie jedynie pewnym „dalece niedoskonałym” przybliżeniem linii czerwonej. Na starcie algorytm zapali piksel A0 następnie w każdym następnym kroku i będzie zapalał ten piksel spośród Ai i Bi, którego środek znajduje się bliżej czerwonej linii.
Załóżmy, że w kroku i-1 zapalono piksel Ai-1. Na rysunku 1 zapalony piksel wypełniono kolorem szarym.
W kroku i algorytm podejmie decyzję co do wyboru następnego piksela.
Jeżeli d(Ai, Li) ≤ d(Bi, Li) to zostanie zapalony piksel Ai. W przeciwnym wypadku tzn.
d(Ai, Li) > d(Bi, Li) zostanie zapalony piksel Bi.
Przyjmując odległość euklidesową można napisać:
(3)
Po opuszczeniu modułów i uporządkowaniu mamy:
(4)
Wykorzystując z (4) można napisać następujące równanie:
(5)
Mnożąc obie strony ostatniego równania przez
otrzymujemy:
(6)
Po podstawieniu
otrzymujemy:
Wartość di można traktować jako kryterium wyboru punktu w kroku i.
(7)
(8)
(9)
(10)
(11)
(12)
Inaczej formułę (7) można zapisać następująco:
Zwiększając formalnie indeksy o 1 otrzymujemy:
Odejmując od równania (9) równanie (8) otrzymujemy związek między kryteriami wyboru w krokach: i oraz i+1:
Ponieważ
to ostatnie równanie można zapisać prościej:
Na podstawie powyższych rozważań można zapisać sposób postępowania algorytmu w ogólnym przypadku:
Jeżeli
(d(Ai, Li) > d(Bi, Li) ) to algorytm wybiera punkt Bi. Wtedy
. Stąd i z (11) mamy:
Jeżeli
(d(Ai, Li) ≤ d(Bi, Li) ) to algorytm wybiera punkt Ai. Wtedy
. Stąd i z (11) mamy:
(13)
Najpierw algorytm zapala punkt A0. Następnie przyjmując, że (x0, y0) = (0, 0) oraz wykorzystując (8) otrzymujemy kryterium w kroku i = 0:
(14)
Schemat algorytmu w ogólnym przypadku:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Rysunek 1 Ilustracja zasady działania algorytmu Bresenhama.
Teraz algorytm Bresenhama zostanie zaprezentowany na przykładzie zilustrowanym na rysunku 2:
Krok 0:
Zapalenie piksela A0
Krok 1:
Ponieważ d1 < 0, to zapalenie piksela A1.
Krok 2:
Ponieważ d2 < 0, to zapalenie piksela A2.
Krok 3:
Ponieważ d3 < 0, to zapalenie piksela A3.
Krok 4
Ponieważ d4 > 0, to zapalenie piksela B4.
Krok 5:
Ponieważ d5 < 0, to zapalenie piksela A5.
Krok 6:
Ponieważ d6 < 0, to zapalenie piksela A6.
Krok 7:
Ponieważ d7 < 0, to zapalenie piksela A7.
Krok 8:
Ponieważ d8 < 0, to zapalenie piksela A8.
Krok 9:
Ponieważ d9 < 0, to zapalenie piksela A9.
Krok 10:
Ponieważ d10 < 0, to zapalenie piksela A10.
Krok 11:
Ponieważ d11 < 0, to zapalenie piksela A11.
Krok 12:
Ponieważ d12 > 0, to zapalenie piksela B12.
Krok 13:
Ponieważ d13 > 0, to zapalenie piksela A13.
Krok 14:
Ponieważ d14 > 0, to zapalenie piksela A14.
Krok 15:
Ponieważ d15 > 0, to zapalenie piksela A15.
KONIEC
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Rysunek 2 Przykład sposobu działania algorytmu Bresenhama
Krok 0:
Zapalenie piksela (x0, y0) i wyliczenie d1 ze wzoru (14)
Krok i-ty:
Dla kryterium di obliczonego w poprzednim kroku
Jeżeli di >0 to wybór punktu
i obliczenie
ze wzoru (12).
Jeżeli di ≤0 to wybór punktu
i obliczenie
ze wzoru (13).
0 1 2 3 4 5 6 7
Ai-1=(xi-1, yi-1)
Ai=(xi-1+1, yi-1)
A0=(x0,y0)
Bi-1
Bi=(xi-1+1, yi-1+1)
Li-1
0
1
2
An=(xn,yn)
Li
A1
A2
A3
A4
A0=(x0,y0)
A5
A6
A7
A8
A9
A10
A11
A12
B1
B2
B3
B4
A13
A14
A15=(x15,y15)
B5
B6
B7
B8
B9
B10
B11
B12
B13
B15
L1
L2
L3
L4
L5
L6
L7
L8
L9
L10
L11
L12
L13
L14
B14
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0
1
2
3
4
5