Taking a Random Walk

Inspired by this video by Simon Geilfus (which sadly hasn’t fared well with Vimeo’s compression-method), I decided to try something similar in Quartz Composer.

The basic idea, as outlined in Simon’s post, is very simple:
1. Place a point in 3D space
2. Take the position of the previous point, and add a small random offset on the X, Y and Z axes
3. Create a new point at the coordinates thus generated
4. Repeat, offsetting each new point from the coordinates of the last point.

Here’s some JavaScript:

3D Random-Walk experiment, inspired by Simon Geilfus’ video at

– PointsStruct –
output should be connected to Kineme GL Tools
Point/Quad/Triange Structure patches.

– LastX/Y/Z –
conect to GL Look At Center inputs (with smoothing)
so camera appears to follow point-drawing.

– dummy –
input fed from Patch Time to force updating every frame.

toneburst 2009

// Init array to hold points
var points = new Array();

// Init object to hold initial point
var p = new Object();
p.X = 0;
p.Y = 0;
p.Z = 0;
p.R = 0;
p.G = 0;
p.B = 0;

// Add point to array
points[0] = p;

// Init Frame/Iteration-counter variable
var frames = 1;

function (__structure PointsStruct,
__number LastX, __number LastY, __number LastZ,
__string NumPoints)
(__boolean Draw, __index MaxPoints, __number StepSize,
__number dummy)
if(!_testMode && Draw) {

// Fetch previous point from array
var previousPoint = points[frames – 1];

// Init temp Object variable to hold new point
var tmpP = new Object();

// Random 3D position based on offset from last point
tmpP.X = previousPoint.X + StepSize * (Math.random() – 0.5);
tmpP.Y = previousPoint.Y + StepSize * (Math.random() – 0.5);
tmpP.Z = previousPoint.Z + StepSize * (Math.random() – 0.5);
// Random RGB values (only works for Triangles and Quads)
tmpP.R = Math.random();
tmpP.G = Math.random();
tmpP.B = Math.random();

// Add point to array at index set by frames variable
points[frames] = tmpP;

// Increment frame-counter and reset frame-counter if MaxPoints exceeded.
// Reset to 1 rather than 0 so that previous point
// can be fetched from points array index 0 after reset
frames += 1;
frames = (frames < MaxPoints) ? frames : 1; // Init output object var result = new Object(); // Assign Points array to output object // (JavaScript array converted to QCStructure on output) result.PointsStruct = points; // Last point coordinates (for camera control) result.LastX = points[frames - 1].X; result.LastY = points[frames - 1].Y; result.LastZ = points[frames - 1].Z; // Number of iterations (for debugging) result.NumPoints = frames + " iterations"; // Output values return result; } }[/code] The key to rendering the data is the Kineme GL Tools Point/Line/Triangle/Quad Structure plugins, which takes a simple array of 3D points (and optionally colours, for the Triangle and Quad versions), and create 3D primitives from them. I've also added a stock fog effect to increase the sense of depth, and placed all the rendered objects inside a Kineme GL Tools Look At patch, which effectively makes the camera appear to follow the points as they are drawn. [vimeo 4607256] and another variation. [vimeo 4626625] This time, only complete triangles are drawn, and a Queue patch is used to keep track of the points (speeding things up quite a lot). and another [vimeo 4636184] in which I mess around with a GLSL fake depth-of-field effect on a set of point-sprites.


4 Responses to “Taking a Random Walk”

  1. 1 Rob
    May 12, 2009 at 11:54 am

    Wow, that’s very cool! I will have to have a play with the Kineme stuff some more!

    How do you get the camera to follow the newest point?

    • 2 toneburst
      May 12, 2009 at 1:41 pm

      The Kineme GL Tools patches ARE very cool, and a free download, so no reason not to give them a go, I think!

      The camera-following is down to the Kineme GL Look At macro patch, which uses the gluLookAt function to manipulate the OpenGL transformation matrices to effectively mimic a camera being pointed at a particular point (though in reality, there’s no such thing as a camera in OpenGL- it’s the objects in the scene that are moved, rather than your view of them). I just feed it the coordinates of the current point every frame, and Look At does the rest. I had to add some smoothing so the camera moved less jerkily, but apart from that, it just worked.

      Incidentally, it would actually be possible to mimic camera movements using JavaScript code and the 3D Transform patch. I was actually going to try that, but the Kineme patch is a much easier way of doing it.

  2. June 3, 2009 at 7:28 pm

    Good one!! I have been playing all day with this. very usefull!!!

    Is there any way to slow it down?? I am trying to slow down ‘dummy’ but it seems it just draws with any trigger data.

    Thank you!! 🙂

  3. 4 toneburst
    June 3, 2009 at 9:05 pm

    Hi Oscar.

    Thanks for the feedback, and glad you found it useful. It’s really just a proof-of-concept though, rather than a fully-finished piece. Nice tweaks to it though (just looking at your clip there)!

    You’re right about the ‘dummy’ input. It’s just there to force the JS patch to do its thing each frame. You could slow the whole thing down by sending a periodic trigger to this input, rather than a continuously-changing value. You’d find that the JS was executed every time you tweaked one of its settings though. Another alternative would be to add extra code to the JS so it only sent out a new point every nth frame.

    I’m working on other stuff at the moment, so I can’t work out the details right now, but maybe you can have a go yourself..



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


May 2009
« Apr   Jun »


Blog Stats

  • 468,884 hits

%d bloggers like this: