I found a solution to detect the collision function when generating random coordinates, here is the jsfiddle link and code:
(function () { var angle, offset, data, x, y, r, collision, circle1, circle2, circles = [], size = [8, 15], width = 500, color = d3.scale.category10(), height = 600, radius = 130, dispersion = 10, svgContainer = d3.select('body').append("svg") .attr("width", width) .attr("height", height); function detectCollision(c2, c1) { var dx = c1.cx - c2.cx; var dy = c1.cy - c2.cy; var rSum = c1.r + c2.r; return ((Math.pow(dx, 2) + Math.pow(dy, 2)) < Math.pow(rSum, 2)); } var sh = 2, elements = 55; data = d3.range(elements).map(function (i) { do { // dispersion += i / 50; angle = Math.random() * Math.PI * 2; offset = Math.max(size[0], size[1]) + radius + dispersion + (elements/sh); x = offset + Math.cos(angle) * radius + rand(- (dispersion + i / sh), dispersion + i / sh); y = offset + Math.sin(angle) * radius + rand(- (dispersion + i / sh), dispersion + i / sh); r = rand(size[0], size[1]); circle2 = {cx : x, cy : y, r : r}; collision = false; if (circles.length > 1) { circles.forEach(function (d) { circle1 = {cx : d.cx, cy : d.cy, r : dr}; if (detectCollision(circle1, circle2)) { collision = true; } }); } } while (collision); circles.push(circle2); return circles[circles.length - 1]; }); svgContainer.selectAll("circle") .data(data) .enter().append("circle") .attr({ r : function (d) { return dr }, cx : function (d) { return d.cx }, cy : function (d) { return d.cy }, fill : function (d, i) { return color(i % 3) } }); function rand(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } })();
source share