xxxxxxxxxx
126
// https://thecodingtrain.com/CodingChallenges/033-poisson-disc.html
let r = 9; // minimum distance between two points
let k = 30; // limit of samples to choose before rejecting
let grid = [];
let w;
let active = [];
let rows, cols;
let ordered = [];
function setup() {
createCanvas(windowWidth, windowHeight);
background(20);
stroke(255);
strokeWeight(4);
w = r / sqrt(2);
// STEP 0
cols = floor(width / w);
rows = floor(height / w);
for (let i = 0; i < cols * rows; i++) {
grid[i] = undefined;
}
// STEP 1 - select initial sample
let x = random(width);
let y = random(height);
let i = floor(x / w);
let j = floor(y / w);
let pos = createVector(x, y);
grid[i + j * cols] = pos;
active.push(pos);
}
function draw() {
background(20);
// noLoop();
// STEP 2
if (active.length > 0) {
// while (active.length > 0) {
for (let total = 0; total < 200; total++) {
let randIndex = floor(random(active.length));
let pos = active[randIndex];
let found = false;
for (let n = 0; n < k; n++) {
let sample = p5.Vector.random2D();
let m = random(r, r * 2);
sample.setMag(m);
sample.add(pos);
let col = floor(sample.x / w);
let row = floor(sample.y / w);
if (
col > -1 &&
row > -1 &&
col < cols &&
row < rows &&
!grid[col + row * cols]
) {
let ok = true;
for (let i = -1; i <= 1; i++) {
for (let j = -1; j <= 1; j++) {
let index = col + i + (row + j) * cols;
let neighbor = grid[index];
if (neighbor) {
let d = p5.Vector.dist(sample, neighbor);
if (d < r) {
ok = false;
}
}
}
}
if (ok) {
found = true;
grid[col + row * cols] = sample;
active.push(sample);
ordered.push(sample);
// Should we break?
break;
}
}
}
if (!found) {
active.splice(randIndex, 1);
}
}
} else {
console.log("No more active points");
noLoop();
}
// for (let i = 0; i < grid.length; i++) {
// if (grid[i]) {
// stroke(255);
// strokeWeight(8);
// // noFill();
// // circle(grid[i].x, grid[i].y,10);
// point(grid[i].x, grid[i].y);
// }
// }
// for (let i = 0; i < active.length; i++) {
// stroke(255, 0, 255);
// strokeWeight(3);
// point(active[i].x, active[i].y);
// }
for (let i = 0; i < ordered.length; i++) {
if (ordered[i]) {
stroke(i % 360, 100, 220);
strokeWeight(r * 0.5);
point(ordered[i].x, ordered[i].y);
}
}
for (let i = 0; i < active.length; i++) {
stroke(255, 40, 100);
strokeWeight(r * 1.25);
point(active[i].x, active[i].y);
}
}