Skip to content

Instantly share code, notes, and snippets.

@louismullie
Created March 19, 2012 01:33
Show Gist options
  • Select an option

  • Save louismullie/2089431 to your computer and use it in GitHub Desktop.

Select an option

Save louismullie/2089431 to your computer and use it in GitHub Desktop.
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

Copy link
Copy Markdown

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