אלגוריתם ציור המעגלים של ברסנהאם

אלגוריתם ציור המעגלים של ברסנהאם

לא קל להציג קשת חלקה רציפה על מסך המחשב שכן מסך המחשב שלנו עשוי מפיקסלים המאורגנים בצורת מטריצה. אז כדי לצייר עיגול על מסך מחשב עלינו לבחור תמיד את הפיקסלים הקרובים ביותר מתוך פיקסל מודפס כדי שיוכלו ליצור קשת. ישנם שני אלגוריתמים לעשות זאת:

  1. אלגוריתם ציור עיגול של נקודת אמצע
  2. אלגוריתם ציור המעגלים של ברסנהאם

כבר דנו ב אלגוריתם ציור עיגול של נקודת אמצע בפוסט הקודם שלנו.בפוסט זה נדון על אלגוריתם ציור המעגל של Bresenham. 

שני האלגוריתמים הללו משתמשים בתכונת המפתח של המעגל שהוא סימטרי מאוד. אז עבור 360 מעלות שלמות של מעגל נחלק אותו ל-8 חלקים כל אוקטנט של 45 מעלות. על מנת לעשות זאת נשתמש באלגוריתם המעגל של Bresenham לחישוב מיקומי הפיקסלים באוקטנט הראשון של 45 מעלות. זה מניח שהמעגל מרוכז במקור. אז עבור כל פיקסל (x y) הוא מחשב אנו מציירים פיקסל בכל אחד מ-8 האוקטנטים של המעגל כפי שמוצג להלן: 

עבור פיקסל (xy) כל הפיקסלים האפשריים ב-8 אוקטנטיםעבור פיקסל (xy) כל הפיקסלים האפשריים ב-8 אוקטנטים


כעת נראה כיצד לחשב את מיקום הפיקסל הבא ממיקום פיקסל ידוע בעבר (x y). באלגוריתם של Bresenham בכל נקודה (x y) יש לנו שתי אפשרויות או לבחור את הפיקסל הבא במזרח כלומר (x+1 y) או בדרום מזרח כלומר (x+1 y-1).
 

מעגל 2


וניתן להחליט על כך על ידי שימוש בפרמטר ההחלטה d כ: 
 

  • אם d > 0 אזי (x+1 y-1) יש לבחור בתור הפיקסל הבא מכיוון שהוא יהיה קרוב יותר לקשת.
  • אחרת (x+1 y) יש לבחור בתור הפיקסל הבא.


כעת לצייר את המעגל עבור רדיוס נתון 'r' ומרכז (xc yc) נתחיל מ- (0 r) ונעבור ברביע הראשון עד x=y (כלומר 45 מעלות). עלינו להתחיל מהמצב הראשוני הרשום: 
 

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

כעת עבור כל פיקסל נבצע את הפעולות הבאות:  

  1. הגדר ערכים ראשוניים של (xc yc) ו-(x y).
  2. הגדר את פרמטר ההחלטה d ל-d = 3 – (2 * r).
  3. קרא לפונקציה drawCircle(int xc int yc int x int y).
  4. חזור על השלבים הבאים עד ל-x <= y:
    • אם ד < 0 set d = d + (4 * x) + 6.
    • אחרת, הגדר d = d + 4 * (x – y) + 10 והקטין את y ב-1.
    • הגדל את הערך של x.
    • קרא לפונקציה drawCircle(int xc int yc int x int y).

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

להלן יישום C של הגישה לעיל. 

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

תְפוּקָה: 
 

מעגל


יתרונות  

  • זה אלגוריתם פשוט.
  • זה יכול להיות מיושם בקלות
  • זה מבוסס לחלוטין על משוואת המעגל כלומר x 2 +y 2 =r 2

חסרונות  

  • יש בעיה של דיוק בזמן יצירת נקודות.
  • אלגוריתם זה אינו מתאים לתמונות גרפיות מורכבות וגבוהות.
צור חידון