Tuesday, March 16, 2010

L-System v2



 

I have modified my previous L-System demo and added a few new features. Click on the image on the left to load the canvas demo. The axiom, rules and angle are now in editable fields, so you can change them and click [update] to view. This makes it quite quick to play around and explore l-systems. For the code internals, I separated out the l-system code into its own .js file, and also changed how the turtle works. Instead of a case statement, it now uses a map of functions, which looks like this:

return {
    // Turn right
    '+': function(args) { args.ctx.rotate(vary( args.angle, args.angle * args.angleVariance)); },
    // Turn left
    '-': function(args) { args.ctx.rotate(vary(-args.angle, args.angle * args.angleVariance)); },
    // Push
    '[': function(args) { args.ctx.save(); args.depth++; },
    // Pop
    ']': function(args) { args.ctx.restore(); args.depth--; },
    // Draw forward by length computed by recursion depth
    '|': function(args) { args.distance /= Math.pow(2.0, args.depth); drawForward() },
    'F': drawForward,
    'A': drawForward,
    'B': drawForward,
    'G': goForward
};
This makes it extremely easy to add new turtle commands, for instance to draw a green dot every time you see a 'L' just add the following to the map:
turtleHandler['L'] = function(args) {
args.ctx.fillStyle = '#00ff00';
args.ctx.beginPath();
args.ctx.arc(0, 0, 2, 0, 2 * Math.PI, true);
args.ctx.fill();
}
This was used to draw the leaves in the image above. To get 'L's in the right place in the l-system, I used 'L->' as the first rule, which deletes all existing 'L's, so the only ones that remain at the end of the iterations are the most recently created ones, which are on the (appropriately named) leaf nodes. TODO: Make extra functions an editable field, make better alignment/zooming.

No comments:

Post a Comment