Final Project

My final project places plants, seeds, and a flock of birds together in a digital meadow influenced by user interactions and variations governed by physics laws.

In this scene, “grass” blades sway in the “wind”, seeds fall to the ground and sprout into new plants, and birds navigate the environment following flocking rules. As a viewer, you influence wind direction, create rain to accelerate plant growth, and steer the bird flock with your mouse. The goal was to create a piece that feels organic and alive.

 


Seeds drift down into the scene and, once landed, germinate over time. Grass blades grow taller, especially when nourished by “rain” created by the user. Wind vectors influence the direction and sway of grass blades. Seeds fall under gravity. Birds respond to flocking forces—separation, alignment, cohesion. Instead of scripting each bird, I use the Boids algorithm to define local rules.

User Interaction

    • Wind Control: Arrow keys change wind direction, subtly shifting the meadow’s behavior.
    • Rain Creation: Clicking and dragging creates raindrops, accelerating the growth of plants.
    • Bird Guidance: Moving your mouse influences the flock’s position, inviting them to avoid or explore your cursor’s location

Future Directions

  • Adding seasonal shifts or migration patterns for birds would add further complexity and opportunities for interaction.
  • More biodiversity could make the scene richer—different plant species, insects, or small mammals.
  • Dynamic sounds (birds chirping, wind rustling) could evolve based on user inputs and environmental states.

code

Week 11 Assignment

These systems, where each cell in a grid evolves based on the state of its neighbors, have inspired mathematicians, artists, and technologists alike. From Conway’s Game of Life to modern generative art, cellular automata demonstrate how emergent behaviors can create visually captivating and intellectually intriguing works.

In this project, I designed an interactive cellular automata sketch using p5.js. The goal was to create a dynamic canvas where users can experiment with CA rules, colors, and patterns in real-time. The grid evolves based on Conway’s Game of Life rules: cells are born, survive, or die based on the number of active neighbors. However, the interactivity takes the experience further, allowing users to influence the automata by adding or removing cells, toggling simulation states, and randomizing initial conditions. This makes the system not only generative but also deeply personal and exploratory.

What makes this project exciting is the ability to tweak parameters and immediately see their impact. Users can modify grid size, experiment with different initial states, and even create patterns manually by dragging their mouse. The vibrant, gradient-based color scheme adds an artistic dimension, transforming mathematical rules into dynamic visual expressions. Cellular automata are not just about abstract computation—they’re about discovering the unexpected beauty that emerges from simplicity.

Code

Week 10 Assignment

Using the Matter.js library, I built an interactive physics playground that explores two fundamental aspects of physics simulation: applying forces and handling collision events. This project not only demonstrates the core capabilities of Matter.js but also creates a visually engaging and interactive experience.

The centerpiece of the playground is a controllable cube that reacts to user input. Using the arrow keys, you can push this object in different directions, applying realistic forces that accelerate and decelerate its motion. Around this object, other bodies fall from above, bouncing off surfaces and interacting with the central body. These falling objects change color upon collision, visually signaling their interaction. Static boundaries define the edges of the world, ensuring objects remain within the canvas while responding dynamically to gravity, friction, and restitution.

What makes this project exciting is its interactive nature. By combining user-applied forces and collision events, it demonstrates the responsiveness of Matter.js and highlights how even simple rules can result in rich, emergent behaviors. The physics playground is more than just a demonstration—it’s an example of how computational physics can create engaging, real-time experiences that blend logic with creativity.

Code

 

Week 9 Flocking Assignment

Inspired by the works of Robert Hodgin and Ryoichi Kurokawa, I designed an evolving flocking system that transitions through three distinct phases: chaos, development, and harmony. Each phase reflects a shift in behavior and mood, creating a dynamic visual narrative that explores tension and release. The boids (agents) begin in disarray, move toward alignment, and ultimately flow as a unified, harmonious whole.

This evolution is driven by balancing three simple flocking behaviors: alignment, cohesion, and separation. During the chaotic phase, separation dominates, creating erratic and fragmented movement. As the system develops, the forces balance, bringing order and shared direction. In the final phase, alignment and cohesion prevail, resulting in fluid, synchronized motion. These transitions add rhythm to the system, reflecting larger themes of growth, collaboration, and transformation.

The aesthetic choices amplify the emotional arc. Colors evolve from bold reds to glowing cyan, trails highlight the continuity of motion, and forms shift from sharp to soft as the flock becomes more cohesive. Inspired by Hodgin’s focus on emergence, the system reveals how complexity and beauty arise from simplicity. It’s a meditation on movement, unity, and the harmony that comes from finding balance.

code

Week 9 Coding Assignment

In this project, each vehicle acts as an independent agent with three key behaviors:

  1. Cohesion: Vehicles steer toward the average position of nearby flockmates.
  2. Separation: To avoid collisions, vehicles steer away from those that come too close.
  3. Alignment: Vehicles match their direction and speed with nearby flockmates, creating a collective flow.

These behaviors produce an emergent, cohesive movement across the system as vehicles move together as a group while avoiding overcrowding and maintaining some alignment. We also added a wander function with Perlin noise to generate more organic, smooth changes in direction, which softened the rigidness of purely algorithmic steering.

Challenges and Discoveries

One challenge was balancing the behaviors, as the vehicles could either clump together too tightly or spread out too widely. Adjusting the perception radii and scaling each behavior’s force was key in achieving the desired balance, allowing each vehicle to respond naturally to its neighbors while still participating in a larger, collective pattern.

I also experimented with Perlin noise to influence movement subtly. By introducing this form of randomness, each vehicle gained a more fluid, organic quality, reminiscent of natural systems where movement isn’t perfectly uniform. This approach has inspired further experimentation, such as adding color shifts or trails to visualize the vehicles’ paths.

code

Guest Lecture Reflection

The guest artist lecture this week was enjoyable and inspiring. Their work emphasized that designing with nature often means embracing imperfections and patterns that emerge over time, rather than controlling every element. This philosophy connects well with our coding assignments where we learn that emergent behaviors often arise from simple rules rather than strict control.

SMH

 

This version of Simple Harmonic Motion will feature multiple particles moving in harmonic motion along different axes. Each particle’s motion is governed by sine and cosine functions, and we’ll experiment with adding layers of complexity by adjusting frequency, amplitude, and phase shift over time. The interaction of these particles will create a visually intriguing harmonic system.

Design Approach

  1. Multiple Oscillators: Each oscillator (particle) will move along one or two axes following SHM principles.
  2. Phase Shifting: The oscillators will have slight differences in their phase, creating beautiful and non-repetitive motion patterns.
  3. Layering Frequencies: Multiple sine and cosine waves will be layered to simulate interacting harmonic systems.
  4. Memo Akten’s Influence: Drawing from Memo Akten’s complex motion systems, we’ll make the motion more intricate by introducing randomness to parameters like amplitude and frequency over time.

Code design

  • Particles: Each particle is modeled as a point oscillating based on sine and cosine functions, representing harmonic motion along both the X and Y axes.
  • Amplitude and Frequency: The amplitude controls how far the particle moves, while the frequency controls how fast it oscillates.
  • Phase Shift: Each particle starts with a random phase, ensuring their motion is out of sync, creating an intricate, layered pattern.
let particles = [];

function setup() {
  createCanvas(800, 800);
  for (let i = 0; i < 10; i++) {
    particles.push(new Particle(random(50, 100), random(50, 200), random(0.02, 0.05)));
  }
}

class Particle {
  constructor(amplitudeX, amplitudeY, frequency) {
    this.amplitudeX = amplitudeX; // Amplitude of motion in X
    this.amplitudeY = amplitudeY; // Amplitude of motion in Y
    this.frequency = frequency; // Frequency of oscillation
    this.angle = random(TWO_PI); // Starting phase angle
  }

  update() {
    // Increment angle over time to simulate oscillation
    this.angle += this.frequency;
  }

  display() {
    let x = this.amplitudeX * cos(this.angle); // Simple harmonic motion in X
    let y = this.amplitudeY * sin(this.angle); // Simple harmonic motion in Y
    
    noFill();
    stroke(255, 200);
    ellipse(x, y, 50, 50); // Draw particle at (x, y)
  }
}

View code

Midterm Progress 3

Final Project Refinements

  1. Polished Modes: The three modes (Growth, Random, Stability) now work seamlessly, offering different visual representations of population dynamics.
  2. Final Experimentation: After experimenting with various settings, I settled on a configuration that produces visually appealing population patterns, especially in Stability Mode where populations stabilize.
  3. Plotted Output: The final SVG image generated in Stability Mode resonated with me, as it visually symbolizes population balance. I exported the high-res version and prepared it for printing on A3 sheets.

view code

Midterm Progress 2

Project Development

  1. Fertility & Death Rate Integration: By this phase, I fully incorporated fertility and death rates. Each region now grows or shrinks based on these factors, and in Stability Mode, populations stabilize around a 2.1 replacement rate.
  2. Mode Switching: Users can toggle between Growth, Random, and Stability modes using the keyboard.
  3. Visual Feedback: The size of each circle dynamically adjusts based on the population changes, offering a visual representation of how populations are evolving in each region.
  4. Significant Code Progress: Implemented the full logic for handling different population behaviors across modes.

Code Refinements

In this phase, I added full functionality for fertility and death rates, and populations now stabilize in Stability Mode.

let regions = [];
let mode = 0; // Mode selector

function setup() {
  createCanvas(800, 800);
  let gridSize = 4;
  let spacing = width / gridSize;
  
  for (let i = 0; i < gridSize; i++) {
    for (let j = 0; j < gridSize; j++) {
      let x = spacing * i + spacing / 2;
      let y = spacing * j + spacing / 2;
      let population = random(50, 200);
      let fertilityRate = random(1.5, 5);
      let deathRate = random(0.5, 3);
      regions.push(new Region(x, y, population, fertilityRate, deathRate));
    }
  }
}

function draw() {
  background(255);
  switch (mode) {
    case 0:
      growthMode();
      break;
    case 1:
      randomMode();
      break;
    case 2:
      stabilityMode();
      break;
  }
}

function keyPressed() {
  if (key === '1') mode = 0;
  if (key === '2') mode = 1;
  if (key === '3') mode = 2;
}

function growthMode() {
  for (let region of regions) {
    region.grow();
    region.display();
  }
}

function randomMode() {
  for (let region of regions) {
    region.randomizeRates();
    region.grow();
    region.display();
  }
}

function stabilityMode() {
  for (let region of regions) {
    region.stabilize();
    region.grow();
    region.display();
  }
}

Three Variations for Export

  1. Growth Mode: Populations grow or shrink based on initial fertility and death rates.
  2. Random Mode: Random changes in fertility and death rates cause erratic population behaviors.
  3. Stability Mode: Populations gradually stabilize around the replacement rate.

I exported these three variations in SVG format using the save() function in p5.js.

function keyPressed() {
  if (key === 's') {
    save(); // Saves the current state as SVG
  }
}

 

Midterm Progress 1

Project Concept

The project mimics population dynamics in different parts of the world by incorporating fertility rates and death rates, allowing each region to grow, shrink, or stabilize based on these parameters. Over time, population levels converge towards a 2.1 replacement rate (the level needed to maintain a stable population). This concept is inspired by real-world demographic transitions, where regions move from rapid population growth to stabilization.

  • Regions as Grid: A grid of circles represents different global regions. Each circle’s size correlates to the population size, while fertility and death rates drive the growth or shrinkage.
  • Fertility Rate: Controls how quickly a region’s population expands.
  • Death Rate: Controls how quickly populations decline.
  • Replacement Rate: Populations converge towards a stable size (replacement rate of 2.1 children per woman), creating patterns of population stability.

Modes of the System

  1. Growth Mode: Populations grow or shrink based on predefined fertility and death rates.
  2. Random Mode: Random fluctuations in fertility and death rates simulate unpredictable factors like pandemics or booms.
  3. Stability Mode: Regions converge towards the replacement rate, stabilizing population growth.

Design Approach

  1. Grid Layout: A grid layout represents various regions, and each circle symbolizes a region’s population.
  2. Fertility and Death Rates: Each region has different fertility and death rates, randomly assigned initially. These rates determine whether a population grows or declines.
  3. Replacement Rate: In Stability Mode, all populations will stabilize around a fertility rate of 2.1.
  4. Modes: The user can toggle between modes using the keyboard.
  5. Visualization: Circle size visualizes population changes, expanding during growth and shrinking during decline.

Most Complex Part

Handling the stabilization towards the 2.1 replacement rate is the most uncertain part. Populations should gradually approach equilibrium without abrupt changes. I’ll mitigate this risk by implementing gradual transitions in the stabilization mode, where the fertility and death rates are slowly adjusted.

Initial Code and Progress (Growth Logic)

At this phase, I implemented the basic grid and growth logic, focusing on population growth and shrinkage. I designed classes and functions that would later incorporate fertility and death rates.

class Region {
  constructor(x, y, population, fertilityRate, deathRate) {
    this.x = x;
    this.y = y;
    this.population = population;
    this.fertilityRate = fertilityRate;
    this.deathRate = deathRate;
  }

  grow() {
    let growthFactor = this.fertilityRate - this.deathRate;
    this.population += growthFactor;
    this.population = constrain(this.population, 10, 300);
  }

  display() {
    fill(100, 150, 200);
    ellipse(this.x, this.y, this.population);
  }

  randomizeRates() {
    this.fertilityRate = random(1.5, 5); // Random fertility rate
    this.deathRate = random(0.5, 3); // Random death rate
  }

  stabilize() {
    this.fertilityRate = lerp(this.fertilityRate, 2.1, 0.05); // Gradual shift towards replacement rate
    this.deathRate = lerp(this.deathRate, 1.9, 0.05); // Shift death rate to balance fertility
  }
}