Coding: Bring the Noise

%26lt;0011 Em

Old code: “playing with boids” OR “this would be a cool music visualizer”

leave a comment »

As I was sorting through my old code, I found this “gem” from my visual python experiments last year in college.  The code and instructions are at the end of this post.  I’d recommend reading the rest of the post before watching the video, otherwise it might not make sense.

boids

Playing with boids (you can jump to 0:45)

Attractor jump at 2:05 (which is pretty freakin cool)

I particularly like how they respond to the attractor (blue ball) once they’ve settled into an orbit- it’s like an amoeba reaching out and surrounding a smaller organism and then devouring it all at once.

There’s some music in here from this playlist.

So at one point, I was thinking of using part of the boid algorithm to determine the flight of cell groups as they headed towards control points, such that they would group and (when touching) merge into a larger group.  To see how this would work, and to try writing a reasonably fast implementation of the algorithm, I decided to test it in vpython.  I learned two immediate lessons.

1) small tweaks to coefficients == large changes when you only have a few coefficients and you make > 5% changes to one.

2) it’s very easy to set out to test something easy, have a small bug sidetrack you, and spend all day exploring some cool unexpected behavior because of that bug.

For the first, I was originally trying to get the boids to avoid obstacles, but they refused to turn around in time.  So I kept upping their avoidance until it was orders of magnitude larger, and then I realized that I’d had a problem with how I was aggregating their direction.  Once I fixed that, they suddenly lurched away from all obstacles, so strongly repelled by the massive coefficient that they never grouped and never changed path!  I brought the avoidance down to within 30% of the other numbers, and then as I tuned it realized that anything over 8% for any one steering trait would seriously throw off balance.  Tuning by 1-2% per iteration was time-consuming, but otherwise I would get crazy divergent behavior.

For the second, I continually had one or two boids running away, and after fixing the previous avoidance behavior, couldn’t seem to nail down what was happening.  To try and make debugging easier, I added the ability to “lock” the camera to a boid, and then use “[” and “]” to change which boid the camera would follow.  However, it was useless to print out the boid’s position history, or current weights, because it’s somewhat meaningless with 60 updates per sec.  So instead, I added trails to each boid, with the current lock colored yellow.

This was a good start, but then I thought “this is great! but it’s hard to get a sense of scale here….” so I added zooming in/out.

…Which was handy for gauging global positioning, but hard when they started to run away, so I thought “if I could just move left or right a bit…” and added panning.

…Which was a relatively quick change, and then I thought “It wouldn’t be too hard to report boid positions, periodically query the absolute position of the boid, move and drop an attractor, lock the attractor, …”

…And then it was 12 hours later and I’d written up a brief guide to key commands and added various tracking and… completely lost track of the original purpose of this project.

I’m actually glad I got so lost in a minor feature of that project, looking back now.  At the time, it really frustrated me that I had spent so much time on something that was supposed to decide “can I use boids here” and eventually just said “not right now”.  Now, it’s kind of cool, and I like to leave it on next to me while I code.  When people walk in to ask how it’s going, they usually comment on the cool visualizer, and there’s enough random sway and acceleration/deceleration of the camera that it feels like it almost matches whatever music is playing.

The lesson?  Sometimes it’s ok to get lost in a minor feature, because even if it doesn’t help you with the project you’re working on right then, it might turn into something really cool later on.  In fact, looking at it again today, I can already see some things I’d like to try messing around with- for example, alpha decay for the trails, so you can better see where the heads are.  That would be awesome!  But I was merely in here to grab code for tomorrow’s post… ugh.

Here’s the code, as promised above.  You will need Python 2.7 + a compatible version of vpython.  I believe 32bit versions are safest in both cases, but this script doesn’t rely on / care about 32v64.

Source pastebin

Command rundown and usage suggestions:

The boids are still a bit sensitive to sudden changes in attractor position, so try not to move it too far, or they’ll accelerate away and never regain stable orbit.

I’d recommend locking the attractor to start (hit T) and then zoom out to around ~0.11 and then hit “Y” to turn trails on, and “L” to lock on to a boid.  This will start the slow turning and rolling effect.

Then, slowly tap “]” to cycle through different boids, pausing a few seconds to compare the different orbit speeds/ turning speeds/ accelerations.

Pause the simulation at any time with “P” and then unlock with “L” to sweep the camera around by right clicking and dragging.

Panning isn’t correctly locked to current view, which means if you flip the camera over, “pan left” key will in fact “pan local right” which is “global left”.

Commands (from source):

Key  ::  Effect
R  ::  Toggle Reporting
T  ::  Pick up / Drop the “attractor” (blue orb)
Y  ::  Toggle Trails.
P  ::  Pause the Simulation.
U  ::  Update on position of highlighted boid
S  ::  Toggle “Slow Mode” not.. terribly impressive.
L  ::  Toggle Camera Lock; Follows the highlighted boid
[  ::  Follow previous boid
]  ::  Follow next boid
–  ::  Zoom Out
+  ::  Zoom In
Up  ::  Pan Up
Down  ::  Pan Down
Left  ::  Pan Left
Right  ::  Pan Right

=======
MOUSE
=======
LClick + Drag  ::  Nothing
RClick + Drag  ::  Rotate Camera
LCick+RClick + Drag  ::  Zoom In/Out

Advertisements

Written by delwinna

January 22, 2012 at 4:03 am

Posted in Projects, Python

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: