Salem Al Shamsi – Assignment 2

Saharan Dust to the Amazon

 

 Concept:

At first, I planned to simulate a palm tree frond moving in the wind, but it started to feel like the project was only about appearance. While researching movement in nature, I found something more surprising: dust from the Sahara can travel across the Atlantic and help fertilize the Amazon rainforest. I chose this idea because it shows how tiny particles can move huge distances and create real environmental change. My sketch simulates dust being lifted, carried by wind, and settling in the Amazon, using simple physics rules (acceleration, velocity, and Perlin noise wind).

Reference video showing Saharan dust traveling from Africa to the Amazon rainforest (NASA).

Rules / How the Simulation Works:

  1. Dust particles are released in short bursts, representing real dust storms.
  2. Wind pushes the particles using smooth Perlin noise, so the motion feels natural.
  3. All motion is controlled by acceleration, not by directly changing position.
  4. When particles reach the Amazon side, a downward settling force pulls them down.
  5. As dust settles, the Amazon area slowly becomes greener.
  6. After one dust event (a “season”), the system fades out and restarts.

Code Highlight:

function drawBackground(season) {
  let desertCol = color(220, 200, 150);

  // Amazon color changes depending on fertility
  let amazonStart = color(55, 75, 55);   // dull green
  let amazonEnd   = color(35, 165, 80);  // vivid green
  let amazonCol   = lerpColor(amazonStart, amazonEnd, fertility);

  // 0) Fill whole canvas first (prevents any 1px gaps)
  noStroke();
  fill(desertCol);
  rect(0, 0, width, height);

  // 1) Draw smooth left→right gradient
  // Using 1px rectangles helps avoid “brown seam” line
  for (let x = 0; x < width; x++) {
    let t = x / (width - 1);
    let col = lerpColor(desertCol, amazonCol, t);
    fill(col);
    rect(x, 0, 1, height);
  }

  // 2) Fertility overlay on the Amazon side (soft edge)
  let startX = width * 0.6;
  for (let x = startX; x < width; x++) {
    let tt = map(x, startX, width, 0, 1);
    let a = tt * lerp(0, 200, fertility);
    stroke(20, lerp(70, 210, fertility), 60, a);
    line(x, 0, x, height);
  }

  // 3) Small warm tint that increases when season is “strong”
  noStroke();
  fill(255, 220, 180, 12 * season);
  rect(0, 0, width, height);
}

I chose this part of the code because it represents a decision I struggled with the most. I initially tried to use maps and detailed visuals to show Africa and South America, but they distracted from the movement of the dust. This background uses simple color transitions instead, allowing the particles’ behavior to tell the story. The Amazon only becomes greener when dust settles and increases the fertility value, which connects the visual change directly to the simulation rules.

Embedded Sketch:

 

Reflection and Future Work:

The hardest part of this project was choosing the topic and figuring out how to represent it visually. I explored many different natural movements and phenomena from around the world before settling on this one, and deciding how to deliver the idea took a lot of time and thinking. Through this process, I learned that simple rules and forces like wind, gravity, and acceleration can be enough to communicate complex natural systems. This project made me realize how interesting it is to study invisible movements in nature, and in the future I would like to explore other global phenomena or experiment with different environmental conditions to see how the behavior changes.

Sun Bleached Flies – Assignment 2

Concept

Inspired by the swarming, atmospheric soundscapes of Ethel Cain’s Preacher’s Daughter, I wanted to recreate the jittery and unsettling movement of flies in nature.

Rather than just having objects fly randomly around the screen, I wanted to simulate the urge of a fly to either be stationary on the ground or burst into a manic, erratic flight. I focused on manipulating acceleration to distinguish between these two states: the heavy pull of landing and the weightless jitter of flying in the air.

Sketch

Highlight

I’m particularly proud of the state-switching logic within the update() function. It allows the fly to exist in two completely different physical modes (perched vs. flying) and uses a conditional check to ensure that the transition to landing only happens when the fly is actually descending toward the ground:

// Only force landing if they are below the line AND moving downwards
if (this.isFlying && this.pos.y >= height - 20 && this.vel.y > 0) {
  this.isFlying = false;
}

This bit of logic was crucial because it prevents the flies from accidentally tripping over the ground while they are trying to take off.

Reflection

Initially, the flies were ghosting through the floor. Even though I had a ground line, they would keep flying below it because their state was still set to “flying.” When I first tried to fix the ground collision, the flies became permanently stuck. Because they started on the ground, the force landing rule triggered at the exact same time as the take off urge, pinning them to the floor. I solved this by adding a grace rule: the ground check only applies if the fly is moving downwards (vel.y > 0). This finally allowed them to pop off the floor and enter their erratic flying state properly.

This assignment made me think back to the Flake reading about how simple rules create complex behaviors. By just giving the flies a 1% chance to change their mind, the screen starts to look like a living swarm. In the future, I want to replace the black circles with a PNG of a fly and potentially add a buzzing sound (like what you can faintly hear in the song “Family Tree“) that increases in volume or pitch based on the magnitude of the fly’s acceleration.

I’d also like to try making them avoid the mouse, simulating a swatting reaction using repulsive forces.

Amal – Assignment 2

Inspiration

Concept

For this assignment, I chose to simulate the movement of a moth attracted to a lamp, inspired by how insects behave around light sources in nature. When observing moths, their motion is rarely direct or smooth; instead, it feels hesitant, wobbly, and slightly chaotic.

The goal of this sketch was to recreate that behavior using only acceleration-based forces, without relying on complex visuals. The personality of the moth comes entirely from how it moves rather than how it looks.

The lamp acts as a constant attractor, while a subtle wobble force gives the moth an organic, fluttering quality.

Code Highlight

The part of the code I am most proud of is the wobble (flutter) force, which adds personality to the moth’s movement without making it feel random:

this.wobble += 0.1;
let flutter = createVector(
  cos(this.wobble),
  sin(this.wobble)
);
flutter.mult(0.03);
this.applyForce(flutter);

This small oscillating acceleration creates a natural, insect-like flutter. Combined with the attraction to the lamp, it makes the moth feel alive and slightly unpredictable, rather than robotic. And, this is where I used ChatGPT’s to help.

The Code

Reflection & Future Work

This project helped me better understand how simple rules can create believable natural motion. Using acceleration alone forced me to think carefully about how each force affects the behavior over time.

What worked well:

  • The combination of attraction and wobble felt natural and readable.
  • Limiting speed and force helped keep the movement smooth.
  • Keeping visuals simple allowed the motion to stand out.

If I were to continue developing this sketch, I would:

  • Add a “panic zone” near the lamp where the moth starts circling instead of approaching directly.
  • Introduce multiple moths with slightly different parameters to give each one a unique personality.
  • Experiment with a pulsing or moving light source to see how the behavior adapts.

Assignment 2

Concept

For this project, I wanted to simulate how moths fly around a porch light. I noticed that real bugs are chaotic. They don’t fly in straight lines, and they are all different sizes. I created a system where every moth tries to fly toward the mouse (the light), but they are constantly pushed around by a “jitter” force that makes them flutter. I also gave each moth a specific weight where big moths are heavy and slow to turn, while small moths are hyperactive and fast.

Code Highlight

I chose this function because it acts as the “brain” of the moth. It uses a physics formula to calculate exactly how to steer toward the light. When the user clicks, the code multiplies the allowed acceleration by 5, instantly transforming the moth from a lazy flyer into a chaotic one.

seek(target) {
    // 1. Find the direction pointing to the light
    let desired = p5.Vector.sub(target, this.pos);
    desired.normalize();
    
    // 2. Set the speed: If clicking, double the top speed!
    let speedLimit = mouseIsPressed ? this.maxSpeed * 2 : this.maxSpeed;
    desired.mult(speedLimit);

    // 3. Calculate steering (Desired velocity minus Current velocity)
    let steer = p5.Vector.sub(desired, this.vel);
    
    // 4. Limit the turning power: If clicking, allow 5x more force
    let currentForceLimit = mouseIsPressed ? this.maxForce * 5 : this.maxForce;
    steer.limit(currentForceLimit); 
    
    // 5. Apply this steering force 
    this.applyForce(steer);
  }

 

Reflection and Future Work

I was surprised by how realistic the movement felt, especially when the moths reach the light source and begin orbiting around it. It created a very organic, feeling without complex animation code. For future improvements, I would like somehow make them bump into each other so they don’t overlap.

 

Assignment 2

Concept

For this assignment, I chose to simulate drifting clouds moving across a sky. I was inspired by how clouds move so peacefully yet unpredictably – they have a gentle, steady drift from wind, but also bob up and down with air currents and occasionally get pushed by gusts. The challenge was to recreate this serene, organic movement using only acceleration to control the motion. No directly setting velocities or positions – everything had to come from forces acting on the clouds: wind, air currents, drag, and occasional gusts. Each cloud has its own “personality” through variations in drift speed, bobbing frequency, and size, making the scene feel more natural and alive rather than mechanical.

Code Highlight

In my implementation, a section of my code that i am proud of is below:

// Vertical bobbing using perlin noise for smooth, natural variation
this.time += 0.01;
let bobForce = map(noise(this.time), 0, 1, -this.bobFrequency, this.bobFrequency);
let bob = createVector(0, bobForce);
this.applyForce(bob);

This creates the gentle up-and-down bobbing motion of the clouds. Instead of using random() which would make the clouds jitter, I used Perlin noise which gives smooth, organic transitions. Each cloud has its own time value that increments, creating unique but natural bobbing patterns. The bobFrequency variable gives each cloud a different personality – some bob more dramatically while others are more subtle. I am also proud of this snippet that creates creates air resistance, that opposes the cloud’s velocity, preventing it from accelerating infinitely and giving it that slow, peaceful drift. It’s a small detail but makes a huge difference in the realism.

// Air resistance (drag)
let drag = this.vel.copy();
drag.mult(-0.05); // Drag coefficient
this.applyForce(drag);

Embedded Sketch

Reflections and Future Improvements

Through this assignment, I discovered that subtle forces acting over time can generate intricate, lifelike movement. In nature, nothing moves in perfectly straight lines or at constant speeds – everything is constantly being pushed and pulled by multiple forces. By combining simple acceleration vectors (wind, drag, turbulence), I could create movement that felt surprisingly alive and organic. My biggest takeaway is personality, which comes from imperfection and variation. Making every cloud slightly different in how it responds to forces was what made the scene feel natural rather than computational. Below are some ideas i would implement in the future for improvement of what i have currently:

  1. Multiple cloud layers – Add parallax depth by having clouds at different “distances” moving at different speeds.
  2. Dynamic wind – Instead of constant wind, have the wind direction and strength change slowly over time.
  3. Cloud morphing – Make clouds gradually change shape as they drift, growing and shrinking.
  4. Weather transitions – Clouds could darken and speed up before “rain,” then slow down and lighten afterward.
  5. Interactive elements – Mouse interaction could create temporary wind forces that push clouds around.
  6. Better visual design – Use gradients and transparency to make clouds look more three-dimensional and fluffy.
  7. Sound – Add gentle wind sounds that change based on cloud speed.

With my implementation so far some feature i believe work very well include, the drag force, bobbing through perlin noise, personality traits of each cloud and the combination of multiple forces which created complex behaviours from simple rules.

Assignment 1

Concept

For this assignment, just like the description suggested, I combined:

    • LIST 1: Random walker with motion experimentation
    • LIST 2: Walking through RGB color space

My sketch features a simple random walker that moves in four directions (up, down, left, right) across the canvas. Instead of being a fixed color, the walker’s color is determined by its position in space, creating a direct mapping between XY coordinates and RGB color values:

Red channel = X position (left edge = 0, right edge = 255)
Green channel = Y position (top edge = 0, bottom edge = 255)
Blue channel = Distance from center (center = 255, edges = 0)

As the walker moves randomly, it paints a trail of colors that visualize its journey through both physical space and color space simultaneously.

Code Highlight

Throughout my code, I am most proud of this snippet where I map the walker’s position to RGB values.

// Map position to RGB color
let r = map(x, 0, width, 0, 255);
let g = map(y, 0, height, 0, 255);

// Blue based on distance from center
let centerX = width / 2;
let centerY = height / 2;
let distFromCenter = dist(x, y, centerX, centerY);
let maximumDist = dist(0, 0, centerX, centerY);  // Changed from maxDist
let b = map(distFromCenter, 0, maximumDist, 255, 0);

// Set the color and draw
fill(r, g, b);
noStroke();
circle(x, y, 10);

In the code, the map() function translates position into color. The blue channel calculation is especially interesting because it uses the Pythagorean distance from the center, creating a radial gradient effect. When the walker is near the center, it’s more blue; when it’s at the edges, it loses blue and becomes more red/green/yellow.

Embedded Sketch

Reflection and Future Work

This project was a great way to visualize the connection between position and color. Watching the walker create organic, colorful patterns by pure randomness is mesmerizing! The RGB color space creates interesting gradients naturally – reds in the upper right, greens in the lower right, blues in the center. Ideas for future improvements:

  1. Add diagonal movement – Currently limited to 4 directions; adding diagonals would create smoother, more varied paths.
  2. Implement Gaussian random walk – Instead of equal probability in all directions, use a normal distribution for step sizes to create more organic movement patterns.
  3. Try HSB color mode – Experiment with Hue-Saturation-Brightness instead of RGB for different color relationships.
  4. Multiple walkers – Have several walkers moving simultaneously, each leaving their own colored trail.
  5. Fade trail effect – Instead of permanent marks, make older circles fade away over time for a ghostly trail effect.
  6. Add 50% mouse attraction – Implement the probability-based walker that has a 50% chance of moving toward the mouse (combining two LIST 1 options).
  7. Step size control – Add a slider to adjust how fast/far the walker moves.

Assignment 1

Concept

For the first assignment, I decided to make a random walker using the Levy Flight algorithm. Additionally, I tweaked the motion so that the walker has a small chance of making a huge leap instead of always making small leaps, just to make it a bit different. It reminds me of how fast moving objects seem to us (such as how the Flash or Quicksilver seem to move in movies). I also mapped movement to scale, where the distance of the jump determines the thickness of the walker’s line and the size of the line’s head. Just to make it visually more appealing, I also decided to change the color of the head based on where it is on the sketch, such that it creates a nice looking color gradient.

Sketch:

Highlight

Even though it’s pretty simple, I was proud of how I decided between small and big leaps using a probability threshold. Here is the code:

let r = random(1);
if (r < 0.05) {
  step.mult(random(25, 100)); // Big leap 5% of the times
} else {
  step.mult(2); // Small leap otherwise
}

Reflection (Milestones, Challenges, Ideas)

An important milestone was successfully implementing the map() function to link two different mediums: spatial distance and visual scale. One challenge was figuring out the right reset interaction, before I settled on simply using a mouse click to leave it up to the viewer.

This sketch could be expanded on by maybe only changing the head’s color when a big leap is made, to signify the walker moving into a new “environment”, like stages of its life, or seasons of a show. It could also be made more visually appealing, but I’m not your guy for that (not yet, at least).

 

Frog Catching Flies – Movement Assignment 2

Concept

I wanted to capture the contrast between patience and explosive action you see when a frog hunts. Frogs sit completely still, tracking flies with just their eyes, then BAM tongue shoots out in a split second. The whole personality comes from this timing difference, not from making it look realistic.

The movement is controlled purely through acceleration values. The frog’s body never moves (zero acceleration on position), but the tongue has two completely different acceleration modes: aggressive when extending (accel = 8) and gentle when retracting (accel = -0.8). The flies get constant random acceleration in small bursts, which creates that jittery, unpredictable flight pattern you see in real insects.

I found a few videos of frogs hunting online and what struck me was how much waiting happens. Most of the time nothing is moving except the eyes tracking. Then when the tongue extends, it’s over in like 200 milliseconds. I tried to capture that same rhythm lots of stillness punctuated by sudden action.

Code Highlight

The part I’m most proud of is how the tongue uses completely different acceleration values depending on its state:

if (this.state === 'striking') {
  // Explosive acceleration out
  this.tongueAccel = 8;
  this.tongueVel += this.tongueAccel;
  this.tongueLength += this.tongueVel;
  
  if (this.tongueLength >= this.maxTongue) {
    this.state = 'retracting';
    this.tongueVel = 0;
  }
}

if (this.state === 'retracting') {
  // Gentle acceleration back
  this.tongueAccel = -0.8;
  this.tongueVel += this.tongueAccel;
  this.tongueLength += this.tongueVel;
  
  if (this.tongueLength <= 0) {
    this.tongueLength = 0;
    this.tongueVel = 0;
    this.tongueAccel = 0;
    this.state = 'idle';
  }
}

 

The 10x difference in acceleration (8 vs 0.8) creates that snappy-then-slow feeling. The tongue rockets out but drifts back lazily. This tiny numerical difference gives it way more personality than any visual design could.

Embedded Sketch

 

Reflection & Future Ideas

The acceleration-only constraint actually made this more interesting than if I’d used direct position control. You get these natural easing curves without writing any easing functions. The tongue feels weighty and real.

Things I noticed while testing:

  • The flies sometimes cluster in corners and the frog gives up. Maybe add a “frustration” behavior where it shifts position after too many misses?
  • The eye tracking is subtle but really sells the “watching” behavior. Glad I added that.
  • Random acceleration on the flies works better than I thought. They feel nervous and unpredictable.

Future improvements:

  • Add multiple frogs competing for the same flies
  • Make the frog’s strike range dependent on hunger (longer tongue when hungry = more acceleration)
  • Flies could accelerate away when they sense the tongue coming
  • Different frog personalities (patient vs aggressive = different strike thresholds)
  • Tongue could miss sometimes based on fly speed

The constraint of “acceleration only” forced me to think about how motion creates personality. A patient hunter isn’t patient because of how it looks, it’s patient because of when and how it accelerates.

 

Buernortey Buer – Assignment 2

Simulating the Free Movement of Clouds

Concept

This assignment is inspired by a scene from my favorite anime “Naruto” in which a character looks up at the sky and expresses a desire to be like the clouds, moving freely without worry and simply following the wind. That idea of effortless movement and quiet reflection became the foundation for this simulation.

To connect this idea to real world motion, I found a video online of clouds slowly drifting across the sky and used it as a reference. Rather than focusing on the visual appearance of the clouds, the emphasis was placed on replicating their movement. The behavior in the sketch is controlled entirely through acceleration, allowing motion to emerge naturally from wind like forces over time. While the clouds all move in the same general direction, small variations in their movement prevent the motion from feeling uniform or repetitive.

The intention of this assignment is to recreate the calm experience of watching clouds pass by, capturing a feeling of flow and freedom through motion rather than visual detail.

Code Highlight

A key part of the simulation is how wind direction and strength are controlled using Perlin noise, which provides smooth and natural variation over time:

let baseWindAngle = PI; // base direction pointing leftwards
let noiseVariation = (noise(frameCount * 0.003 + this.offset) - 0.5) * (PI / 6);
let windAngle = baseWindAngle + noiseVariation;
let wind = p5.Vector.fromAngle(windAngle);
wind.setMag(0.05);
this.acc.add(wind);

Here, each cloud experiences a base wind force pushing it leftwards (PI radians), with subtle angle variations added by noise for a natural, organic drift.

Embedded Sketch

Reflection and Future Ideas

This project helped me understand how motion driven entirely by acceleration can create lifelike, organic behavior without directly manipulating position or velocity. Using Perlin noise to vary the wind direction over time introduces natural unpredictability, allowing each cloud to move with variation rather than uniform motion. Watching the clouds drift smoothly across the canvas feels calm and meditative, similar to observing real clouds moving through the sky.

In the future, this system could be expanded by allowing clouds to interact with one another, respond to changing environmental conditions, or evolve based on different wind patterns. Small visual enhancements, such as lighting changes or atmospheric shifts, could also be explored while keeping the movement rooted in physics-based rules. Overall, this simulation captures a quiet moment of nature’s flow and reflects the peaceful experience of simply watching clouds pass by.

Haris – Assignment 2

Concept

For this weeks assignment we were asked to mimic movement we saw in the nature. To find out what I will do I decided to take a walk around the campus and observe movement around me. Other than students rushing to classes I also observed the trees moving under the subtle wind, but specifically I noticed the leaves falling off of the trees. This made me think, the movement of the leaves is not just done by the gravity pulling them towards the ground, but also by the wind pushing them around. I decided to try and mimic this movement.

I also wanted the sketch to be interactive so I gave the user “the power of the wind” with their mouse. So if you move your mouse closer to the leaf it will move away from it, simulating the wind in real life and how if affects a falling leaf.

Process

After getting the idea I decided to get straight to coding it. The first order of business was creating the background which includes the sky, the ground and the trees. But I didn’t want to just create a background that would be the same for everyone, I wanted to give some sense of randomness. So I came up with an idea to make a forest that randomly generates every time.

After I was happy with this and I made sure the generation would be random it was time for the more difficult task and that was actually adding the leaf that falls down and adding the required logic to make it swirl a bit so it doesn’t really just fall like a rock.

class Leaf {
  constructor(x, y) {
    this.pos = createVector(x, y);
    this.vel = createVector(0, 0);
    this.acc = createVector(0, 0);

    this.size = 26;

    // Rotation
    this.angle = random(TWO_PI);
    this.spin = random(-0.03, 0.03);

    // Motion
    this.flutterStrength = 0.06;
    this.flutterChance = 0.02;
    this.dragK = 0.02;

    // Background wind
    this.windT = random(1000);
    this.baseWindStrength = 0.18;
  }

I created a leaf class that would “manage” all the leaves.

I was really happy with the result, but there is one issue with this. The leaves start from way up above the trees so it looks pretty unnatural. To fix this I created a new function which would spawn a leaf on a random tree foliage.

function spawnLeafFromTree() {
  let t = random(trees);

  // Spawn somewhere near the canopy
  let x = t.x + random(-t.canopyW * 0.25, t.canopyW * 0.25);
  let y = t.trunkTopY + random(-t.canopyH * 0.35, t.canopyH * 0.05);

  return new Leaf(x, y);
}

And this is how I got the final result and something I am happy with.

Code Highlight

// Leaf swinging
if (random(1) < this.flutterChance) {
  let up = createVector(0, -random(0.4, 1.0) * this.flutterStrength * 10);
  let side = createVector(random(-1, 1) * this.flutterStrength * 6, 0);
  this.applyForce(up);
  this.applyForce(side);

  this.spin += random(-0.05, 0.05) * this.flutterStrength;
}

This part of the code is responsible for the subtle swinging of the leaves. It makes their movement natural so they don’t just smoothly fall on the floor by introducing upwards, sideways and rotational impulses simulating that brief moment when a leaf catches air as it falls. I am proud of all the little math that went into it and it was honestly fun tweaking numbers to get the right movement I was happy with.

Future improvements

In the future I would like to add a bit more functionalities and possibly gamify the sketch. I like how the leaves fall and how they all pile up at the bottom but maybe I would add a feature where the mouse wind would move the ones on the floor and maybe the point will be to clean the garden. Due to the deadline I didn’t add these features yet but it is definitely something I will continue working on and improving. Overall this was a really fun project and I can’t wait to explore it further.