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
edytujZałożenia
edytuj- 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
edytujZałóż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
edytujImplementacja 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
edytujProcedura 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);
}
}
}
Założenia
edytuj- 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
edytujPrzybliż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- 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- Algorytm Bresenhama. wm.ite.pl. [zarchiwizowane z tego adresu (2017-11-12)].