Evolution of an Experiment: Circle Collision part 2

Continuing from yesterdays article showing the beginning of my circular collision experiments, this post will show how the simple test cases evolved into a music visualizer.

Yesterday on Twitter SeyelentEco asked me why I built a circular collision engine instead of using an existing physics library. The main reasons were size, speed, and simply because I wanted to learn a bit about the math involved. For example, all of these experiments are under 5kb, and the collision logic can handle a couple hundred circles without too much trouble.

As part of the initial commercial project that birthed these experiments, I built out a version in which circles would scale up quickly when the user rolled over them. Unfortunately, I don’t seem to have this version any more, but I thought it was pretty cool to roll over a circle and watch the surrounding circles get propelled outwards. Rolling over/out of a circle rapidly sparked the idea of having two “speaker” circles that would expand based on the volume of a playing track.

To build this, I realized I would need support for anchored circles (ones that didn’t move). This led to CircleTest4 which implemented this feature. Click and drag to create circles, move the cursor before you release to give them velocity. It’s mildly entertaining to see how many bounces between the circles you can get.

Next I plugged in the music, wired each channel’s volume to a “driver”, and started playing with the aesthetics, resulting in CircleTest5.

From there, it largely became an exercise in design and motion graphics. I played with the colors, added trails using the drawing API and bitmapdata, and continued tweaking the collision logic to be more reliable in high speed collisions. The result was CircleTest6.

I ran through a few more design iterations (which I won’t link because they are pretty minor): CircleTest7 had the drivers orbit each other at close proximity and added the subtle bevel effect to make them look like metaballs, CircleTest8 was a variation playing with the circles moving farther apart based on volume (which I didn’t like), and CircleTest9 played with adding color.

Ultimately, all this tweaking resulted in the current final product, CircleTest10, which combined the metaballs, color, and some basic lighting effects. If you click and hold, you’ll note some vestigial functionality from earlier experiments: the ability to create new red circles.

In part 3 I will show how CircleTest10 evolved into a short series of experiments on lighting effects. I will also release at least some of this code once I have a chance to clean it up a tad.

Grant Skinner

The "g" in gskinner. Also the "skinner".



  1. Cool!!! great post Grant.

  2. The lighting experiment is very realistic! I love the transparency of the black balls!

    One more little thing: small ball hits large ball’s lower part but not the edge if they’re 3D. You know what I mean?

  3. Amazing experiments. Will you ever release the code for this. Would be amazing to experiment for generative artwork with sound.

  4. This is starting to look like Flight 404! Exciting.

  5. Wow Grant, this is amazing. The lighting effects example blew me away. I’d love to know how you did that. 🙂

    Thank you for doing this. It’s enlightening to see things like this. Really gets you thinking…

  6. Yeah the lighting experiment has a lovely feel to it.

    Hello to the gSkinner team!

  7. Wow! I really liked the music visualiser, but that lighting effect is incredible! Awesome work – I look forwards to seeing the code.

  8. Anyway your final post could allow us to insert our own mp3 url to play?

  9. That’s really cool Grant! I actually laughed when the balls all got thrown away when the music went quiet and then blasted out. Very interesting experiment! Made the fan go on full blast on my macbook pro here though.

  10. Yeah, that’s a fantastic lighting effect Grant.

    It’s getting me itching to try out a reactive music visualiser.

Leave a Reply

Your email address will not be published. Required fields are marked *