xxxxxxxxxx
158
const MAX_SIZE_PERCENT = 0.1;
const MIN_SIZE_PERCENT = 0.01;
const BUFF = 0.001;
const MAX_TRIES = 1000;
let circles = [];
let maxSize, minSize, buff;
let seed = 2;
let lines = false;
let loops = false;
let outline = false;
let round_outline = true;
let lightMode = true;
function setup() {
pixelDensity(1);
createCanvas(9000, 9000);
strokeWeight(10);
maxSize = width * MAX_SIZE_PERCENT;
minSize = width * MIN_SIZE_PERCENT;
buff = width * BUFF;
noFill();
noLoop();
}
function draw() {
randomSeed(seed);
packCircles();
clear();
for(let i = 0; i < circles.length; i ++) {
let c = circles[i];
drawCircle(c);
}
}
function mouseReleased() {
lightMode = !lightMode;
if(lightMode) {
stroke(255);
} else {
stroke(0);
}
draw();
}
function keyReleased() {
if(key === " ") {
saveDesign();
} else {
seed += 1;
console.log(seed);
circles = [];
draw();
}
}
function saveDesign() {
let o = outline ? "_outlined" : "";
let cr = round_outline ? "_circled": "";
let l = lines ? "_lines" : "";
let c = loops ? "_loops" : "";
let li = lightMode? "_light" : "_dark";
let s = "_" + str(seed);
save("PackedCircles" + cr + o + l + c + s + li + ".png")
}
function drawCircle(c) {
push();
translate(c.x, c.y);
rotate(random(TAU));
let numMin = map(c.z, minSize, maxSize, 5, 10);
let numMax = map(c.z, minSize, maxSize, 8, 16);
let num = floor(random(numMin, numMax));
let centreSpace = random(-0.2, 0.2);
if(round_outline) {
circle(0, 0, c.z * 2);
}
if(outline) {
beginShape();
for(let i = 0; i < num; i ++) {
let a = (TAU/num) * i;
vertex(cos(a) * c.z, sin(a) * c.z);
}
endShape(CLOSE);
}
if(lines) {
for(let i = 0; i < num; i ++) {
let a = (TAU/num) * i;
line(0, 0, cos(a) * c.z, sin(a) * c.z);
}
}
if(loops) {
for(let i = 0; i < num; i ++) {
let x = (c.z * centreSpace) + c.z/2;
let r = c.z - x;
circle(x, 0, r * 2);
rotate(TAU/num);
}
}
pop();
}
function packCircles() {
let totalTries = 0;
while(totalTries < MAX_TRIES) {
totalTries += 1;
let c = createVector(random(width), random(height), minSize);
let lastR = c.z;
let missedLast = false;
let canAdd = false;
while(c.z <= maxSize) {
if(!hits(c)) {
lastR = c.z;
missedLast = true;
c.z += buff * 10;
if(c.z >= maxSize) {
c.z = lastR;
canAdd = true;
break;
}
} else if(missedLast) {
c.z = lastR;
canAdd = true;
break;
} else {
break;
}
}
if(canAdd) {
circles.push(c);
totalTries = 0;
}
}
}
function hits(c) {
if(c.x < c.z || c.x > width - c.z ||
c.y < c.z || c.y > height - c.z) {
return true;
}
for(let i = 0; i < circles.length; i ++) {
let test = circles[i];
if(dist(c.x, c.y, test.x, test.y) < (buff + c.z + test.z)) {
return true;
}
}
return false;
}