xxxxxxxxxx
154
const numPeople = 500;
const numConnections = 15;
const people = [];
let selectedPerson = null;
let frameCount = 0;
let haltSimulation = false;
function mix(a, b, fraction) {
return fraction * a + (1-fraction) * b;
}
function checkSameColor() {
const firstColor = people[0];
for (const person of people) {
if (!same(firstColor, person)) return false;
}
return true;
}
function same(a, b) {
return ((a.r == b.r) && (a.g == b.g) && (a.b == b.b));
}
function setup() {
createCanvas(800, 800);
for (let i = 0; i < numPeople; i++) {
people.push(new Person(random(width), random(height), random(255), random(255), random(255)));
}
for (let i = 0; i < numPeople; i++) {
const distances = [];
for (let j = 0; j < numPeople; j++) {
if (i !== j) {
distances.push({index: j, distance: dist(people[i].x, people[i].y, people[j].x, people[j].y)});
}
}
distances.sort((a, b) => a.distance - b.distance);
for (let j = 0; j < numConnections; j++) {
people[i].connections.push(people[distances[j].index]);
}
}
}
function draw() {
if (!haltSimulation) {
background(220);
for (const person of people) {
person.mixColors();
person.displayEdges(selectedPerson);
}
for (const person of people) {
person.displayNode();
}
frameCount++;
if (checkSameColor()) {
haltSimulation = true;
}
}
stroke(220);
textSize(14);
fill(0);
text("Frames: " + frameCount, 20, 30);
}
function mousePressed() {
let closestPerson = null;
let minDistance = Infinity;
for (const person of people) {
const distance = dist(mouseX, mouseY, person.x, person.y);
if (distance < minDistance) {
minDistance = distance;
closestPerson = person;
}
}
if (minDistance < 10) {
selectedPerson = closestPerson;
selectedPerson.randomizeColor();
} else {
selectedPerson = null;
}
}
class Person {
constructor(x, y, r, g, b) {
this.x = x;
this.y = y;
this.r = r;
this.g = g;
this.b = b;
this.connections = [];
}
mixColors() {
let rSum = 0;
let gSum = 0;
let bSum = 0;
for (const connection of this.connections) {
// Maybe adopt the color of a neighbor?
if (random() < 0.01) {
this.r = connection.r;
this.g = connection.g;
this.b = connection.b;
}
rSum += connection.r;
gSum += connection.g;
bSum += connection.b;
}
/*
const mixRate = 0.99;
this.r = mix(this.r, rSum / this.connections.length, mixRate);
this.g = mix(this.g, gSum / this.connections.length, mixRate);
this.b = mix(this.b, bSum / this.connections.length, mixRate);
//this.r = (this.r + rSum / this.connections.length) / 2;
//this.g = (this.g + gSum / this.connections.length) / 2;
//this.b = (this.b + bSum / this.connections.length) / 2;
*/
}
randomizeColor() {
this.r = random(255);
this.g = random(255);
this.b = random(255);
}
displayEdges(selectedPerson) {
if (selectedPerson === this) {
strokeWeight(2);
stroke(this.r, this.g, this.b);
for (const connection of this.connections) {
line(this.x, this.y, connection.x, connection.y);
}
} else {
strokeWeight(1);
stroke(this.r, this.g, this.b);
for (const connection of this.connections) {
if (same(this, connection)) stroke(this.r, this.g, this.b);
else stroke(180);
line(this.x, this.y, connection.x, connection.y);
}
}
}
displayNode() {
strokeWeight(10);
stroke(this.r, this.g, this.b);
point(this.x, this.y);
}
}