/* compute a Lindenmayer system given an axiom, a number of steps and rules */ (function() { var collapse, curves, fractal, fractalize, height, side, steps, svg, svg_path, width; fractalize = function(config) { var char, i, input, output, _i, _len, _ref; input = config.axiom; for (i = 0, _ref = config.steps; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) { output = ''; for (_i = 0, _len = input.length; _i < _len; _i++) { char = input[_i]; if (char in config.rules) { output += config.rules[char]; } else { output += char; } } input = output; } return output; }; /* convert a Lindenmayer string into an SVG path string */ svg_path = function(config) { var angle, char, path, _i, _len, _ref; angle = 0.0; path = 'M0 0'; _ref = config.fractal; for (_i = 0, _len = _ref.length; _i < _len; _i++) { char = _ref[_i]; if (char === '+') { angle += config.angle; } else if (char === '-') { angle -= config.angle; } else if (char === 'F') { path += "l" + (config.side * Math.cos(angle)) + " " + (config.side * Math.sin(angle)); } } return path; }; side = 6; curves = []; for (steps = 1; steps <= 6; steps++) { fractal = fractalize({ axiom: 'A', steps: steps, rules: { A: '-BF+AFA+FB-', B: '+AF-BFB-FA+' } }); curves.push(svg_path({ fractal: fractal, side: side, angle: Math.PI / 2 })); } width = 960; height = 500; svg = d3.select('body').append('svg').attr('width', width).attr('height', height); svg.selectAll('.curve').data(curves).enter().append('path').attr('class', 'curve').attr('d', function(d) { return d; }).attr('transform', function(d, i) { return "translate(" + (70 + (Math.pow(2, i + 1) + i) * side) + ",430) " + (i % 2 ? 'rotate(90)scale(-1,1)' : ''); }).attr('opacity', 1); collapse = false; svg.on('click', function() { collapse = !collapse; if (collapse) { return svg.selectAll('.curve').transition().duration(1000).attr('transform', function(d, i) { return "translate(300,430) " + (i % 2 ? 'rotate(90)scale(-1,1)' : ''); }).attr('opacity', 0.2); } else { return svg.selectAll('.curve').transition().duration(1000).attr('transform', function(d, i) { return "translate(" + (70 + (Math.pow(2, i + 1) + i) * side) + ",430) " + (i % 2 ? 'rotate(90)scale(-1,1)' : ''); }).attr('opacity', 1); } }); }).call(this);