Salem Al Shamsi – Assignment 5

Midterm Progress — “Shifting Grounds”

Concept — What Am I Making?

I’m building a generative desert landscape. Not a drawing of a desert, a system that grows one. Dunes form, shift, break apart, and settle, all on their own, driven by wind, tremors, and rain.

The title is “Shifting Grounds.”

The system moves through four phases like a timeline:

Wind → Ground Tremor → Rain → Stillness

  • Wind pushes sand around and builds dunes
  • Ground Tremor shakes things up, dunes collapse and spread out
  • Rain smooths the surface through erosion
  • Stillness everything settles. The terrain stops changing. This is the frame I export for my A3 prints

The simulation runs once and ends. It doesn’t loop.

Why a Desert?

I’m from the UAE. The desert isn’t just a landscape to me, it’s something I grew up around. I’ve always noticed how dunes shift and reshape themselves. Sand looks still but it never really is.

I want to explore that through code. How do dunes actually get their shape? Why are some tall and some flat? What happens when wind hits a ridge? This project is my way of digging into those questions and turning them into generative art.

Design — How Will It Work?
The Height Map

Instead of simulating thousands of sand particles (which is way too complex and slow), I’m using a height map. It’s just an array:

heightMap[0] = 45
heightMap[1] = 47
heightMap[2] = 52

Each index is a column on the canvas. The value is how tall the sand is at that spot. When I draw it, I fill from the bottom up to the height. That gives me a terrain profile, like a side view of the desert.

Why this approach:

  • Way more stable than particles
  • Easier to control
  • Better for high-res A3 output
  • Clean and simple
Rendering

The look is minimal. Warm sandy monochrome palette. Shading is based on slope:

fill(baseColor - slope * contrast)

Steep slopes = darker. Flat areas = lighter. This fakes sunlight hitting the dunes from the side and creates a 3D look using just math. No textures, no images, just numbers and color.

Code Design — Functions, Classes, Structure

Here’s how I’m planning to organize the code:

  • windPhase() — moves sand using Perlin noise for wind direction and strength. After moving sand, it checks slope stability (angle of repose) so dunes don’t become unrealistically steep
  • tremorPhase() — lowers the stability threshold temporarily so dunes collapse and spread. Adds small random jitter to simulate vibration
  • rainPhase() — averages each column’s height with its neighbors. This is what erosion does, peaks go down, valleys fill up, everything smooths out
  • renderTerrain() — draws the height map with slope-based shading
State Management

A variable like currentPhase controls which phase is active. Each phase runs for a set number of frames, then transitions to the next:

WIND → TREMOR → RAIN → STILLNESS

In stillness, the draw loop still runs but nothing changes. The terrain is frozen in its final form.

Key Variables

  • heightMap[] — the core data. One value per pixel column
  • windStrength — controlled by Perlin noise, varies across space
  • maxSlope — the angle of repose. How steep sand pile can be before it slides
  • currentPhase — which phase the system is in
  • phaseTimer — counts frames in each phase

Interactivity (Planned)

  • Different noise seeds = different landscapes each run
  • Keyboard controls to adjust wind strength or skip phases
  • Parameter presets for different “climates” (strong wind, heavy rain, etc.)
States and Variations

Each run of the sketch will look different because of Perlin noise; different seeds create completely different dune formations from the same rules. That’s what makes it generative. I don’t place the dunes. The algorithm does.

For my three A3 prints, I plan to create variation by:

  • Changing the noise seed (different dune shapes)
  • Adjusting wind strength and direction (some runs make tall, sharp dunes, others make gentle rolling ones)
  • Varying how long each phase lasts (more wind = more dramatic terrain, more rain = smoother result)

The final stillness frame from each run becomes a unique print.

The Scariest Part

The most frightening part of this project is the wind simulation.

If sand transport is too strong, everything flattens instantly, and no dunes form. If the slope stability rules are too strict, the terrain freezes before anything interesting happens. The whole project depends on finding the right balance between these forces.

What I Did to Reduce This Risk

I wrote a basic prototype that tests the two core mechanics together: wind transport and slope stability.

This isn’t the final system. It only has the wind phase. But it confirms that the core mechanic, the hardest part, actually works. The tremor, rain, and stillness phases will be simpler to add on top of this foundation.

Other Risks I’m Watching

The final print might look too simple on A3 paper. Since it is just a 1D height map, it could feel flat. I need to test it early. If it looks too basic, I might add more depth, like a fake 3D effect or layered lines. I will decide after the full system is working.

References
  • R.A. BagnoldThe Physics of Blown Sand and Desert Dunes (1941).
  • Angle of Repose — From granular mechanics. The maximum steepness a pile of sand can have before it slides.
  • Ken Perlin — Perlin Noise (1983).
  • Soil Liquefaction — When vibration makes sand temporarily act like liquid.
  • Aeolian Transport — The geological process of wind moving sand.

 

Salem Al Shamsi – Assignment 4

The Conductor — Invisible Hand

Concept & Inspiration :

For this project, I was inspired by Memo Akten’s “Simple Harmonic Motion #12 for 16 Percussionists.” In that piece, 16 performers stand on stage, and each one receives instructions from a computer through their earpiece when to step forward, when to hit their drum, and when to turn on their flashlight. They don’t know what the bigger picture looks like. They just follow their own simple instructions. But when you watch all 16 of them together, something beautiful and complex emerges.

I wanted to translate that idea into a visual sketch. Instead of real performers, I have 16 glowing nodes arranged in a circle. Instead of a computer sending cues through earpieces, I have an invisible point, “the conductor,” that orbits around them. When it gets close to a node, that node lights up. The conductor’s path starts clean and orderly, then gradually becomes chaotic and unpredictable, then returns to order. And the viewer can use their mouse to become a second conductor, creating a tension between human control and machine control.

 

Code I’m Proud Of:

getActivation() method from the Shockwave class:

getActivation(nodeX, nodeY) {
    let d = dist(this.x, this.y, nodeX, nodeY);
    let distFromWave = abs(d - this.radius);

    if (distFromWave < this.activationWidth) {
      return map(distFromWave, 0, this.activationWidth, 1, 0);
    }
    return 0;
  }

What this does is pretty simple: it checks how far a node is from the wave’s current edge. If the node is within the wave’s “thickness” (60 pixels), it gets activated stronger if it’s right on the edge, weaker if it’s at the boundary. If it’s outside that band, nothing happens. So when you click, the ring expands outward and each node lights up only when the wave actually reaches it, not all at once. That one small function is what makes the whole click interaction feel like dropping a stone in water instead of just flipping a switch.

Milestones and Challenges

Stage 1: Circle of 16 Nodes. I placed 16 nodes evenly around a circle using cos() and sin(). The main challenge was getting the spacing right and making the glow effect look soft instead of harsh.

Stage 2: The Invisible Conductor I added an invisible point that orbits the circle and activates nearby nodes based on distance. The tricky part was making the activation smooth without lerp(), the nodes just snapped on and off like a light switch, which looked bad.

Stage 3: Hit Flashes and Ripples. When a node reaches peak activation, it now flashes bright and sends out a ripple ring. The challenge was making sure the hit only fires once per pass, not every single frame while the conductor is nearby. I solved this with a simple flag called wasAboveThreshold.

Stage 4: Order to Chaos to Order. This is where it got interesting. I made the conductor’s path morph between a circle, a figure-8, and random noise over a 35-second cycle. Getting the blending right took some trial and error at first; the transitions were too sudden, and it looked glitchy instead of smooth.

Embedded Sketch

Stage 5:Polish and Mouse Interactivity I added connection lines between nodes, a center glow, film grain, and mouse interactivity. The mouse acts as a second conductor with a smaller reach (so you can only affect a few nodes at a time). Clicking sends a shockwave. The biggest challenge here was combining three different activation sources (machine, mouse, and shockwave) without them conflicting with each other.

Reflection

This project taught me a lot about how simple rules can create complex-looking behavior. Each node only knows one thing: how far it is from the conductor, but when you watch all 16 together, it looks like something alive. That’s basically the same idea behind Akten’s original piece, and I think that’s what makes it so powerful. If I had more time, I’d love to add sound, maybe a soft tone or drum hit when each node gets activated, so it feels more like an actual performance. I’d also like to try it with more nodes (maybe 32 or 64) to see how the patterns change. Another idea is to let the viewer switch between order and chaos manually using a key press, so they have even more control over the composition.

Salem Al Shamsi – Assignment 3

Al-Muraud (The Chase)

A simulation of UAE falconry using flocking behavior and physics forces

Embedded Sketch

How to Interact

  1. Move your mouse : The falcon follows and birds run away
  2. Click : Creates a dive attack with spinning chaos
  3. Press +/- : Add or remove birds
  4. Press R : Reset everything
  5. Press S : See the invisible force circles (debug mode)

Concept & Inspiration

I wanted to create something connected to UAE culture, so I chose falconry the traditional hunting practice where falcons chase desert birds called Houbara Bustards. The idea is simple: you control a falcon (the mouse), and it hunts a flock of birds. The birds try to stick together for safety, but when the falcon gets close, they scatter. There are also two green “oasis” spots where birds naturally want to gather. When you click, the falcon does a dive attack that creates a spinning vortex.

My inspiration came from:

Code Organization & Variable Names

I organized my code into two main classes:

1- Houbara Class (The Prey)

Variables:

  • perceptionRadius – How far a bird can “see” neighbors
  • panicLevel – Maps speed to fear (0 = calm, 1 = terrified)
  • maxForce – How sharply a bird can turn

Methods that organize behavior:

  • cohesion() – Pull toward flock center
  • separation() – Avoid crashing into neighbors
  • flee() – Escape from predator
  • seekOasis() – Drift toward safe zones
  • turbulence() – Get caught in chaos vortex
  • flock() – Combines all forces with priorities

2-Falcon Class (The Predator)

Variables:

  • wingAngle – For flapping animation
  • sizeMultiplier – Grows when moving fast

Methods:

  • follow() – Smoothly chase mouse
  • show() – Draw with animated wings

Global Variables

Clear names that explain themselves:

  • diveActive – Is turbulence happening right now?
  • divePos – Where did the user click?
  • diveDuration – Countdown timer for chaos
  • showDebug – Toggle for seeing perception circles

Code Highlights

Here are three pieces of code I’m particularly proud of:

1. Panic Escalation System
// FLEE: Escape from predator
// Force strength increases as falcon gets closer (gradient of fear)
flee(target) {
  let perceptionRadius = 150; // How far bird can sense danger
  let desired = p5.Vector.sub(this.pos, target); // Point AWAY from falcon
  let d = desired.mag(); // Distance to falcon
  
  // Only flee if falcon is within perception range
  if (d < perceptionRadius) {
    desired.setMag(this.maxSpeed); // Set to maximum speed (fleeing urgently)
    let steer = p5.Vector.sub(desired, this.vel); // Steering = desired - current
    steer.limit(this.maxForce); // Don't turn impossibly sharp
    
    // KEY FEATURE: Map distance to force strength
    // Close (0px) = 2x force, Far (150px) = 0.5x force
    let strength = map(d, 0, perceptionRadius, 2, 0.5);
    steer.mult(strength);
    
    return steer;
  }
  return createVector(0, 0); // No force if falcon is far
}

The map() function creates a gradient of fear. At 0 distance = 2x force. At 150 pixels = 0.5x force. This makes the behavior feel natural instead of just on/off. Birds don’t just “run”, they panic MORE as danger gets closer.

2. Creating the Spinning Vortex
// Create spinning vortex force
let toCenter = p5.Vector.sub(diveCenter, this.pos);
let vortex = toCenter.copy();
vortex.rotate(HALF_PI); // KEY: Rotate 90° transforms "pull" into "orbit"

// Add random chaos
let chaos = p5.Vector.random2D();
chaos.mult(random(2, 5));

// Combine structured spin + random chaos
let turbulence = p5.Vector.add(vortex, chaos);

The key insight is that rotating a force 90 degrees turns “pull toward center” into “orbit around center”. Then adding random chaos makes it unpredictable but still structured. This one line vortex.rotate(HALF_PI) is the difference between an explosion and a whirlwind.

3. Weighted Separation Force
let diff = p5.Vector.sub(this.pos, other.pos); // Point away from neighbor
diff.div(d); // IMPORTANT: Closer neighbors create stronger push

Dividing by distance means: bird at 10px pushes 10x harder than bird at 100px. This single line creates realistic personal space. It’s elegant math that produces natural behavior.

Development Milestones & Challenges

I built this in 6 steps, adding one feature at a time:

Milestone 1: Basic Birds Moving Around

I started by creating a Houbara class with basic physics: position, velocity, and acceleration. At this point, birds just drifted randomly across the screen.

Challenge: Getting the triangle shape to point in the direction they’re moving using rotate(this.vel.heading()).

At first I tried rotating without translate() first, which made all the birds rotate around the canvas origin (0,0) instead of their own centers. Solution: Use push(), then translate() to the bird’s position, then rotate(), then draw the shape, then pop(). The order matters!

 

Milestone 2: Flocking Behavior

Added two forces based on Craig Reynolds’ Boids algorithm:

  • Cohesion – Birds want to move toward the center of the flock
  • Separation – Birds don’t want to crash into each other

Challenge: At first, all the birds just merged into one blob. They were stuck together in a tight cluster.

Solution: I made the separation force stronger (1.5x weight) and gave it a smaller radius (50px vs 100px for cohesion). This creates the “nervous flock” behavior they want to stay together but maintain personal space.

 

Milestone 3: Falcon Chases Birds

Made the mouse act like a predator using Reynolds’ Steering Behaviors. Birds flee when the falcon gets within 150 pixels.

Challenge: The flee force was either too weak (birds didn’t care about falcon) or too strong (birds shot off screen instantly).

Solution: I used map() to scale flee force from 0.5x to 2x based on distance. This creates realistic panic where birds freak out more when danger is right on top of them. It’s a gradient instead of binary.

 

Milestone 4: Dive Attack Turbulence

When you click, it creates chaos at that spot. The turbulence combines two things:

  • A vortex that spins birds in a circle (by rotating the force vector 90 degrees)
  • Random chaos pushing birds in unpredictable directions

Challenge: I initially just pushed birds away from the click point, which looked like an explosion. Boring.

Solution: The breakthrough was understanding that vortex.rotate(HALF_PI) turns a “push away” force into circular motion. This creates the spinning whirlwind effect.

 

Milestone 5: Making It Look Good

Added visual improvements:

  • Created an actual Falcon class with flapping wings
  • Added the two green oasis spots
  • Birds leave motion trails
  • Birds change color based on speed (tan → reddish)
  • Sand particles scatter during dive

Challenge: I accidentally put the seekOasis() function in the Falcon class instead of the Houbara class. Got error: TypeError: this.seekOasis is not a function

Solution: Read the error message carefully! It told me exactly what was wrong. Moved the method to the correct class (birds seek oases, not falcons).

 

Milestone 6: Polish & Controls

Final touches:

  • Designed the UI with desert colors (browns and golds)
  • Added keyboard controls (R, +, -, S)
  • Made the oases pulse using sin() animation
  • Changed edge wrapping to bouncing physics
  • Made the falcon grow bigger when moving fast

Challenge: The perception circle was appearing in the wrong spot because it was inside the falcon’s rotation transformation.

Solution: I moved the circle drawing from inside Falcon.show() to the main draw() function, before any transformations are applied. Now it uses absolute world coordinates instead of the falcon’s rotated local coordinates.

The final polished version with all features is available in the embedded sketch above.

How the Forces Work Together

Each bird calculates 5 forces every frame and combines them:

  1. cohesionForce.mult(1.0); // Want to stay with group
  2. separationForce.mult(1.5); // Don’t crash into neighbors
  3. fleeForce.mult(2.5); // RUN FROM DANGER (strongest)
  4. oasisForce.mult(0.8); // Drift toward safety
  5. turbulenceForce.mult(2.0); // Get caught in chaos

The weights create a priority system:

Survival > Safety > Chaos > Togetherness > Comfort

This matches how real animals behave: immediate threats override long-term goals.

Reflection

What I Learned

Simple rules create complex patterns. Each bird only knows about its nearby neighbors, yet the whole flock moves as one. This is called “emergent behavior.”

Small numbers matter.

Changing flee force from 2.0 to 2.5 completely changed how scared birds act. The difference between good and great simulation is often just finding the right numbers.

Building step-by-step works.

Adding one feature at a time made debugging way easier than trying to do everything at once.

Theme matters.

Framing this as falconry instead of “particles following forces” made it way more interesting.

What Worked Well

  • Force priority system feels natural (survival > safety > togetherness)
  • Visual feedback makes invisible forces visible (color changes, trails, size)
  • Keyboard controls make it interactive
  • Vortex turbulence looks really cool

What I’d Improve

  • Plan UI design earlier instead of adding it last
  • Use systematic testing for force weights instead of random tweaking
  • Add sounds (wing flaps, bird chirps, dive whoosh)
  • Implement energy system (birds get tired, need to rest)
  • Create visual dive animation (falcon swoops before turbulence)

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.

Reading Reflection – Week 1

Reading Reflection on The Computational Beauty of Nature by Gary William Flake

Before reading The Computational Beauty of Nature by Gary William Flake, I honestly never connected nature to computer programs at all. In my mind, computers were something artificial that humans fully control, while nature was something completely different and separate. For example, when I write code, I usually think about building apps or solving clear technical problems, not about how birds move, how ants organize, or how weather behaves. This reading changed the way I see that. The author explains that we should focus “not with ‘What is X?’ but with ‘What will X do?’” (p. 5), and this made me realize that code can be used to study real life behavior, not just screens. He also says, “The goal of this book is to highlight the computational beauty found in nature’s programs” (p. 5), which helped me understand that many natural systems follow rules, just like programs. The idea that “simple units… when combined, form a more complex whole” (p. 4) made me think of things I see every day, like how traffic in Abu Dhabi sometimes looks chaotic even though each driver is just following simple rules. I do not feel the author is biased, because he supports his ideas using examples from many different fields like biology, economics, and computing. This also made me wonder how far we can really simulate nature before systems become too complex to fully control.

Another part that affected me was the discussion of reductionism and holism. The author defines reductionism as the idea that “a system can be understood by examining its individual parts” (p. 2), but he also explains that “the whole of the system [can be] greater than the sum of the parts” (p. 4), which is what holism means. This really connects to how I usually solve problems by breaking them into pieces, especially in programming, but it also shows why that is sometimes not enough. The ideas of agents and interactions also made a lot of sense to me, especially when the book explains that scientists study “agents … and interactions of agents” (p. 3). For example, one person in a group project is simple, but when many people work together, the result can become very different and sometimes unpredictable. The book also says, “Interesting systems can change and adapt” (p. 5), and this reminded me of how humans, over many years, gain experience, learn from their mistakes, and slowly improve. This reading even made me rethink my capstone idea. Instead of only building something purely technical, I started thinking about working on a project related to nature or real life systems, something that can actually make life easier or better, not just something that runs on a screen.

 

Assignment 1a – Code

Concept : My sketch simulates one simple agent moving over time, like one driver moving through traffic. The agent switches between two behaviors: random drifting and following the mouse. The switch happens only when a time cycle ends, and probability decides which behavior will happen next. The agent leaves a fading trail so we can see its full path and how small decisions over time create a larger pattern. The trail color changes using HSB color space, which means the color slowly moves through different hues instead of using fixed RGB values. In this version, the color also responds to the agent’s movement speed, so faster motion causes quicker hue changes and stronger saturation and brightness. A timer bar on top shows how close the system is to switching behaviors.

Code Highlight : One part of the code I am proud of is the visual timer bar at the top of the screen. It shows the passage of time before the agent switches behavior, and it also changes color from green to red as the end of the cycle approaches. This makes the system easier to understand instead of hiding the logic.

// "timer" increases every frame
// "currentLimit" is how long the current mode should last

// Convert timer into a value between 0 and 1
let p = timer / currentLimit;

// Change color based on progress:
// 120 = green at start, 0 = red at end
let barHue = map(p, 0, 1, 120, 0);

// Set the fill color using HSB
fill(barHue, 90, 100);

// Draw the bar:
// barW * p makes the bar grow as time passes
rect(barX, barY, barW * p, barH, 7);

Embedded Sketch:

Reflection / Future Ideas : This project helped me understand how a very simple rule and one agent can create a long and interesting path over time. Instead of only seeing the current position of the agent, the fading trail shows the history of its movement, which made me think more about time and process, not just results. I also understood better how systems work in cycles, using a timer, and how behavior changes depending on simple conditions.

In the future, I would like to add more than one agent and see how their paths interact. I am especially interested in trying an example similar to traffic, where one agent (one driver) can create a big effect on the whole system, even though it is only one small part of it. I also want to experiment with different types of movement, like smoother motion or more natural behavior, and see how that changes the overall pattern.