Algorytm Bresenhama
Algorytm Bresenhama służy do rasteryzacji krzywych płaskich, czyli do jak najlepszego ich obrazowania na siatce pikseli. Jack Bresenham w 1965 roku opracował metodę rasteryzacji odcinków, którą następnie przystosowano do rysowania obiektów innego rodzaju (okręgów czy elips).
Siła algorytmu tkwi w prostocie; koszt postawienia jednego piksela to porównanie i jedno dodawanie (dla odcinków) lub porównanie i dwa dodawania (dla okręgów i elips), ponadto algorytm wykonuje obliczenia na liczbach całkowitych, które są bardzo szybkie na wszystkich mikroprocesorach.
Metoda pozwala w bardzo prosty sposób wybierać, które piksele leżą najbliżej rasteryzowanego obiektu (np. odcinka). Zakładając, że poprzednio algorytm zapisał piksel o współrzędnych w kolejnym kroku algorytm może zapisać piksel albo (ruch poziomy), albo (ruch ukośny) – wybór determinuje znak tzw. zmiennej decyzyjnej, której wartość jest po każdym kroku aktualizowana. Aktualizacja polega na dodaniu pewnych wartości, będących w przypadku odcinka stałymi, zaś dla okręgu i elipsy wartościami zmieniającymi się z każdym krokiem:
- D = zmienna decyzyjna
- = przyrost D przy ruchu w lewo
- = przyrost D przy ruchu ukośnym
- = przyrost przy ruchu w lewo (dla odcinka = 0)
- = przyrost przy ruchu w lewo (dla odcinka = 0)
- = przyrost przy ruchu ukośnym (dla odcinka = 0)
- = przyrost przy ruchu ukośnym (dla odcinka = 0)
- powtarzaj
- zapisz piksel
- jeśli
- – ruch w lewo
- – aktualizacja zmiennej decyzyjnej
- – aktualizacja parametrów pomocniczych
- – aktualizacja parametrów pomocniczych
- w przeciwnym razie
- – ruch ukośny
- – aktualizacja zmiennej decyzyjnej
- – aktualizacja parametrów pomocniczych
- – aktualizacja parametrów pomocniczych
Algorytm konwersji odcinka
[edytuj | edytuj kod]Założenia
[edytuj | edytuj kod]- Kąt pomiędzy styczną a osią OX, nie może przekraczać 45 stopni,
- Krzywa musi być nierosnąca albo niemalejąca
Algorytm i jego działanie
[edytuj | edytuj kod]Załóżmy, że krzywa w przedziale spełnia ww. założenia
Pierwszy piksel stawiamy w punkcie Drugi natomiast ogranicza się jedynie do dwóch możliwości: lub Przyrost w kierunku osi OX (osi wiodącej) jest stały – jeden piksel. Korzystając z równania kierunkowego prostej
policzymy w jakiej odległości znajdują się powyższe piksele od punktu przecięcia łączącego je odcinka z prostą przebiegającą w rzeczywistym układzie współrzędnych
Ponieważ dx > 0, di określa, która z odległości s i t jest większa. Jeżeli to s > t za punkt Pi+1 przyjmujemy piksel Ti+1, jeżeli wybieramy piksel Si+1. Wartość oznacza, że oba piksele leżą w tej samej odległości i arbitralnie przyjmujemy, że następny piksel to Ti+1. Policzmy jeszcze wartość
oraz różnicę
czyli
gdyż
Jeżeli to (wybieramy piksel ), co pozwala na uproszczenie obliczeń
Analogicznie, gdy mamy (wybieramy piksel ), i wzór na ma postać
Z uwagi na rekurencyjną postać wzoru na obliczanie współczynnika nazywanego także zmienna decyzyjna, należy jeszcze policzyć wartość początkową Podstawiając oraz do równania
otrzymujemy wzór na
Implementacja
[edytuj | edytuj kod]Implementacja algorytmu Bresenhama musi oczywiście uwzględniać inne możliwe położenia odcinka względem osi OX. Jednak w każdej sytuacji można zastosować opisany wyżej schemat, w razie potrzeby traktując oś OY jako oś wiodącą
Rysowanie odcinka algorytmem Bresenhama
[edytuj | edytuj kod]Procedura w języku C:
// x1 , y1 - współrzędne początku odcinka
// x2 , y2 - współrzędne końca odcinka
void BresenhamLine(const int x1, const int y1, const int x2, const int y2)
{
// zmienne pomocnicze
int d, dx, dy, ai, bi, xi, yi;
int x = x1, y = y1;
// ustalenie kierunku rysowania
if (x1 < x2)
{
xi = 1;
dx = x2 - x1;
}
else
{
xi = -1;
dx = x1 - x2;
}
// ustalenie kierunku rysowania
if (y1 < y2)
{
yi = 1;
dy = y2 - y1;
}
else
{
yi = -1;
dy = y1 - y2;
}
// pierwszy piksel
glVertex2i(x, y);
// oś wiodąca OX
if (dx > dy)
{
ai = (dy - dx) * 2;
bi = dy * 2;
d = bi - dx;
// pętla po kolejnych x
while (x != x2)
{
// test współczynnika
if (d >= 0)
{
x += xi;
y += yi;
d += ai;
}
else
{
d += bi;
x += xi;
}
glVertex2i(x, y);
}
}
// oś wiodąca OY
else
{
ai = ( dx - dy ) * 2;
bi = dx * 2;
d = bi - dy;
// pętla po kolejnych y
while (y != y2)
{
// test współczynnika
if (d >= 0)
{
x += xi;
y += yi;
d += ai;
}
else
{
d += bi;
y += yi;
}
glVertex2i(x, y);
}
}
}
Algorytm Bresenhama dla elipsy
[edytuj | edytuj kod]Założenia
[edytuj | edytuj kod]- Elipsa ma osie zgodne z osiami układu współrzędnych,
- Półosie elipsy mają długości a (wzdłuż osi OX) i b (wzdłuż OY),
- Rozważamy elipsę w I ćwiartce układu współrzędnych,
- Środkiem symetrii elipsy jest środek układu współrzędnych,
- Rysowanie elipsy zaczynamy od punktu (0, b),
- W każdym kroku stawiamy symetrycznie 4 punkty elipsy,
- Początkową osią wiodacą jest oś OX,
- W punkcie zmiany osi wiodącej, współczynnik nachylenia stycznej do elipsy wynosi -1 (tg 135°)
Algorytm i jego działanie
[edytuj | edytuj kod]Przybliżana elipsa ma równanie:
O wyborze piksela decydować będzie wartość funkcji
w punkcie środkowym M położonym pomiędzy alternatywnymi pikselami. Gdy osią wiodąca jest OX oblicza się
Jeżeli F (M) > 0, to punkt M leży na zewnątrz elipsy i wybieramy piksel Natomiast, gdy F (M)⇐ 0, to punkt M leży wewnątrz elipsy lub na jej brzegu i wybieramy piksel Gdy osią wiodąca jest OY oblicza się
Jeżeli to punkt M leży na zewnątrz elipsy i wybieramy piksel Natomiast, gdy to punkt M leży wewnątrz elipsy lub na jej brzegu i wybieramy piksel Algorytm nie wymaga jednak wyliczania każdorazowo wartości funkcji Jego siła leży w możliwości wyliczania wartości tej funkcji (czyli zmiennej decyzyjnej) w kolejnym kroku mniej obliczeń.
Zgodnie z przyjętymi założeniami elipsę zaczynamy rysować w punkcie Ponieważ osią wiodącą jest wówczas OX policzymy wartość zmiennej decyzyjnej d dla piksela startowego
Jeżeli następnym pikselem jest czyli to wartość zmiennej decyzyjnej wynosi:
Jeżeli następnym pikselem jest czyli to wartość zmiennej decyzyjnej wynosi:
Przy zmianie osi wiodącej na OY należy także zmienić wartość zmiennej decyzyjnej. Różnica między „nową” i „starą” zmienną wynosi:
Teraz wyliczymy rekurencyjne równania opisujące zmienną decyzyjną, gdy osią wiodącą jest OY. Jeżeli następnym pikselem jest czyli to wartość zmiennej decyzyjnej wynosi:
Przy wyborze następnego piksela czyli wartość zmiennej decyzyjnej wynosi:
Bibliografia
[edytuj | edytuj kod]- J.E. Bresenham. Algorithm for computer control of a digital plotter. „IBM Systems Journal”. 4 (1), 1965. [zarchiwizowane z adresu 2008-05-28]. (ang.).
- Michał Jankowski: Elementy grafiki komputerowej. Warszawa: Wydawnictwa Naukowo-Techniczne, 1990, s. 27–34. ISBN 83-204-1326-5.
Linki zewnętrzne
[edytuj | edytuj kod]- Algorytm Bresenhama. wm.ite.pl. [zarchiwizowane z tego adresu (2017-11-12)].