Packing circles inside a shape

(9 comments)

A previous blog post dealt with packing circles into a circle. To fill an arbitrary shape, a slightly different approach is needed. The code is presented in my github repo.

A black-and-white PNG image should provided (the black areas to be filled). The ShapeFill class is initialized with its filename, the number of circles (n), and rho_min and rho_max, the ratios of the minimum and maximum circle size to the shortest dimension of the image (defaults are used if these parameters are not provided).

The colours are set at random from a sequence of indexes into a list of CSS-style colour specifiers. Not all the colours need to be set in a single pass through the make_circles algorithm in building an image, but they should all be sent to the ShapeFill constructor in order to set the CSS styles correctly.

# Land colours, sea colours.
c1 = ['#b6950c', '#9d150b']
c2 = ['#173f5f', '#20639b', '#3caea3']

# First fill the land silhouette.
shape = ShapeFill('uk.png', n=3000, rho_max=0.01, colours=c1+c2)
shape.guard = 1000
shape.make_circles(c_idx=range(len(c1)))
shape.make_svg('uk-1.svg')

The UK filled with circles

We can then go round again and pass another image (e.g. the inverse of the original image, to fill in the background):

# Now load the image again, invert it and fill the sea with circles.
shape.read_image('uk.png')
shape.img = 255 - shape.img
shape.n = 5000
shape.make_circles(c_idx=[len(c1)+i for i in range(len(c2))])
shape.make_svg('uk-2.svg')

The UK and surrounding sea filled with circles

Current rating: 3.3

Comments

Comments are pre-moderated. Please be patient and your comment will appear soon.

Ken Flerlage 5 years ago

Really cool stuff. I'm trying to do something just like this except using data to drive the size of the circles--like a typical packed bubble chart, except inside of a shape. Going to dig into your code to see if that might be doable. Thanks!

Link | Reply
Current rating: 5

christian 5 years ago

I'm glad you find it interesting. Hope your project works out!
Christian

Link | Reply
Currently unrated

Zhuldyz 4 years, 4 months ago

Can I put set it up to make two different specific shapes that do not vary like in this example? Thank you for making this! It is really helpful.

Link | Reply
Currently unrated

christian 4 years, 4 months ago

I'm not sure I understand: you can use any file in place of uk.png as the silhouette that is filled, but the filling shapes used have to be circles.

Link | Reply
Currently unrated

Adam 3 years, 5 months ago

Is Shapefill part of a module or library? I can’t find it anywhere.

Link | Reply
Currently unrated

christian 3 years, 5 months ago

Hi Adam,
The ShapeFill class is defined in shapefill.py which is available on my GitHub repository (linked above): https://github.com/xnx/circle-packing/blob/master/shapefill.py
I hope that helps,
Christian

Link | Reply
Currently unrated

Dave Low 3 years, 4 months ago

Hi Christian!

My name's Dave - I'm a graphic designer and I've been looking into using something like this in my work - but I know very little about code and how I might use something like this to produce images. Would you have time to give me a few pointers?

Link | Reply
Currently unrated

mk 2 years ago

Hi, how can I achieve all the circles usde for packing are the same size?

Link | Reply
Currently unrated

christian 2 years ago

In the Circles class, I think you can just set rho_min equal to rho_max, can't you? (https://scipython.com/blog/packing-circles-in-a-circle/)

Link | Reply
Currently unrated

New Comment

required

required (not published)

optional

required