Algoritmo di disegno del cerchio di Bresenham

Algoritmo di disegno del cerchio di Bresenham

Non è facile visualizzare un arco continuo e uniforme sullo schermo del computer poiché lo schermo del nostro computer è costituito da pixel organizzati in forma di matrice. Quindi per disegnare un cerchio sullo schermo di un computer dovremmo sempre scegliere i pixel più vicini da un pixel stampato in modo che possano formare un arco. Ci sono due algoritmi per fare questo:

  1. Algoritmo di disegno del cerchio del punto medio
  2. Algoritmo di disegno del cerchio di Bresenham

Abbiamo già discusso di Algoritmo di disegno del cerchio del punto medio nel nostro post precedente. In questo post parleremo dell'algoritmo di disegno del cerchio di Bresenham. 

Entrambi questi algoritmi utilizzano la caratteristica chiave del cerchio che è altamente simmetrico. Quindi per l'intero cerchio di 360 gradi lo divideremo in 8 parti ciascun ottante di 45 gradi. Per fare ciò utilizzeremo l'algoritmo del cerchio di Bresenham per calcolare le posizioni dei pixel nel primo ottante di 45 gradi. Si presuppone che il cerchio abbia come centro l'origine. Quindi per ogni pixel (x y) calcolato disegniamo un pixel in ciascuno degli 8 ottanti del cerchio come mostrato di seguito: 

Per un pixel (xy) tutti i pixel possibili in 8 ottantiPer un pixel (xy) tutti i pixel possibili in 8 ottanti


Ora vedremo come calcolare la posizione del pixel successivo da una posizione del pixel precedentemente nota (xy). Nell'algoritmo di Bresenham in qualsiasi punto (x y) abbiamo due opzioni: scegliere il pixel successivo a est cioè (x+1 y) o a sud-est cioè (x+1 y-1).
 

cerchio 2


E questo può essere deciso utilizzando il parametro decisionale d come: 
 

  • Se d > 0 allora (x+1 y-1) deve essere scelto come pixel successivo poiché sarà più vicino all'arco.
  • altrimenti (x+1 y) deve essere scelto come pixel successivo.


Ora per disegnare il cerchio per un dato raggio 'r' e centro (xc yc) inizieremo da (0 r) e ci sposteremo nel primo quadrante fino a x=y (cioè 45 gradi). Dovremmo iniziare dalla condizione iniziale elencata: 
 

 d = 3 - (2 * r)   
x = 0
y = r

Ora per ogni pixel faremo le seguenti operazioni:  

  1. Impostare i valori iniziali di (xc yc) e (x y).
  2. Imposta il parametro decisionale da d a d = 3 – (2 * r).
  3. Chiama la funzione drawCircle(int xc int yc int x int y).
  4. Ripetere i passaggi seguenti fino a x <= y:
    • Se d < 0 set d = d + (4 * x) + 6.
    • Altrimenti imposta d = d + 4 * (x – y) + 10 e decrementa y di 1.
    • Aumenta il valore di x.
    • Chiama la funzione drawCircle(int xc int yc int x int y).

funzione drawCircle():  

CPP
   // function to draw all other 7 pixels   // present at symmetric position   drawCircle  (  int     xc       int     yc       int     x       int     y  )   {      putpixel  (  xc  +  x       yc  +  y       RED  );      putpixel  (  xc  -  x       yc  +  y       RED  );      putpixel  (  xc  +  x       yc  -  y       RED  );      putpixel  (  xc  -  x       yc  -  y       RED  );      putpixel  (  xc  +  y       yc  +  x       RED  );      putpixel  (  xc  -  y       yc  +  x       RED  );      putpixel  (  xc  +  y       yc  -  x       RED  );      putpixel  (  xc  -  y       yc  -  x       RED  );   }   

Di seguito è riportata l'implementazione C dell'approccio precedente. 

CPP
   // C-program for circle drawing   // using Bresenham’s Algorithm   // in computer-graphics   #include         #include         #include         // Function to put pixels   // at subsequence points   void     drawCircle  (  int     xc       int     yc       int     x       int     y  ){      putpixel  (  xc  +  x       yc  +  y       RED  );      putpixel  (  xc  -  x       yc  +  y       RED  );      putpixel  (  xc  +  x       yc  -  y       RED  );      putpixel  (  xc  -  x       yc  -  y       RED  );      putpixel  (  xc  +  y       yc  +  x       RED  );      putpixel  (  xc  -  y       yc  +  x       RED  );      putpixel  (  xc  +  y       yc  -  x       RED  );      putpixel  (  xc  -  y       yc  -  x       RED  );   }   // Function for circle-generation   // using Bresenham's algorithm   void     circleBres  (  int     xc       int     yc       int     r  ){      int     x     =     0       y     =     r  ;      int     d     =     3     -     2     *     r  ;      drawCircle  (  xc       yc       x       y  );      while     (  y     >=     x  ){          // check for decision parameter      // and correspondingly       // update d y      if     (  d     >     0  )     {      y  --  ;         d     =     d     +     4     *     (  x     -     y  )     +     10  ;      }      else      d     =     d     +     4     *     x     +     6  ;      // Increment x after updating decision parameter      x  ++  ;          // Draw the circle using the new coordinates      drawCircle  (  xc       yc       x       y  );      delay  (  50  );      }   }   int     main  ()   {      int     xc     =     50       yc     =     50       r     =     30  ;      int     gd     =     DETECT       gm  ;      initgraph  (  &  gd       &  gm       ''  );     // initialize graph      circleBres  (  xc       yc       r  );     // function call      return     0  ;   }   

Produzione: 
 

circleout


Vantaggi  

  • È un algoritmo semplice.
  • Può essere implementato facilmente
  • È totalmente basato sull'equazione del cerchio, cioè x 2 +y 2 =r 2

Svantaggi  

  • C'è un problema di precisione durante la generazione di punti.
  • Questo algoritmo non è adatto per immagini complesse e ad alto contenuto grafico.
Crea quiz