diff --git a/lindenmayer-system/lindenmeyer-system.html b/lindenmayer-system/lindenmeyer-system.html index 8a2df2a..8e62c9b 100644 --- a/lindenmayer-system/lindenmeyer-system.html +++ b/lindenmayer-system/lindenmeyer-system.html @@ -182,6 +182,70 @@ function sierpinski() { } + /************************************************ + * some other tree + ************************************************/ + + function other_tree(num_defects) { + project.clear(); + if(typeof num_defects == 'undefined') { num_defects = 0 }; + var r = generate( + 'iIjX'.split(''), + [ + ['X'.split(''), 'F[-lfX][cfX][+rfX]'.split('')], + //['F'.split(''), 'FF'.split('')], + //['L'.split(''), 'LL'.split('')], + //['C'.split(''), 'CC'.split('')], + //['R'.split(''), 'RR'.split('')], + ], + 8 + ); + + var n = 0; + while(n < num_defects) { + var rnd = Math.floor(Math.random()*r.length); + if((r[rnd] != '[') & (r[rnd] != ']')) { + r[rnd] = '*'; + if(Math.random() > 0.9) { + if(Math.random() < 0.5) { + r.splice(rnd, 0, '+'); + } else { + r.splice(rnd, 0, '-'); + } + } + n += 1; + } + } + + console.log(r); + var p = draw( + r, + { + 'F': draw_forward(), + 'f': draw_forward(0.5), + + 'l': draw_stepsize_mul(0.7), + 'c': draw_stepsize_mul(0.8), + 'r': draw_stepsize_mul(0.7), + + 'i': draw_set_dir(Math.PI), + 'I': draw_angle_init(25/180 * Math.PI), + 'j': draw_set_turn_noise(1), + + '*': draw_angle_add((Math.random() - 0.5) * 0.01), + '-': draw_angle_turn(-1), + '+': draw_angle_turn(1), + '[': draw_state_push(), + ']': draw_state_pop(), + } + ); + p.scale(60); + p.translate(new Point(200, 200)); + p.strokeWidth = 1; + p.strokeColor = '#ff00ff'; + } + + /************************************************ * ************************************************/ @@ -190,6 +254,7 @@ globals.dragon_curve = dragon_curve; globals.sierpinski2 = sierpinski2; globals.sierpinski = sierpinski; globals.barnsley_fern = barnsley_fern; +globals.other_tree = other_tree; globals.get_svg = function() { return project.exportSVG({asString: true}); @@ -247,6 +312,10 @@ window.onload = function() { window.globals.barnsley_fern(150); }); + document.getElementById('other-tree').addEventListener('click', function() { + window.globals.other_tree(); + }); + } @@ -260,6 +329,7 @@ window.onload = function() { +
diff --git a/lindenmayer-system/lindenmeyer-system.js b/lindenmayer-system/lindenmeyer-system.js index 23e29a6..ea1f801 100644 --- a/lindenmayer-system/lindenmeyer-system.js +++ b/lindenmayer-system/lindenmeyer-system.js @@ -52,6 +52,10 @@ function generate(start, rules, iterations) { function draw_initstate(p, state) { if(!('dir' in state)) { state.dir = 0; + state.turnnoise = 0; + } + if(!('stepsize' in state)) { + state.stepsize = 1; } if(!('curpath' in state)) { p.addChild(new paper.Path()); @@ -67,7 +71,14 @@ function draw_set_dir(dir) { } -function draw_forward() { +function draw_set_turn_noise(level) { + return function(p, state) { + state.turnnoise = level; + } +} + + +function draw_forward(factor=1) { return function(p, state) { draw_initstate(p, state); if(state.curpath.segments.length == 0) { @@ -76,12 +87,26 @@ function draw_forward() { } var lastp = state.curpath.segments[state.curpath.segments.length - 1].point; state.curpath.add(lastp.add( - new paper.Point(Math.sin(state.dir), Math.cos(state.dir)) + new paper.Point(Math.sin(state.dir) * state.stepsize * factor, + Math.cos(state.dir) * state.stepsize * factor) )); } } +function draw_stepsize_mul(factor) { + return function(p, state) { + if(typeof factor == 'function') { + var f = factor(); + } else { + var f = factor; + } + draw_initstate(p, state); + state.stepsize *= f; + }; +} + + function draw_turn(angle) { return function(p, state) { draw_initstate(p, state); @@ -93,7 +118,8 @@ function draw_turn(angle) { function draw_angle_turn(fac) { return function(p, state) { draw_initstate(p, state); - state.dir += state.angle * fac; + var a = state.angle * (1 + (Math.random() - 0.5) * state.turnnoise); + state.dir += a * fac; } } @@ -120,6 +146,7 @@ function draw_state_push() { state.stack.push({ pos: state.curpath.segments[state.curpath.segments.length - 1].point, dir: state.dir, + stepsize: state.stepsize, }); } } @@ -129,6 +156,7 @@ function draw_state_pop() { return function(p, state) { var s = state.stack.pop(); state.dir = s.dir; + state.stepsize = s.stepsize; p.addChild(new paper.Path()); state.curpath = p.lastChild; state.curpath.add(s.pos);