|
/* compute a Lindenmayer system given an axiom, a number of steps and rules |
|
*/ |
|
|
|
(function() { |
|
var fractalize, svg_path, transition, tweenDash; |
|
|
|
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; |
|
}; |
|
|
|
window.main = function() { |
|
var d, height, moore, svg, width; |
|
moore = fractalize({ |
|
axiom: 'AFA+F+AFA', |
|
steps: 5, |
|
rules: { |
|
A: '-BF+AFA+FB-', |
|
B: '+AF-BFB-FA+' |
|
} |
|
}); |
|
d = svg_path({ |
|
fractal: moore, |
|
side: 6, |
|
angle: Math.PI / 2 |
|
}); |
|
width = 960; |
|
height = 500; |
|
svg = d3.select('body').append('svg').attr('width', width).attr('height', height); |
|
svg.append('path').attr('class', 'curve shadow').attr('d', d).attr('transform', 'translate(300,250)'); |
|
return svg.append('path').attr('class', 'curve').attr('d', d).attr('transform', 'translate(300,250)').call(transition); |
|
}; |
|
|
|
/* animate the path |
|
*/ |
|
|
|
/* from Mike Bostock's stroke dash interpolation example http://bl.ocks.org/mbostock/5649592 |
|
*/ |
|
|
|
tweenDash = function() { |
|
var i, l; |
|
l = this.getTotalLength(); |
|
i = d3.interpolateString('0,' + l, l + ',' + l); |
|
return function(t) { |
|
return i(t); |
|
}; |
|
}; |
|
|
|
transition = function(path) { |
|
return path.transition().duration(20000).attrTween('stroke-dasharray', tweenDash); |
|
}; |
|
|
|
}).call(this); |