Forked from Mike Bostock's example
Last active
January 21, 2017 22:54
-
-
Save philipcdavis/86080a7d3d658f4e1ee3953410edd368 to your computer and use it in GitHub Desktop.
Mitchell's Best Candidate Bounded
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>Heart</title> | |
</head> | |
<style> | |
canvas { | |
margin: 0 auto; | |
display: block; | |
} | |
</style> | |
<body> | |
<div id="chart"></div> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> | |
<script type="text/javascript"> | |
var chart = d3.select("#chart"); | |
var canvas = chart.append("canvas"); | |
canvas.node().width = 1920; | |
canvas.node().height = 1000; | |
canvas.node().style.width = "960px"; | |
canvas.node().style.height = "500px"; | |
canvas.node().getContext('2d').scale(2,2); | |
var context = canvas.node().getContext("2d"); | |
var heart = new Path2D("M240.438984,75.1180229 C213.906656,13.0479209 138.485199,27.5290591 138.001548,99.5711057 C137.727478,139.139685 173.916719,153.927901 198.010636,169.746443 C221.387137,185.100328 238.004604,206.070503 240.608262,215 C242.841121,206.248285 261.360952,184.667995 282.988245,169.31411 C306.634785,152.521808 343.271403,138.703311 342.997334,99.1387726 C342.485469,26.9189442 265.766213,15.5207045 240.438984,75.1180229 Z"); | |
// forked from @mbostock's example | |
// https://bl.ocks.org/mbostock/6224050 | |
var maxRadius = 15, // maximum radius of circle | |
padding = 5, // padding between circles; also minimum radius | |
margin = {top: -maxRadius, right: -maxRadius, bottom: -maxRadius, left: -maxRadius}, | |
width = 960 - margin.left - margin.right, | |
height = 500 - margin.top - margin.bottom; | |
var k = 1, // initial number of candidates to consider per circle | |
m = 6, // initial number of circles to add per frame | |
n = 500, // remaining number of circles to add | |
newCircle = bestCircleGenerator(maxRadius, padding); | |
var timer = d3.timer(function(elapsed) { | |
if (elapsed > 1500) timer.stop(); | |
for (var i = 0; i < m && --n >= 0; ++i) { | |
var circle = newCircle(k); | |
context.beginPath(); | |
context.arc(circle[0], circle[1], circle[2], 0, 2 * Math.PI, false); | |
context.fillStyle = d3.interpolateOrRd(Math.random()); | |
context.fill(); | |
} | |
return !n; | |
}); | |
function bestCircleGenerator(maxRadius, padding) { | |
var quadtree = d3.quadtree().extent([[0, 0], [width, height]]), | |
searchRadius = maxRadius * 2, | |
maxRadius2 = maxRadius * maxRadius; | |
return function(k) { | |
var bestX, bestY, bestDistance = 0; | |
for (var i = 0; i < k || bestDistance < padding; ++i) { | |
var x = Math.random() * width; | |
var y = Math.random() * height; | |
// Check if point is in the SVG path | |
if (!context.isPointInPath(heart, x, y)) { | |
do { | |
x = Math.random() * width; | |
y = Math.random() * height; | |
} while (!context.isPointInPath(heart, x, y)) | |
} | |
var rx1 = x - searchRadius, | |
rx2 = x + searchRadius, | |
ry1 = y - searchRadius, | |
ry2 = y + searchRadius, | |
minDistance = maxRadius; // minimum distance for this candidate | |
quadtree.visit(function(node, x1, y1, x2, y2) { | |
if (p = node.data) { | |
var p, | |
dx = x - p[0], | |
dy = y - p[1], | |
d2 = dx * dx + dy * dy; | |
r2 = 10; | |
if (d2 < r2) return minDistance = 0, true; // within a circle | |
var d = Math.sqrt(d2) - p[2]; | |
if (d < minDistance) minDistance = d; | |
} | |
return !minDistance || x1 > rx2 || x2 < rx1 || y1 > ry2 || y2 < ry1; // or outside search radius | |
}); | |
if (minDistance > bestDistance) bestX = x, bestY = y, bestDistance = minDistance; | |
} | |
var best = [bestX, bestY, bestDistance - padding]; | |
quadtree.add(best); | |
return best; | |
}; | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment