Where ideas percolate and thoughts brew

Particle Flow

About This Sketch

One hundred particles move independently across the canvas, bouncing off walls like molecules in a gas. This simple physics simulation creates emergent complexity from straightforward rules.

The semi-transparent background creates elegant motion trails, while the boundary collisions keep particles contained. This is a foundational pattern in generative art and physics simulations—simple rules creating complex, organic-looking behavior.

Algorithm

A particle system where 100 independent particles bounce around the canvas. This demonstrates basic physics simulation with velocity vectors and boundary collision. **Key Concepts:** - **Vector Mathematics**: Position and velocity as 2D vectors - **Velocity Clamping**: Limiting maximum speed with `limit()` - **Collision Detection**: Reversing velocity when hitting boundaries - **Object-Oriented Design**: Particle class encapsulates behavior **How it works:** 1. Create 100 particle objects with random positions and velocities 2. Each frame, update each particle's position by adding its velocity 3. Check boundaries and reverse velocity direction on collision 4. Render particles with transparency for trailing effect 5. Velocity limit prevents particles from moving too fast

Pseudocode

CLASS Particle:
  PROPERTIES:
    position = random vector
    velocity = random vector (-1 to 1)
    size = random(3, 8)

  METHOD update():
    LIMIT velocity to max 3
    position = position + velocity

    IF position.x outside canvas:
      velocity.x = -velocity.x

    IF position.y outside canvas:
      velocity.y = -velocity.y

  METHOD show():
    DRAW circle at position with size

SETUP:
  CREATE 100 particles

DRAW (every frame):
  CLEAR background with transparency

  FOR EACH particle:
    particle.update()
    particle.show()

Source Code

let sketch = function(p) {
    let particles = [];

    p.setup = function() {
        p.createCanvas(400, 300);
        p.colorMode(p.RGB);
        for (let i = 0; i < 100; i++) {
            particles.push(new Particle(p));
        }
    };

    p.draw = function() {
        const colors = getThemeColors();
        p.background(...colors.bg, 50);

        for (let particle of particles) {
            particle.update(p);
            particle.show(p, colors);
        }
    };

    class Particle {
        constructor(p) {
            this.pos = p.createVector(p.random(p.width), p.random(p.height));
            this.vel = p.createVector(p.random(-1, 1), p.random(-1, 1));
            this.size = p.random(3, 8);
        }

        update(p) {
            this.vel.limit(3);
            this.pos.add(this.vel);

            if (this.pos.x < 0 || this.pos.x > p.width) this.vel.x *= -1;
            if (this.pos.y < 0 || this.pos.y > p.height) this.vel.y *= -1;
        }

        show(p, colors) {
            p.fill(...colors.accent2, 150);
            p.noStroke();
            p.circle(this.pos.x, this.pos.y, this.size);
        }
    }
};