diff options
| author | Yuval Adam <yuv.adm@gmail.com> | 2012-05-18 11:04:06 +0300 |
|---|---|---|
| committer | Yuval Adam <yuv.adm@gmail.com> | 2012-05-18 11:04:06 +0300 |
| commit | c900d290a3d86a4486ac2a8790de0b89b914c47d (patch) | |
| tree | cb6d7542e07741fd0ad9eb491a2eeed05ecc2ae9 | |
| parent | 3c3aabf0522eed2cf1fdbb4a934606deca091040 (diff) | |
initial lsys.js import
| -rw-r--r-- | lsys.js | 143 |
1 files changed, 143 insertions, 0 deletions
@@ -0,0 +1,143 @@ +// L-System as defined in +// http://en.wikipedia.org/wiki/L-system + +// Example usage: +// lsys = LSystem('F', { 'F' : 'F-F+FF' }); +// tree = lsys.iterate(2) + +function LSystem(axiom, rules) { + this.axiom = axiom; + this.rules = rules; + this.tree = axiom; + + this.iterate = function(n) { + for (var i=0; i<n; i++) { + this.tree = this.tree.replace(/\w/g, function(c) { + return rules[c] || c; + }); + } + return this.tree; + }; + + this.draw = function(alpha) { + if (alpha === undefined) + alpha = 90 * (Math.PI / 180); + + var coords = []; + var stack = []; + var geometry = [[0,0,0]]; + + var x = 0, y = 0, z = 0; // cartesian coordinates + var nx = 0, ny = 1, nz = 0; // next step delta + var H = 0, L = 0, U = 0; // headings on 3 axes + var RUu = false, RLu = false, RHu = false; + + for (var i=0; i<this.tree.length; i++) { + var c = this.tree.charAt(i); + switch(c) { + case '+': + U += alpha; + RUu = true; + break; + case '-': + U -= alpha; + RUu = true; + break; + + case '&': + L += alpha; + RLu = true; + break; + case '^': + L -= alpha; + RLu = true; + break; + + case '<': + H += alpha; + RHu = true; + break; + case '>': + H -= alpha; + RHu = true; + break; + + case '|': + U += Math.PI / 2; + RUu = true; + break; + // push and pop branch + case '[': + stack.push(x, y, z, H, L, U, geometry); + geometry = [[x,y,z]]; + break; + case ']': + coords.push(geometry); + geometry = stack.pop(); + U = stack.pop(); + L = stack.pop(); + H = stack.pop(); + z = stack.pop(); + y = stack.pop(); + x = stack.pop(); + break; + // forward draw + case 'F': + nx = 0, ny = 1, nz = 0; + nc = this.tree.charAt(i+1); + + if (RUu) { + var tx = (nx * Math.cos(U)) - (ny * Math.sin(U)); + var ty = (nx * Math.sin(U)) + (ny * Math.cos(U)); + nx = tx; + ny = ty; + + if (nc != 'F') + RUu = false; + } + + if (RLu) { + var tx = (nx * Math.cos(L)) + (nz * Math.sin(L)); + var tz = -(nx * Math.sin(L)) + (nz * Math.cos(L)); + nx = tx; + nz = tz; + + if (nc != 'F') + RLu = false; + } + + if (RHu) { + var ty = (ny * Math.cos(H)) + (nz * Math.sin(H)); + var tz = -(ny * Math.sin(H)) + (nz * Math.cos(H)); + ny = ty; + nz = tz; + + if (nc != 'F') + RHu = false; + } + + x += nx; + y += ny; + z += nz; + + geometry.push([x,y,z]); + break; + } + } + + coords.push(geometry); + return coords; + }; + + this.reset = function() { + this.tree = axiom; + return this.tree; + }; + + this.debug = function() { + console.log('Axiom: ' + this.axiom); + console.log('Rules: ' + this.rules); + console.log('Tree: ' + this.tree); + }; + +} |
