I’m playing around with ideas from the book Mathographics by Robert Dixon. On pages 190-192 he has images of what he calls Condensation drawings. I call them Kissing Circles because the circles all touch each other at just one point – hopefully.
Here is my attempt. If you want to see something cool set the drop count to 1 and then use the right-arrow key to increment the drop count by one over and over so that you can see one drop at a time being added.
| view source |
The author, Robert Dixon, doesn’t provide the code for his examples. Just the concept and how he would go about writing an algorithm to solve a particular problem. For this one he suggested that each circle gets pushed into an array. Then for each new circle – randomly placed – you loop through the array of existing circles to see if it overlaps with any of them. If not then you have a new circle to add to the display. Otherwise create a new circle in a random location and test again.
Code outline
My approach follows this general idea. I created a KissingCircles class that accepts 5 parameters:
- width, height, // area that the center of the circles can occupy
- circleCount, // number of circles to draw
- seed, // number that is used to seed the random number generator
- maxRadius
After drawing an initial circle to get things started I start looping through a while-loop that keeps track of the number of times through the loop – runs – and the number of circles that are successfully created – count.
Each time through the loop I use my PseudoRnd class to pick a random numbers for the x/y postion of a new circle. I then use the BitmapData.getPixel() method to find the color at that point. If it is white then I know that there is no circle at that point. ( The background is white. )
I’m using the PseudoRnd class because I want to be able to recreate a pattern. If the seed remains the same then the pattern will always be exactly the same for the same number of circles.
If the space it clear to draw a circle then I need to fit it up against the nearest circle to that point. To do so I loop through all of the existing circles to find the one that it is closest to. Once I have the nearest circle I check and see if it is further away than the maxRadius. If not then I’m done. The new circle will be drawn right up against the nearest one.
But if it is further away then I need to reposition the circle so that it has a radius equal to maxRadius and is right up against the nearest circle. This is where the Math.atan2( y, x ) method comes in handy. ( Check out my Math.atan2( y, x ) Explorer for an example of how it works. )
Now we have a new circle that has been placed right up against the nearest circle. Since the new circle has been moved we need to make sure that it didn’t get dropped on top of an existing circle so once more through the loop of all existing circles with the checkOverlap() method.
That pretty much does it.
Code evolved
This approach evolved over time. Initially I didn’t have a value for the maxRadius. So each new circle was exactly the radius it needed to be in order to just kiss up against the nearest circle. That’s fine but if the new circle is a long way from the nearest circle it means that this new circle will be huge. It could take up most of the available space.
If I were doing this over from scratch I might try picking a random circle from the array of all existing circles and then fit a new circle up against it. I think that might run a little faster because it would remove some of the looping that is needed to make sure that circles don’t overlap.
Interesting additions
I think it would be cool to let each circle animate from a point size up to its calculated radius over time. That might be a neat effect.
Do you have any suggestions for how to improve this?





Cool effect, I know what you mean about code evolving over time until you reach a point that the current functionality isn't as efficient as it could be. And I agree that choosing an existing circle from the array and making the new circle "kiss" it would be better than a random loop that repeats until you get a kissing circle.
@Evan, I'm trying to think of a logo that would stand for "Code Evolves". If I can think of one I'm making a T-shirt! :)
nice man I love Kisses :)
The visual result is a very pleasant pattern… To take it a step farther, what about a way to randomly generate a color code for each circle? And then two percent-based sliders: slider one amplifies the radius of each circle, and slider two sets the alpha transparency of the newly amplified radius area.
THAT would be fraking cool you'd have to build a kickass fullscreen button just to show it off properly.
@matthew, funny you should mention the colors and such. I first explored this pattern for a client project – don't ask what it was about. In the client version the circles have different background gradient colors and the gradients are randomly rotated. And it does look pretty cool. But there's something to be said for visual simplicity as well.
True enough. It's also be just as cool to go in the simplify direction and have only fills. Maybe black ones? Still, the real magic is that you made circles kiss at your bidding. Nice work!
good,but how to fit some given irregular polygons in the container? thanks