// Generated by CoffeeScript 1.10.0 (function() { var F_ROTATION_INDEXES, GOSPER_ANGLE, INITIAL_SCALE, ROTATION_INDEXES, data, get_hept_coords, get_hex_data, height, hexes, order, rec, svg, vis, width; width = 960; height = 500; data = []; INITIAL_SCALE = height / 2.4; GOSPER_ANGLE = Math.acos(5 * Math.sqrt(7) / 14) / Math.PI * 180; ROTATION_INDEXES = [0, 120, 0, -120, 0, 0, -120]; F_ROTATION_INDEXES = [-120, 0, 0, -120, 0, 120, 0]; svg = d3.select('svg').attr({ width: width, height: height, viewBox: (-width / 2) + " " + (-height / 2) + " " + width + " " + height }); vis = svg.append('g'); get_hept_coords = function(scale, indexes, index_i) { var a, coords, flip, i, j, len, r, ref; a = scale / Math.sqrt(7); r = a / Math.sin(Math.PI / 3); coords = [ { x: -a, y: r + r / 2 }, { x: a, y: r + r / 2 }, { x: 0, y: 0 }, { x: -2 * a, y: 0 }, { x: -a, y: -r - r / 2 }, { x: a, y: -r - r / 2 }, { x: 2 * a, y: 0 } ]; flip = false; if (index_i > 0) { ref = indexes.slice(0, index_i); for (j = 0, len = ref.length; j < len; j++) { i = ref[j]; if (!flip && (i === 1 || i === 2 || i === 6)) { flip = !flip; } else if (flip && (i === 0 || i === 4 || i === 5)) { flip = !flip; } } } if (flip) { coords.reverse(); } return { coords: coords[indexes[index_i]], flip: flip }; }; /* Returns the rotation, translation and scale of a certain hexagon described as a base 7 number */ get_hex_data = function(indexes) { var f_rotation, hept_coords, i, index, j, len, result, rotation, scale, scale_i, translation; rotation = GOSPER_ANGLE * indexes.length; f_rotation = 0; translation = { x: 0, y: 0 }; scale = 1 / Math.pow(Math.sqrt(7), indexes.length); for (i = j = 0, len = indexes.length; j < len; i = ++j) { index = indexes[i]; scale_i = 1 / Math.pow(Math.sqrt(7), i); result = get_hept_coords(scale_i, indexes, i); hept_coords = result.coords; hept_coords = hept_tree_utils.rotate_point(hept_coords, GOSPER_ANGLE * (i + 1)); hept_coords = hept_tree_utils.rotate_point(hept_coords, f_rotation); f_rotation += result.flip ? F_ROTATION_INDEXES[index] : ROTATION_INDEXES[index]; translation.x += hept_coords.x; translation.y += hept_coords.y; } return { rotation: rotation, frotation: f_rotation, translation: translation, scale: scale }; }; rec = function(order, index) { var i, j, results; if (order === 0) { data.push({ index: index, data: get_hex_data(index) }); return; } data.push({ index: index, data: get_hex_data(index) }); results = []; for (i = j = 0; j <= 6; i = ++j) { results.push(rec(order - 1, index.concat([i]))); } return results; }; order = Math.floor(Math.random() * 5); rec(order, []); vis.append('g').attr({ transform: "translate(" + (-width / 2 + 50) + ", " + (-height / 2 + 50) + ")" }).append('text').text("Order " + order); hexes = vis.selectAll('path').data(data); hexes.enter().append('path').attr({ "class": 'hex', d: function(d) { return hept_tree_utils.hex_generate_svg_path(d.data.scale * INITIAL_SCALE, 0); }, transform: function(d) { return "translate(" + (d.data.translation.x * INITIAL_SCALE) + ", " + (d.data.translation.y * INITIAL_SCALE) + ") rotate(" + d.data.rotation + ")"; } }); data = data.filter(function(d) { return d.index.length === order; }).sort(function(a, b) { return d3.ascending(a.index.join(''), b.index.join('')); }); vis.append('path').attr({ "class": 'curve', d: "M" + data.map(function(d) { return [d.data.translation.x * INITIAL_SCALE, d.data.translation.y * INITIAL_SCALE].join(' '); }).join('L'), fill: 'none', stroke: 'steelblue' }); }).call(this);