xxxxxxxxxx
91
let points = [];
let rngEdges = [];
const numPoints = 100;
const minDistance = 10;
const maxConnections = 2; // Maximum number of connections per point
function setup() {
createCanvas(500, 500);
// Generate points using Mitchell's best-candidate algorithm
generatePoints();
// Connect the points using the Relative Neighborhood Graph (RNG)
generateRNG();
}
function draw() {
background(220);
// Draw the RNG edges
beginShape();
for (let i = 0; i < rngEdges.length; i++) {
const edge = rngEdges[i];
stroke(0, 50); // Reduced opacity for organic appearance
line(edge.point1.x, edge.point1.y, edge.point2.x, edge.point2.y);
}
endShape();
// Draw the points
for (let i = 0; i < points.length; i++) {
const point = points[i];
fill(0);
noStroke();
ellipse(point.x, point.y, 5, 5);
}
}
function generatePoints() {
for (let i = 0; i < numPoints; i++) {
let valid = false;
let candidate;
// Try generating a valid candidate point
while (!valid) {
valid = true;
candidate = createVector(random(width), random(height));
// Check the minimum distance to existing points
for (let j = 0; j < points.length; j++) {
const existingPoint = points[j];
const distance = p5.Vector.dist(candidate, existingPoint);
if (distance < minDistance) {
valid = false;
break;
}
}
}
points.push(candidate);
}
}
function generateRNG() {
for (let i = 0; i < points.length; i++) {
const point1 = points[i];
const neighbors = findClosestNeighbors(point1, maxConnections);
for (let j = 0; j < neighbors.length; j++) {
const point2 = neighbors[j];
// Add an RNG edge between point1 and point2
rngEdges.push({
point1,
point2
});
}
}
}
function findClosestNeighbors(target, count) {
const sortedPoints = points.slice().sort((a, b) => {
const distanceA = p5.Vector.dist(target, a);
const distanceB = p5.Vector.dist(target, b);
return distanceA - distanceB;
});
return sortedPoints.slice(1, count + 1);
}