Bresenhamov algoritam za crtanje kruga

Bresenhamov algoritam za crtanje kruga

Nije lako prikazati kontinuirani glatki luk na zaslonu računala jer je zaslon našeg računala napravljen od piksela organiziranih u obliku matrice. Dakle, da bismo nacrtali krug na zaslonu računala, uvijek bismo trebali odabrati najbliže piksele iz tiskanog piksela kako bi mogli oblikovati luk. Postoje dva algoritma za to:

  1. Algoritam za crtanje kruga srednje točke
  2. Bresenhamov algoritam za crtanje kruga

Već smo razgovarali o Algoritam za crtanje kruga srednje točke u našem prethodnom postu. U ovom postu ćemo raspravljati o Bresenhamovom algoritmu za crtanje kruga. 

Oba ova algoritma koriste ključnu značajku kruga da je visoko simetričan. Dakle, cijeli krug od 360 stupnjeva podijelit ćemo na 8 dijelova, svaki oktant od 45 stupnjeva. Da bismo to učinili, koristit ćemo Bresenhamov kružni algoritam za izračun lokacija piksela u prvom oktantu od 45 stupnjeva. Pretpostavlja se da je krug u središtu ishodišta. Dakle, za svaki piksel (x y) koji izračunava crtamo piksel u svakom od 8 oktanata kruga kao što je prikazano u nastavku: 

Za piksel (xy) svi mogući pikseli u 8 oktantaZa piksel (xy) svi mogući pikseli u 8 oktanta


Sada ćemo vidjeti kako izračunati lokaciju sljedećeg piksela iz prethodno poznate lokacije piksela (x y). U Bresenhamovom algoritmu u bilo kojoj točki (x y) imamo dvije opcije ili odabrati sljedeći piksel na istoku, tj. (x+1 y) ili na jugoistoku, tj. (x+1 y-1).
 

krug 2


I to se može odlučiti korištenjem parametra odluke d kao: 
 

  • Ako je d > 0 tada (x+1 y-1) treba odabrati kao sljedeći piksel jer će biti bliže luku.
  • inače (x+1 y) treba odabrati kao sljedeći piksel.


Sada da nacrtamo krug za zadani radijus 'r' i centar (xc yc). Počet ćemo od (0 r) i kretati se u prvom kvadrantu do x=y (tj. 45 stupnjeva). Trebalo bi krenuti od navedenog početnog stanja: 
 

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

Sada ćemo za svaki piksel napraviti sljedeće operacije:  

  1. Postavite početne vrijednosti (xc yc) i (x y).
  2. Postavite parametar odluke d na d = 3 – (2 * r).
  3. Pozovite funkciju drawCircle(int xc int yc int x int y).
  4. Ponavljajte sljedeće korake do x <= y:
    • Ako d < 0 set d = d + (4 * x) + 6.
    • Inače postavite d = d + 4 * (x – y) + 10 i smanjite y za 1.
    • Povećajte vrijednost x.
    • Pozovite funkciju drawCircle(int xc int yc int x int y).

funkcija 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  );   }   

Ispod je C implementacija gornjeg pristupa. 

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  ;   }   

Izlaz: 
 

zaokruživanje


Prednosti  

  • To je jednostavan algoritam.
  • Može se jednostavno implementirati
  • U potpunosti se temelji na jednadžbi kruga, tj. x 2 +y 2 =r 2

Nedostaci  

  • Postoji problem točnosti prilikom generiranja bodova.
  • Ovaj algoritam nije prikladan za složene i visoko grafičke slike.
Napravi kviz