// Generated by CoffeeScript 1.10.0 (function() { var F_ROTATION_INDEXES, GOSPER_ANGLE, INITIAL_SCALE, ROTATION_INDEXES, base7_numbers, class_number, color, compare_base7_numbers, data, get_class, get_hept_coords, get_hex_data, height, hexes, i, initial_translation, j, max_hex, numbers, order, rec, ref, svg, width, zoom, zoomable_layer; width = 960; height = 500; data = []; INITIAL_SCALE = height / 25; 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]; order = Math.floor(Math.random() * 6); color = d3.scale.ordinal().domain(["class1", "class2", "class3", "class4", "class5", "class6", "class7", ""]).range(["#fb8072", "#80b1d3", "#fdb462", "#b3de69", "#8dd3c7", "#ffffb3", "#bebada", "#f2f2f2"]); svg = d3.select('svg').attr({ width: width, height: height, viewBox: (-width / 2) + " " + (-height / 2) + " " + width + " " + height }); zoomable_layer = svg.append('g'); zoom = d3.behavior.zoom().scaleExtent([0, 2]).on('zoom', function() { zoomable_layer.attr({ transform: "translate(" + (zoom.translate()) + ")scale(" + (zoom.scale()) + ")" }); return zoomable_layer.selectAll('.semantic_zoom').attr({ transform: "scale(" + (1 / zoom.scale()) + ")" }); }); svg.call(zoom); 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 } ]; /*coords = [ {x: 0, y: 0}, {x: 2*a, y: 0}, {x: a, y: -(r+r/2)}, {x: -a, y: -(r+r/2)}, {x: 0, y: -3*r}, {x: 2*a, y: -3*r}, {x: 3*a, y: -(r+r/2)} ] */ 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 and translation 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_i, translation; rotation = GOSPER_ANGLE * (indexes.length - order); f_rotation = 0; translation = { x: 0, y: 0 }; for (i = j = 0, len = indexes.length; j < len; i = ++j) { index = indexes[i]; scale_i = 1 / Math.pow(Math.sqrt(7), i - order); 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 - order)); 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 }; }; compare_base7_numbers = function(a, b) { return parseInt(a.join('')) < parseInt(b.join('')); }; get_class = function(index) { var i, j, len, n; for (i = j = 0, len = base7_numbers.length; j < len; i = ++j) { n = base7_numbers[i]; if (compare_base7_numbers(index, n)) { return "class" + (i + 1); } } return ""; }; rec = function(order, index) { var i, j, results; if (order === 0) { data.push({ index: index, data: get_hex_data(index), "class": get_class(index) }); return; } results = []; for (i = j = 0; j <= 6; i = ++j) { results.push(rec(order - 1, index.concat([i]))); } return results; }; /* Initialization */ max_hex = Math.pow(7, order); class_number = Math.floor(Math.random() * 7); numbers = []; base7_numbers = []; for (i = j = 0, ref = class_number; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) { numbers.push(Math.floor(Math.random() * (max_hex - d3.sum(numbers)))); base7_numbers.push(hept_tree_utils.base10_to_base7(d3.sum(numbers))); } rec(order, []); initial_translation = data[0].data.translation; svg.append('g').attr({ transform: "translate(" + (-width / 2 + 20) + ", " + (-height / 2 + 40) + ")" }).append('text').text("Order " + order); hexes = zoomable_layer.selectAll('path').data(data); hexes.enter().append('path').attr({ "class": 'hex', d: function(d) { return hept_tree_utils.hex_generate_svg_path(INITIAL_SCALE, 0); }, transform: function(d) { return "translate(" + ((d.data.translation.x - initial_translation.x) * INITIAL_SCALE) + ", " + ((d.data.translation.y - initial_translation.y) * INITIAL_SCALE) + ") rotate(" + d.data.rotation + ")"; }, fill: function(d) { return color(d["class"]); }, stroke: '#FFF', 'stroke-width': function() { if (order < 5) { return 2; } else { return 1; } } }); }).call(this);