Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active November 27, 2016 10:58
Show Gist options
  • Save nitaku/ce638f8bd5e70cb809e1 to your computer and use it in GitHub Desktop.
Save nitaku/ce638f8bd5e70cb809e1 to your computer and use it in GitHub Desktop.
Node Gosper curve
### compute a Lindenmayer system given an axiom, a number of steps and rules ###
fractalize = (config) ->
input = config.axiom
for i in [0...config.steps]
output = ''
for char in input
if char of config.rules
output += config.rules[char]
else
output += char
input = output
return output
### convert a Lindenmayer string into an SVG path string ###
svg_path = (config) ->
angle = 0.0
path = 'M0 0'
for char in config.fractal
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 = () ->
gosper = fractalize
axiom: 'A'
steps: 4
rules:
A: 'A-FB--FB-F++AF++A-F+AF+B-'
B: '+A-FB-F+B--FB--F+AF++AF+B'
# A: 'A+BF++BF-FA--FAFA-BF+'
# B: '-FA+BFBF++BF+FA--FA-B'
d = svg_path
fractal: gosper
side: 8
angle: Math.PI/3
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(680,300)')
svg.append('path')
.attr('class', 'curve')
.attr('d', d)
.attr('transform', 'translate(680,300)')
.call(transition)
### animate the path ###
### from Mike Bostock's stroke dash interpolation example http://bl.ocks.org/mbostock/5649592 ###
tweenDash = () ->
l = this.getTotalLength()
i = d3.interpolateString('0,' + l, l + ',' + l)
return (t) -> i(t)
transition = (path) ->
path.transition()
.duration(20000)
.attrTween('stroke-dasharray', tweenDash)
.curve {
fill: none;
stroke: black;
stroke-width: 1.5px;
}
.shadow {
opacity: 0.1;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Gosper curve</title>
<link type="text/css" href="index.css" rel="stylesheet"/>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="index.js"></script>
</head>
<body onload="main()"></body>
</html>
// Generated by CoffeeScript 1.4.0
/* 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, _j, _len, _ref;
input = config.axiom;
for (i = _i = 0, _ref = config.steps; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
output = '';
for (_j = 0, _len = input.length; _j < _len; _j++) {
char = input[_j];
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, gosper, height, svg, width;
gosper = fractalize({
axiom: 'A',
steps: 4,
rules: {
A: 'A-FB--FB-F++AF++A-F+AF+B-',
B: '+A-FB-F+B--FB--F+AF++AF+B'
}
});
d = svg_path({
fractal: gosper,
side: 8,
angle: Math.PI / 3
});
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(680,300)');
return svg.append('path').attr('class', 'curve').attr('d', d).attr('transform', 'translate(680,300)').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);
.curve
fill: none
stroke: black
stroke-width: 1.5px
.shadow
opacity: 0.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment