Code: https://editor.p5js.org/bdr/sketches/Vnv5bkHdK
Concept:
Connections combines two concepts: Levy flight motion and dynamic bezier curve connections between particles. Levy flight is a type of random walk where the step length follows a heavy-tailed probability distribution, resulting in a long erratic movement. It represents a dynamic system of particles moving within the canvas, with real-time changing edges connecting them. My sketch draws inspiration from concepts in computational art to explore the interplay between randomness and controlled forms in a dynamic particle system.
Steps:
Code Walkthrough:
A ‘Particle’ class encapsulates the behavior and properties of individual particles. Each particle is initialized with a random position (x,y) within the canvas and a random color with alpha transparency. The particles move according to Levy flight motion and can change direction when they come into close proximity to each other.
Particle Movement – Levy Flight:
Using the update() function, a random length and direction is calculated and is reflected on the particle’s movement. Since stepDirection is a random angle, cos(stepDirection) and sin(stepDirection) generate random values between -1 and 1. These values are then multiplied by stepLength, which is a random value as well. The use of cosine and sinus ensures that the particle can move in any direction as stepDirection can take any value between 0 and 2π.
// Levy flight movement
update() {
let stepLength = random(3);
let stepDirection = random(TWO_PI);
this.x += cos(stepDirection) * stepLength;
this.y += sin(stepDirection) * stepLength;
// Keep particles within bounds
this.x = (this.x + width) % width;
this.y = (this.y + height) % height;
}
Particle Appearance:
The display() method draws each particle as a white ellipse with random alpha to create a glowing effect.
Particle Interaction:
As the particles come too close to each other, they both change their respective directions. It is handled by the changeDirection() function.
Particle Connection – Lerp:
If two particles come within a certain distance, a bezier curve is drawn between them. Linear interpolation is used twice for each pair of connected particles: once to determine the position of the first control point (x1,y1) and again for the second control point (x2,y2). It allows for fine-tuning the curvature of the bezier curve between them.
// Control points for bezier
let control1X = lerp(particles[i].x, particles[j].x, 0.1);
let control1Y = lerp(particles[i].y, particles[j].y, 0.4);
let control2X = lerp(particles[i].x, particles[j].x, 0.9);
let control2Y = lerp(particles[i].y, particles[j].y, 0.9);
// Combines the colors of the particles it connects
stroke(lerpColor(particles[i].color, particles[j].color, 0.5));
bezier(particles[i].x, particles[i].y, control1X, control1Y, control2X, control2Y, particles[j].x, particles[j].y);
The color of each bezier curve is a combination of the colors of the two connected particles, creating a smooth color transition along the curve (using Lerp again).
Challenges:
Achieving a balance between randomness and control in the particle movement can be tricky as an excess in randomness can result in chaos and unpredictable behavior. I was able to do that by fine-tuning these parameters and following a trial and error process.
Possible improvements:
- Particle attraction: add forces of attraction
- User Interaction: let the user interact through clicks or mouse movement