More pythonic circle?

Scott David Daniels scott.daniels at acm.org
Sun Apr 9 19:45:08 EDT 2006


Pythor wrote:
> I wrote the following code for a personal project.  I need a function
> that will plot a filled circle in a two dimensional array.  I found
> Bresenham's algorithm, and produced this code.  Please tell me there's
> a better way to do this.
> 
> import numpy
> 
> def circle(field=None,radius,center=(0,0),value=255,):
         ...

Break this code into two functions.  Roughly:

def wedge_nz(radius):
     '''points in octant 2 of 0-origin radius-sized circle, no zeroes'''
     x, y = int(radius), 1
     dr2 = x ** 2  +  y ** 2
     r2 = radius ** 2
     dy_limit = int(radius * .71)  # sin of 45 degrees + a smidge
     while y <= dy_limit:
         if r2 >= dr2:  # dx**2 + dy**2
             for tx in range(1, x + 1):
                 yield tx, y
             dr2 += y * 2 + 1      # dr2 = x ** 2  +  (y + 1) ** 2
             y += 1
         else:
             dr2 -= x * 2 - 1      # dr2 = (x - 1) ** 2  +  y ** 2
             x -= 1
             if x < y:
                 break

and:

def circle2(field=None, radius=3.2, center=(0, 0), entry=255):
     '''Fill field at all points within 'radius' of center with entry.

     center is assumed integral.
     '''
     x, y = center
     if field is None:
         field = numpy.zeros((int(x + radius), int(y + radius)), 'u')

     for px, py in wedge_nz(radius):
         for dx in (px, -px):
             for dy in (py, -py):
                 # Done once per quadrant.  Do both octants.
                 field[max(0, y + dy)][max(0, x + dx)] = entry
                 field[max(0, y + dx)][max(0, x + dy)] = entry
     # do the diameters
     for dx in range(-radius, radius + 1):
         field[y][max(0, x + dx)] = entry
         field[max(0, y + dx)][x] = entry
     return field

There is still overlap done at x = y and x = -y; you could squeeze that
out as well by changing wedge_nz not to put it out, and making circle2
do diagonal diameters as well (leaving the center the sole overwrite).

--Scott David Daniels
scott.daniels at acm.org



More information about the Python-list mailing list