https://d3js.org/d3.v4.min.js
by gdicerbo
HTML
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3plus.org/js/d3plus-text.v0.9.full.min.js"></script>
CSS
html, body {
margin: 0;
height: 100%;
}
.gear-group .gear {
opacity: 0;
}
.gear-gear path{
fill: #81d6dc;
stroke: #ccc;
}
.gear-fill path{
fill: #ebacbe;
stroke: none;
}
.gear-center circle{
fill: white;
}
JavaScript
// ===========================
// ancillary geometric classes
// ===========================
var Point = function (x, y){
this.x = x;
this.y = y;
}
Point.prototype = {
dist: function (p) { return this.vect(p).norm(); },
vect: function (p) { return new Point (p.x-this.x, p.y-this.y); },
norm: function (p) { return Math.sqrt (this.x*this.x+this.y*this.y);},
add : function (v) { return new Point (this.x + v.x, this.y + v.y);},
mult: function (a) { return new Point (this.x * a, this.y * a);}
}
var Circle = function (radius, center, data){
this.r = radius
this.c = center
this.data = data
}
Circle.prototype = {
surface: function () { return Math.PI * this.r * this.r; },
distance: function (circle) { return this.c.dist(circle.c) - this.r - circle.r; }
}
// =========================
// circle packer lives here!
// =========================
var Packer = function (circles, ratio){
this.circles = circles;
this.ratio = ratio || 1;
this.list = this.solve();
}
Packer.prototype = {
// try to fit all circles into a rectangle of a given surface
compute: function (surface){
// check if a circle is inside our rectangle
function in_rect (radius, center){
if (center.x - radius < - w/2) return false;
if (center.x + radius > w/2) return false;
if (center.y - radius < - h/2) return false;
if (center.y + radius > h/2) return false;
return true;
}
// approximate a segment with an "infinite" radius circle
function bounding_circle (x0, y0, x1, y1){
var xm = Math.abs ((x1-x0)*w);
var ym = Math.abs ((y1-y0)*h);
var m = xm > ym ? xm : ym;
var theta = Math.asin(m/4/bounding_r);
var r = bounding_r * Math.cos (theta);
return new Circle (bounding_r,
new Point (r*(y0-y1)/2+(x0+x1)*w/4,
...