Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Space-filling with an arbitrary number of circles with predefined radii
/*
*
* Space-filling with circles
*
* Authors: Kris Van Bael.
* Small modifications by Louis Mullie.
*
*
* Usage:
*
* drawCircles(paper, circles, colors)
* - Paper is a Raphael Paper object.
* - Circles is an array of radii.
* - Colors is an array of colors.
*
* Example:
* var paper = Raphael(10, 50, 800, 600);
* var colors = ['#99cccc', '#99ccff', '#ff6633', '#cccc66'];
* var radii = [90, 50, 60, 100, 60, 40, 90, 50, 60, 100, 60, 40];
*
* drawCircles(paper, radii, colors);
*
* Requires Raphael (http://raphaeljs.com/).
*/
function createGrid(columns, rows, size) {
var grid = [];
var y = size / 2.0;
for (row = 0; row < rows; row++) {
var distanceFromTop = y;
var distanceFromBottom = height - y;
for (col = 0; col < columns; col++) {
var i = row * columns + col;
grid[i] = (distanceFromTop <  distanceFromBottom) ?
distanceFromTop : distanceFromBottom;
}
y += size;
}
var x = size / 2.0;
for (col = 0; col < columns; col++) {
var distanceFromLeft = x;
var distanceFromRight = width - x;
for (row = 0; row < rows; row++) {
var i = row * columns + col;
if (grid[i] > distanceFromLeft) {
grid[i] = distanceFromLeft;
}
if (grid[i] > distanceFromRight) { 
grid[i] = distanceFromRight;
}
}
x += size;
}
return grid;
}
function drawCircles(paper, circles, colors) {
var size = Math.sqrt(paper.width * paper.height / 1000);
var columns = Math.ceil(paper.width / size);
var rows = Math.ceil(paper.height / size);
var grid = createGrid(columns, rows, size);
var json = [];
circles = circles.sort().reverse();
for (circle = 0; circle < circles.length; circle++) {
// We assume circles are sorted large to small!
var radius = circles[circle];
// Find gridpoint with largest distance from anything
var i = 0;
var maxR = 0;
var maxC = 0;
var maxDist = grid[0];
for (row = 0; row < rows; row++) {
for (col = 0; col < columns; col++) {
if (maxDist < grid[i]) {
maxR = row;
maxC = col;
maxDist = grid[i];
}
i++;
}
}
var k = Math.random() * colors.length;
var c = colors[Math.floor(k)];
var x = size / 2.0 + maxC * size;
var y = size / 2.0 + maxR * size;
var offset = (maxDist - radius) / 2.0;
x += Math.random() * offset;
y += Math.random() * offset;
json.push({
type: "circle",
cx: x,
cy: y,
r: radius,
stroke: Raphael.rgb2hsb(c),
fill: '#ffffff'
});
// Update Distance array with new circle;
i = 0;
var yy = size / 2.0;
for (r = 0; r < rows; r++) {
var xx = size / 2.0;
for (c = 0; c < columns; c++) {
var d2 = (xx - x) * (xx - x) + (yy - y) * (yy - y);
var prev2 = grid[i] + radius;
prev2 *= prev2;
if (prev2 > d2) {
var d = Math.sqrt(d2) - radius;
if (grid[i] > d) {
grid[i] = d;
}
}
xx += size;
i++;
}
yy += size;
}
}
paper.add(json);
}
@tackdetack

This comment has been minimized.

Show comment Hide comment
@tackdetack

tackdetack Jul 17, 2016

How would one call this on an HTML page?

How would one call this on an HTML page?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment