Algoritmo dell'arco di cerchio di Bresenham

L' arco di trama dell'algoritmo di Bresenham , o punto medio dell'algoritmo di tracciamento dell'arco ( punto medio inglese) consente una complessità algoritmica notevolmente ridotta, disegnare cerchi nell'immagine raster .

Storico

Questo algoritmo, pubblicato da Bresenham in Febbraio 1977, si ispira al suo precedente lavoro sul tracciato di segmenti e al più generale algoritmo di Pitteway sul tracciato di coniche , di cui i cerchi sono un caso speciale.

Spiegazione dell'algoritmo di base nel primo ottante

Un ottavo è sufficiente

Innanzitutto possiamo notare che su una griglia di pixel sono presenti quattro assi di simmetria rispetto al cerchio , due lungo gli assi della matrice e due che rappresentano le bisettrici della cornice centrata sul cerchio. Quindi, avendo calcolato un arco di un settore del segno di riferimento delimitato dagli assi di simmetria, è sufficiente sfruttare la simmetria per posizionare i pixel negli altri sette ottanti.

L'algoritmo di base

Per ragioni di simmetria spiegate in precedenza, l'algoritmo spiegato sarà limitato al secondo ottante (con angolo compreso tra e ) e quindi generalizzato. L'algoritmo partirà quindi dal punto più alto del cerchio e scenderà fino alla prima bisettrice.

Diagramma

Questa trama procede per iterazione , ogni iterazione attiva un pixel. Immagina di essere in un pixel P e di dover posizionare il pixel successivo. Dato che siamo nel secondo ottante, questo pixel sarà il punto E o il punto F. Il metodo di Bresenham consiste nel valutare se il cerchio di equazione "ideale" passa sopra o sotto il punto M, punto medio del segmento EF per attivare il pixel E o il pixel F.

È quindi necessario calcolare ad ogni iterazione una variabile m tale che . Allora :

Ottimizzazione dell'algoritmo

Per ottimizzare l'algoritmo, calcoliamo ricorsivamente la variabile m. Dimostriamo che (1)

dimostrazione

Passiamo al punto di contatto sulla griglia di pixel e calcoliamo la variabile m.

Allora sappiamo che M ha per coordinate .

Quindi .

Poiché vogliamo lavorare solo con numeri interi e poiché siamo interessati solo al segno di m, moltiplichiamo l'equazione per 4 e otteniamo .  


Modificheremo la variabile m secondo la scelta del pixel E o del pixel F. Denomineremo il vecchio valore di m, e il nuovo valore di m.

È quindi necessario incrementare di .

dimostrazione

Se scegliamo E, allora .

Tuttavia, secondo l'equazione (1),

,

pertanto

da dove .

Utilizzando il fatto che ,

otteniamo .  

È quindi necessario incrementare di .

dimostrazione Ragionamento analogo a quello in cui scegliamo E  

Si deduce quindi il calcolo iterativo di m: con d che è uguale a 0 se scegliamo E, e se scegliamo F.

Per avviare il calcolo iterativo, lo notiamo quindi .

Algoritmo ottimizzato

Algoritmo di trama ottante

procédure tracerOctant (entier rayon, entier x_centre, entier y_centre) déclarer entier x, y, m ; x ← 0 ; y ← rayon ; // on se place en haut du cercle m ← 5 - 4*rayon ; // initialisation Tant que x <= y // tant qu'on est dans le second octant tracerPixel( x+x_centre, y+y_centre ) ; si m > 0 alors // choix du point F y ← y - 1 ; m ← m-8*y ; // correspond au "d" des explications fin si ; x ← x+1 ; m ← m + 8*x+4 ; fin tant que ; fin de procédure ;

La variabile m rappresenta i “4m” del paragrafo precedente, poiché ci interessa solo il segno di 4m ed è uguale a quello di m.

Algoritmo per disegnare l'intero cerchio

procédure tracerCercle (entier rayon, entier x_centre, entier y_centre) déclarer entier x, y, m ; x ← 0 ; y ← rayon ; // on se place en haut du cercle m ← 5 - 4*rayon ; // initialisation Tant que x <= y // tant qu'on est dans le second octant tracerPixel( x+x_centre, y+y_centre ) ; tracerPixel( y+x_centre, x+y_centre ) ; tracerPixel( -x+x_centre, y+y_centre ) ; tracerPixel( -y+x_centre, x+y_centre ) ; tracerPixel( x+x_centre, -y+y_centre ) ; tracerPixel( y+x_centre, -x+y_centre ) ; tracerPixel( -x+x_centre, -y+y_centre ) ; tracerPixel( -y+x_centre, -x+y_centre ) ; si m > 0 alors //choix du point F y ← y - 1 ; m ← m - 8*y ; fin si ; x ← x + 1 ; m ← m + 8*x + 4 ; fin tant que ; fin de procédure ;

Procediamo semplicemente per simmetria nei diversi ottanti.

Note sul metodo Bresenham

Bassa complessità

Abbiamo visto in precedenza che per ogni pixel posizionato la complessità computazionale è stata ridotta a X addizioni, moltiplicazioni Y e confronti Z. L'uso delle usuali funzioni trigonometriche o di una radice quadrata avrebbe richiesto un notevole costo algoritmico in confronto.

Illustrazione di "buchi"

Estensioni

Possiamo anche usare il principio di questo algoritmo per disegnare corone ed ellissi .

Limitazioni del metodo

Se disegniamo cerchi concentrici di raggio sempre maggiore, notiamo che non possiamo riempire tutto il piano: ci sono dei "buchi". Questo difetto porta all'uso di altri metodi, come l' algoritmo di disegno del cerchio di Andres .

Esempio di implementazione

In C #

public static List<Point> BresenhamCircle(int xc,int yc,int r) { List<Point> ret = new List<Point>(); int x,y,p; x=0; y=r; ret.Add(new Point(xc+x,yc-y)); p=3-(2*r); for(x=0;x<=y;x++) { if (p<0) { p=(p+(4*x)+6); } else { y-=1; p+=((4*(x-y)+10)); } ret.Add(new Point(xc+x,yc-y)); ret.Add(new Point(xc-x,yc-y)); ret.Add(new Point(xc+x,yc+y)); ret.Add(new Point(xc-x,yc+y)); ret.Add(new Point(xc+y,yc-x)); ret.Add(new Point(xc-y,yc-x)); ret.Add(new Point(xc+y,yc+x)); ret.Add(new Point(xc-y,yc+x)); } return ret; }

Appunti

  1. (in) Jack Bresenham, "  Un algoritmo lineare per la visualizzazione digitale incrementale di archi circolari  " , Communications of the ACM , vol.  20, n o  2Febbraio 1977, p.  100-106 ( DOI  10.1145 / 359423.359432 )
  2. (in) Michael LV Pitteway, "  Algorithm for Drawing Ellipses gold Hyperbolee with a Digital Plotter  " , The Computer Journal , vol.  10, n o  3,Novembre 1967, p.  282-289 ( ISSN  0010-4620 , OCLC  4653069003 , DOI  10.1093 / comjnl / 10.3.282 ) [PDF]