We are surrounded by people every day , especially as students living on campus. We run into people everywhere, be it the dining hall, the library or even the laundry rooms. I wanted to capture that feeling by filling the entire canvas with people (the dots represent people).
But we don’t actually connect with everyone we see. In my sketch, I use distance as a threshold that determines whether a line forms between two people. The line symbolizes the emotional closeness. If two people get close enough emotionally, a connection forms between them. But life happens. People drift apart, connections break (i.e. line disappears). This is very dynamic, just like in real life.
Also, when the user clicks, a new person appear almost like meeting someone new. At first they are brightly colored because they don’t exactly fit in our network of people just yet, but over time they fade into black, representing how over time they become part of our network. While they are still “new” they don’t form any connections which mirrors how it usually takes time before we can emotionally connect with a new person. The more you click, the more new people are added, just like how engaging with others more often leads to a growing network.
Here’s the code:
let people = []; let numPeople = 30; let connectionDistance = 80; const newPeopleColour = [ [255, 0, 0], [0, 255, 0], [0, 0, 255], [255, 255, 0], [255, 0, 255], [0, 255, 255], [255, 128, 0], [128, 0, 255] ]; function setup() { createCanvas(600, 400); // Create initial people for (let i = 0; i < numPeople; i++) { people.push(new Person(random(0,width), random(0,height), false)); } } function draw() { background(240); for (let i = 0; i < people.length; i++) { // Update & display the person people[i].move(); people[i].updateColor(); people[i].display(); // Check distance with all other people and make connections for (let j = i + 1; j < people.length; j++) { let d = dist(people[i].x, people[i].y, people[j].x, people[j].y); //if close enough and not new make connection if (!people[i].isNew && !people[j].isNew && d < connectionDistance) { stroke(0,50); line(people[i].x, people[i].y, people[j].x, people[j].y); } } } } function mousePressed() { people.push(new Person(mouseX, mouseY, true)); } class Person { constructor(x, y, isNew) { this.x = x; this.y = y; this.speedX = random(-3, 3); this.speedY = random(-3, 3); if (isNew) { // Pick a bright random color let c = random(newPeopleColour); this.r = c[0]; this.g = c[1]; this.b = c[2]; this.isNew = true; } else { // For initial people make them black this.r = 0; this.g = 0; this.b = 0; this.isNew = false; } } move() { this.x += this.speedX; this.y += this.speedY; // Bounce off edges if (this.x < 0 || this.x > width) { this.speedX *= -1; } if (this.y < 0 || this.y > height) { this.speedY *= -1; } } updateColor() { if (this.isNew) { // Fade to black eventually this.r = max(0, this.r - 1); this.g = max(0, this.g - 1); this.b = max(0, this.b - 1); if (this.r === 0 && this.g === 0 && this.b === 0) { this.isNew = false; } } } display() { noStroke(); fill(this.r, this.g, this.b); ellipse(this.x, this.y, 8, 8); } }
The main challenge I faced was that at first, two lines were being drawn between the same two people which broke the clean look of the network. I solved this by using a nested for loop and tarting j from i + 1 which avoided checking duplicate pairs and made sure each connection line was only drawn once. I also really like the colour-fading logic, it’s simple but menaingful as new people slowly assimilate into the network. The max() function is a small but important detail, it prevents colors from becoming negative and making sure the isNew flag flips to false so these people can eventually form connections.
In terms of future work and improvements, I could add a ‘main character’ , a single person who’s at the center and stays still while the rest of the network moves and connects around them. This would focus on the idea of how one person’s network changes.