Last active
July 23, 2016 20:58
-
-
Save vgonda/13f0047be7694af4ada1bd6b5336acf9 to your computer and use it in GitHub Desktop.
Collision Detection (modification of http://bl.ocks.org/mbostock/3231298)
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 http-equiv="Content-Type" content="text/html; charset=UTF-8"> | |
</head><body data-pinterest-extension-installed="cr1.39.2"> | |
<script src="./collision_detection_files/d3.v3.min.js"></script> | |
<script> | |
var width = 960, | |
height = 500; | |
var nodes = d3.range(200).map(function() { return {radius: Math.random() * 12 + 4}; }), | |
root = nodes[0], | |
color = d3.scale.category20(); | |
root.radius = 0; | |
root.fixed = true; | |
var force = d3.layout.force() | |
.gravity(0.05) | |
.charge(function(d, i) { return i ? 0 : -2000; }) | |
.nodes(nodes) | |
.size([width, height]); | |
force.start(); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
svg.selectAll("circle") | |
.data(nodes.slice(1)) | |
.enter().append("circle") | |
.attr("r", function(d) { return d.radius; }) | |
.style("fill", function(d, i) { return color(i % 3); }); | |
force.on("tick", function(e) { | |
var q = d3.geom.quadtree(nodes), | |
i = 0, | |
j = 0, | |
n = nodes.length; | |
while (++i < n) q.visit(collide(nodes[i])); | |
svg.selectAll("circle") | |
.attr("cx", function(d) { return d.x; }) | |
.attr("cy", function(d) { return d.y; }); | |
}); | |
svg.on("mousemove", function() { | |
var p1 = d3.mouse(this); | |
root.px = p1[0]; | |
root.py = p1[1]; | |
force.resume(); | |
}); | |
function collide(node) { | |
detectEdge(node) | |
var r = node.radius + 16, | |
nx1 = node.x - r, | |
nx2 = node.x + r, | |
ny1 = node.y - r, | |
ny2 = node.y + r; | |
return function(quad, x1, y1, x2, y2) { | |
if (quad.point && (quad.point !== node)) { | |
var x = node.x - quad.point.x, | |
y = node.y - quad.point.y, | |
l = Math.sqrt(x * x + y * y), | |
r = node.radius + quad.point.radius; | |
if (l < r) { | |
l = (l - r) / l * .5; | |
node.x -= x *= l; | |
node.y -= y *= l; | |
quad.point.x += x; | |
quad.point.y += y; | |
} | |
} | |
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1; | |
}; | |
} | |
function detectEdge(node) { | |
var r = node.radius + 16; | |
if (node.x - r < 0) { | |
node.x = r; | |
} if (node.x + r > width) { | |
node.x = width - r; | |
} if (node.y - r < 0) { | |
node.y = r; | |
} if (node.y + r > height) { | |
node.y = height - r; | |
} | |
} | |
</script> | |
</body></html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment