Drawing Circles using Bresenham's Circle Algorithm





update dec 2006

bresenham arc, line drawing, and scan conversion working
now!  Thanks to Andy McFadden and Nick Westgate...

here is dsk image:
 zipped disk image



I posted to Comp.sys.apple2.programmer newsgroup, 
asking how to quickly compute an arc + area of 
circle.
  
Andy McFadden  replied with : this post  , which pointed to:

this page,   and this page. 


I had been doing the the following 
to compute circles:

*********************************************

     10 gosub 1000: rem draw screen 
     20 END 

     1010 REM draw screen 
     1020 GR: COLOR = 7 
     1050 color = 3:plot 19,19 : rem center 
     1060 color = 4 

     1070 CX = 19:CY = 19 : rem center coordinates of circle 
     1100 r1=19 : rem radius of circle 
     1110 for a = 0 to 360:rem angle 
     1120 gosub 8000: rem compute x,y offset 
     1130 plot CX + x1 , CY + y1 : rem plot point 
     1140 next a 
     1150 return 


     8000 rem calc pt in circle 
     8010 ar = a * (3.14/180) 
     8020 x1 = r1 * cos (AR) 
     8030 y1=-r1 * sin (ar) 
     8040 return 

*********************************************



This took 30 seconds in an emulator, running at 
"real machine" speed.

Using the information contained in the articles 
that Andy gave me links to, I was able to speed
this up to about 1 second execution time! :


*********************************************

      500 radius = 19
      510 CX = 19: cy = 19 : REM center coordinates

     1000 D = 3 - (2*radius) 
     1010 X = 0 
     1020 Y = radius  :rem (when x=0, Y = radius!) 


     2000"loop": 
     2010 if d < 0 then d = d + ( 4 * x ) + 6 
             :goto 3000: rem "D isn't < 0"  
     2020 if d > = 0 then d = d + 4 * ( x - y ) + 10
             : y = y - 1 


     3000 rem "D isn't <0" 
     3010 gosub 4000: rem "plot" 
     3020 if x=y then GOTO 3500 
     3030 x=x+1:goto 2000 : rem "loop" 
     3040 END 

     3500 rem done with circle
     3510 print "done"
     3520 END

     4000 rem "plot" 
     4010 plot cx+x, cy+y 
     4020 plot cx+x, cy-y 
     4030 plot cx-x,cy+y 
     4040 plot cx-x,cy-y 
     4050 plot cx+y,cy+x 
     4060 plot cx+y,cy-x 
     4070 plot cx-y,cy+x 
     4080 plot cx-y,cy-x 
     4090 return 

*********************************************



this graphic shows the order that the points
are plotted in.  Point 1 refers to line 4010
plot.  point 2 refers to line 4020 plot, etc:

___________________
| number  |   line |
|_________|________|
| pt1:    | 4010   |
| pt2:    | 4020   |
| pt3:    | 4030   |
| pt4:    | 4040   |
| pt5:    | 4050   |
| pt6:    | 4060   |
| pt7:    | 4070   |
| pt8:    | 4080   |
|_________|________|




The graphic above shows what I want to figure
out next.  I want to calculate a 45 degree 
slice of the circle, and fill this area
(I actually want coordinates of all the points,
but if I can fill it, I know the points!)



The 45 degree slice that I want to compute
coordinates for can be *any* 45 degree slice.

As INPUT to the routine, I have the angle
of a line running through the center of 
the 45 degree slice:




In the above example, the slice is centered
on 42 degree line.  In my program I want
the 42 degrees to be variable, but always
compute a 45 degree segment of the circle.




more progress

the above graphic shows which plots (in the code) refer to which angle in the circle. 0 degrees on the circle is "up", or "north". 180 is "down" or "south" ________________________ |number | degrees | |_________|_____________| 1 | # 2 | 0 - 45 | 2 | # 6 | 45 - 90 | 3 | # 5 | 90 - 135 | 4 | # 1 | 135 - 180 | 5 | # 3 | 180 - 225 | 6 | # 7 | 225 - 270 | 7 | # 8 | 270 - 315 | 8 | # 4 | 315 - 0 | ------------------------- Since I only want a 45 degree segment of the circle, I will only be using 2 of the lines in the PLOT routine each time I do a calculation. I need to determine WHICH of these plots to use based on the input angle of the routine. I also have to skip drawing points that are out of range. DSK image of what I have so far