Given the center (x,y)
and radius r
, how one can draw a circle C((x,y),r)
in pixel grid using python? It is fine to assume that pixel grid is large enough.
Asked
Active
Viewed 6,245 times
4
-
Do you want to output a image file, or create an interactive application? If it's interactive, is it for data visualization, or a game? – loopbackbee Jul 20 '15 at 14:39
-
1@goncalopp I want a 2D array containing `0` and `1` such that `1` denote the location of circle. – Jul 20 '15 at 14:41
-
Have a look into the [Midpoint circle algorithm](https://en.wikipedia.org/wiki/Midpoint_circle_algorithm). Let us know if you struggle with an implementation detail. – Falko Jul 20 '15 at 14:44
-
@Falko Thanks a lot. – Jul 20 '15 at 14:46
-
If you want to get fancy & draw a smooth circle, take a look at [Fast, Antialiased Circles and Ellipses from Xiaolin Wu’s concepts](https://yellowsplash.wordpress.com/2009/10/23/fast-antialiased-circles-and-ellipses-from-xiaolin-wus-concepts/). The code on that site is in Pascal, but it doesn't look _too_ hard to translate to Python. FWIW, Wu's line algorithm is the standard for drawing antialiased lines; his circle algorithm is less well-known. – PM 2Ring Jul 20 '15 at 14:57
2 Answers
5
Here's the RosettaCode Midpoint circle algorithm in Python
def circle(self, x0, y0, radius, colour=black):
f = 1 - radius
ddf_x = 1
ddf_y = -2 * radius
x = 0
y = radius
self.set(x0, y0 + radius, colour)
self.set(x0, y0 - radius, colour)
self.set(x0 + radius, y0, colour)
self.set(x0 - radius, y0, colour)
while x < y:
if f >= 0:
y -= 1
ddf_y += 2
f += ddf_y
x += 1
ddf_x += 2
f += ddf_x
self.set(x0 + x, y0 + y, colour)
self.set(x0 - x, y0 + y, colour)
self.set(x0 + x, y0 - y, colour)
self.set(x0 - x, y0 - y, colour)
self.set(x0 + y, y0 + x, colour)
self.set(x0 - y, y0 + x, colour)
self.set(x0 + y, y0 - x, colour)
self.set(x0 - y, y0 - x, colour)
Bitmap.circle = circle
bitmap = Bitmap(25,25)
bitmap.circle(x0=12, y0=12, radius=12)
bitmap.chardisplay()

A.M.
- 1,757
- 5
- 22
- 41
-
It's better to make the link text a little more meaningful to guard against link rot. Eg "Here's the RosettaCode [Midpoint circle algorithm](http://rosettacode.org/wiki/Bitmap/Midpoint_circle_algorithm#Python) in Python". True, rosettacode is a rather stable site, but you never know... and it's a good habit to get into on Stack Exchange sites. – PM 2Ring Jul 20 '15 at 15:08
-
-
4
Assuming you want to get things done (as opposed to learning raster graphics algorithms), simply use Pillow:
from PIL import Image, ImageDraw
image = Image.new('1', (10, 10)) #create new image, 10x10 pixels, 1 bit per pixel
draw = ImageDraw.Draw(image)
draw.ellipse((2, 2, 8, 8), outline ='white')
print list(image.getdata())
output:
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
The range is 0..255 because Pillow stores a byte-per-pixel even for a 1-bit-per-pixel image (as its more efficient).
If you want the range on 0..1, you can then divide by 255:
[x/255 for x in image.getdata()]

loopbackbee
- 21,962
- 10
- 62
- 97