Inspired by a query from 2bitpunk, I decided yesterday to have another go at Bezier curves.

I’ve looked at this in the past, and have always been really confused by the maths, or found sourcecode, but been unable to separate-out the relevant maths from the rest of the code. Yesterday though, I stumbled on this page, which had the necessary equation without a load of confusing explanation, that, with my mathematical myopia, I wouldn’t stand a cat’s chance in hell of understanding (as the phrase goes).

Soo… after an hour or so of swearing at QC’s buggy JavaScript module, I managed to put together a simple 2-point Bezier demo. Ironically, in the end, it was the dragging-control-points bit that took the most hair-tearing to implement. My eventual solution to that problem wasn’t ideal, but was functional, at least.

Here’s the JS code to generate a Bezier Curve with a settable number of steps, taking as input 4 2D points (2 anchor-points, 2 control-points/handles) and outputting a structure of points in 3D space descibing the resulting curve. There’s also a chunk of code to output a second structure containing the coordinates of the anchor and control-points, so you can see where they are:

/* Bezier curve between 2 points, with 2 control-points. http://freespace.virgin.net/hugo.elias/graphics/x_bezier.htm */ function bezier(A, B, D, C, t) { // Note I've reversed the order of C and D so that // anchor and control-points are in more intuitive order var a = t; var b = 1 - t; var out= A * Math.pow(b, 3) + 3 * B * Math.pow(b, 2) * a + 3 * C * b * Math.pow(a, 2) + D * Math.pow(a, 3); return out; } function (__structure Points_Struct, __structure Controlpoints_Struct) main (__number P0_X, __number P0_Y, __number P1_X, __number P1_Y, __number P2_X, __number P2_Y, __number P3_X, __number P3_Y, __index Steps) { if(!_testMode) { /* P0 is first anchorpoint, P1 first controlpoint P2 is second anchorpoint, P3 second controlpoint (see note in bezier function) */ // Init output arrays var points = new Array(); var controlpoints = new Array(); // Time-increment amount var stepSize = 1 / Steps; // Curve with steps segments for(i = 0; i <= Steps; i++) { var thisPoint = new Object(); t = stepSize * i; thisPoint.X = bezier(P0_X, P1_X, P2_X, P3_X, t); thisPoint.Y = bezier(P0_Y, P1_Y, P2_Y, P3_Y, t); thisPoint.Z = 0; points[i] = thisPoint; } // Control-points var thisControlpoint = new Object(); thisControlpoint.X = P0_X; thisControlpoint.Y = P0_Y; thisControlpoint.Z = 0; controlpoints[0] = thisControlpoint; var thisControlpoint = new Object(); thisControlpoint.X = P1_X; thisControlpoint.Y = P1_Y; thisControlpoint.Z = 0; controlpoints[1] = thisControlpoint; var thisControlpoint = new Object(); thisControlpoint.X = P2_X; thisControlpoint.Y = P2_Y; thisControlpoint.Z = 0; controlpoints[2] = thisControlpoint; var thisControlpoint = new Object(); thisControlpoint.X = P3_X; thisControlpoint.Y = P3_Y; thisControlpoint.Z = 0; controlpoints[3] = thisControlpoint; // Output var result = new Object(); result.Points_Struct = points; result.Controlpoints_Struct = controlpoints; return result; } }

It would be easy to extend the curve into 3D space by simply passing the Z-coords to the Bezier function too, rather than just setting Z to a constant.

Example video clip:

I think my mistake in the past has been to try and implement Bezier curve-drawing in a fragment shader/CIFilter, whereas it’s much easier to simple generate a load of points, and then draw them using 3D geometry.

EDIT:

Check out this lovely piece for work by Jeogho Park, using the above bezier JavaScript code.

Buggy JavaScript? Ai ai ai… QC annoys me… I’m not the only one to notice the audio input patch doesn’t seem to correspond to any particular frequencies around 13/14/15… harumph…

Bezier curve looks like fun… Didn’t someone do this in Processing the other week? What am I thinking of… something where you put random points down and it extrapolates a nice shape that continues… probably Memo did it…!

Hi Rob,

I think you’re thinking of something else there, mate. I don’t really keep up with the Processing community, to be honest. Probably should, mind you…

The Audio Input patch is an odd one, you’re right. It’s the non-normalized levels you get out of it that annoy me, though…

a|x