(function() { // noprotect; /* BEGIN */ var BLUR, CX1, CX2, CY1, CY2, Fxy, MAX_D, R1, R2, a, b, canvas, color, colorize_inner, colorize_outer, ctx, dist1, dist2, g, hcl_linear_rainbow, height, image, pixel_i, pixel_x, pixel_y, r, side, value, width, x, y, _i, _j, _k, _l, _ref, _ref1, _ref2, _ref3; hcl_linear_rainbow = function() { var chroma_range, domain, hue_range, luminance_range, scale; domain = [0, 1]; hue_range = [340, 340 - 480]; chroma_range = [0, 40]; luminance_range = [0, 100]; scale = function(x) { var c, ext, h, l, xn; ext = domain[1] - domain[0]; xn = (x - domain[0]) / ext; h = hue_range[0] + (hue_range[1] - hue_range[0]) * xn; c = chroma_range[0] + (chroma_range[1] - chroma_range[0]) * (1 - Math.pow(1 - 2 * xn, 2)); l = luminance_range[0] + (luminance_range[1] - luminance_range[0]) * xn; h = Math.max(Math.min(h, d3.max(hue_range)), d3.min(hue_range)); c = Math.max(Math.min(c, d3.max(chroma_range)), d3.min(chroma_range)); l = Math.max(Math.min(l, d3.max(luminance_range)), d3.min(luminance_range)); return d3.hcl(h, c, l); }; scale.domain = function(x) { if (!arguments.length) { return domain; } domain = x; return scale; }; scale.hue_range = function(x) { if (!arguments.length) { return hue_range; } hue_range = x; return scale; }; scale.chroma_range = function(x) { if (!arguments.length) { return chroma_range; } chroma_range = x; return scale; }; scale.luminance_range = function(x) { if (!arguments.length) { return luminance_range; } luminance_range = x; return scale; }; return scale; }; /* END */ /* define the distance function for two circles */ CX1 = 0.5; CY1 = 0.5; R1 = 0.25; dist1 = function(x, y) { return R1 - (Math.pow(x - CX1, 2) + Math.pow(y - CY1, 2)) / R1; }; CX2 = 0.7; CY2 = 0.7; R2 = 0.2; dist2 = function(x, y) { return R2 - (Math.pow(x - CX2, 2) + Math.pow(y - CY2, 2)) / R2; }; /* Draw the distance function */ canvas = d3.select('#left'); width = canvas.node().getBoundingClientRect().width; height = canvas.node().getBoundingClientRect().height; side = Math.min(width, height) - 20; ctx = canvas.node().getContext('2d'); image = ctx.createImageData(side, side); /* define a default cubehelix-style hcl linear rainbow scale */ MAX_D = Math.sqrt(2) / 4; colorize_inner = hcl_linear_rainbow().domain([MAX_D, 0]).hue_range([200, 200 + 90]); colorize_outer = hcl_linear_rainbow().domain([-MAX_D, 0]).hue_range([200 - 180, 200 - 180 + 90]); console.debug('Coloring...'); for (pixel_x = _i = 0; 0 <= side ? _i < side : _i > side; pixel_x = 0 <= side ? ++_i : --_i) { for (pixel_y = _j = 0; 0 <= side ? _j < side : _j > side; pixel_y = 0 <= side ? ++_j : --_j) { pixel_i = (pixel_y * side + pixel_x) * 4; _ref = [pixel_i + 0, pixel_i + 1, pixel_i + 2, pixel_i + 3], r = _ref[0], g = _ref[1], b = _ref[2], a = _ref[3]; _ref1 = [pixel_x / side, pixel_y / side], x = _ref1[0], y = _ref1[1]; Fxy = Math.min(dist1(x, y), -dist2(x, y)); if (Fxy > 0) { color = d3.rgb(colorize_inner(Fxy)); } else { color = d3.rgb(colorize_outer(Fxy)); } image.data[r] = color.r; image.data[g] = color.g; image.data[b] = color.b; image.data[a] = 255; } } ctx.putImageData(image, (width - side) / 2, (height - side) / 2); /* Draw the reconstructed shape */ canvas = d3.select('#right'); width = canvas.node().getBoundingClientRect().width; height = canvas.node().getBoundingClientRect().height; side = Math.min(width, height) - 20; ctx = canvas.node().getContext('2d'); image = ctx.createImageData(side, side); BLUR = 3; for (pixel_x = _k = 0; 0 <= side ? _k < side : _k > side; pixel_x = 0 <= side ? ++_k : --_k) { for (pixel_y = _l = 0; 0 <= side ? _l < side : _l > side; pixel_y = 0 <= side ? ++_l : --_l) { pixel_i = (pixel_y * side + pixel_x) * 4; _ref2 = [pixel_i + 0, pixel_i + 1, pixel_i + 2, pixel_i + 3], r = _ref2[0], g = _ref2[1], b = _ref2[2], a = _ref2[3]; _ref3 = [pixel_x / side, pixel_y / side], x = _ref3[0], y = _ref3[1]; Fxy = Math.min(dist1(x, y), -dist2(x, y)); value = Math.min(1 + Fxy / (BLUR / side), 1); image.data[r] = 255; image.data[g] = 255; image.data[b] = 255; image.data[a] = value * 255; } } ctx.putImageData(image, (width - side) / 2, (height - side) / 2); }).call(this);