Assignment 2 documentation – Mustafa Bakir

What inspired this project is my fish, Abdulfattah, a Betta fish that was gifted to me from a very dear person to my heart.

This sketch mimics natural fish movement when it spots food. The user moves the mouse around and upon clicking you essentially drop a fish food pellet, and the fish mimics natural movement and acceleration towards food.

I first started t project by adding a background I found online

Blue water surface template in cartoon style illustration

then I made a rectangle that will later be a fish to start simulating it’s  movement.

then I wrote very simple code with if statements just as a base for my fish movement.

 

then I updated my code to lerp (linear interpolation) towards the mouse.

new_pos= current_pos + (target_pos – current_pos) * speed

 

After that I started implementing dropping fish pellets, I started with creating a simple function to spawn pellets with an array of circles.

let circles[];

  //in draw
  for (let circle of circles) {
    fill(139, 69, 19); // brown
    noStroke();
    ellipse(circle.x, circle.y, 20, 20);

function mousePressed() {
  circles.push({x: mouseX, y: mouseY});
}

Then I added a sinking motion for the pellets with a slight drift using the sin function to simulate natural waves pushing pellets around as they are sinking with a random angle for variation.

// draw food pellets
for (let i = circles.length - 1; i >= 0; i--) {
  let circle = circles[i];
  
  // make circle float downwards
  circle.y += circle.speed;
  
  // increment the angle for sin
  circle.angle += 0.05;
  
  // subtle drift for food pelletes
  let drift = sin(circle.angle) * 20;
  
  // draw circles
  fill(139, 69, 19);
  noStroke();
  ellipse(circle.x + drift, circle.y, 20, 20);

 

then I edited the code to make the rectangle follow the pellets instead of the mouse. For error handling, the pellets are put in a stack such that the rectangle eats the pellets using a queue as a data structure following the FIFO (first in last out) principle.

 

A challenge I faced:

As shown in the previous gif, there was a problem where the rectangle can’t eat the food because the pellets are drifting and sinking. This is happening because the rectangle is trying to go the position of that circle but it doesn’t account for the drifting and sinking, therefore, its more like it’s tracing the pellet rather than trying to catch it.

The way I tackled this challenge is also a highlight of the code that I’m proud of.

.I fixed this by predicting where each pellet would be 10 frames ahead, accounting for sinking and horizontal drift. I calculated the direction vector and euclidean distance to this predicted target, then normalized it to apply acceleration forces. The velocity builds gradually but it’s not fully smooth yet but I’ll get to that later. I multiplied velocity by 0.92 each frame for friction, cap the maximum speed, then update position. When the fish gets within 30 pixels of a pellet, it gets removed from the queue with shift() and reduce velocity by 70%. This creates a deceleration effect before accelerating toward the next pellet.

function followCircles(){
  // if there are circles, follow the first one following FIFO principle
  if (circles.length > 0) {
    let target = circles[0];
    
    // predict where the pellet will be
    let futureY = target.y + target.speed * 10;
    let futureAngle = target.angle + 0.03 * 10;
    let futureDrift = sin(futureAngle) * 1.5;
    
    let targetX = target.x + futureDrift; // i add the predicted position here so the fish can catch the food
    let targetY = futureY;
    
    // calculate direction to predicted position
    let dx = targetX - x;
    let dy = targetY - y;
    let distance = dist(x, y, targetX, targetY); // calculate the eucilidian distance of the fish and the pellet
    
    // normalize direction and apply acceleration
    if (distance > 0) {
      vx += (dx / distance) * acceleration;
      vy += (dy / distance) * acceleration;
    }
    
    // apply friction for more natural movement
    vx *= friction;
    vy *= friction;
    
    // limit speed
    let speed = dist(0, 0, vx, vy);
    if (speed > maxSpeed) {
      vx = (vx / speed) * maxSpeed;
      vy = (vy / speed) * maxSpeed;
    }
    
    // update position with velocity
    x += vx;
    y += vy;
    
    // check if rectangle is touching the circle 
    let actualDistance = dist(x, y, target.x + target.drift, target.y);
    if (actualDistance < 30) {
      circles.shift(); // eat the circle
      // reduce velocity when eating 
      vx *= 0.3;
      vy *= 0.3;
    }
  } else {
    // slow down when no target
    vx *= 0.9;
    vy *= 0.9;
  }
}

another problem I faced was the fish was getting stuck around the corners but I easily fixed that but implementing a function that lets the fish wander using perlin noise (Thanks professor Jack!!)

Then I added the fish’s sprite from this website.

Future improvements and reflection:

I want to have a simulation of the background such that it actually simulates fluids and looks like water. I also have 3 more fish in the tank that are Abdulfattah’s friends that I want to add, they always steal his food so it would be more realistic that way. Moreover I want to have a bigger canvas so I can add object you naturally find in the ocean or the one’s I have in my fish tank, and an algorithm that makes the fish occasionally hide behind those objects. Lastly, I want an algorithm where  sometimes the fish just rests in the tank doing nothing, which would add more realism to the sketch.

Assignment 2 : Yash

Code Production: The Physics of the Chase

Concept & Inspiration

For this assignment, I was tasked with finding an example of movement in nature and simulating it using code. I started by looking at how birds move in flocks. There is a specific fluidity to how they accelerate and glide that feels very different from mechanical movement.

I found this video of birds in flight which served as my primary visual reference:

https://www.youtube.com/watch?v=SCX946jtKXw

The Pivot

While watching the video, I realized that we almost always observe birds from the ground looking up. I wondered: How do birds see each other?

I decided to shift the perspective. Instead of a human watching a bird, I wanted to create a First-Person Flyer (FPF) experience. The concept became a “Bird Chase Simulation,” where the user plays as a predator bird (or perhaps a playful friend bird) trying to catch up to a leading bird.

My goal was to give the movement “personality” not just through the way the bird looks, but through how the acceleration feels. High acceleration shouldn’t just mean “go faster”, it should feel energetic and slightly chaotic, changing the bird’s perspective of the world.

Process

Before I could make it look like a bird, I had to make it move like one. The prompt required controlling motion only by manipulating acceleration.

I started with a greyboxing phase.  I created a relationship where the distance between the player and the target wasn’t represented by X/Y coordinates, but by the scale of the target. If you accelerate and get closer, the target gets bigger,if you stop flapping (drag), you fall back, and the target shrinks.

Here is a screen recording of that initial physics test:

 

The Code

The part of the code I am most proud of is the relationship between the Acceleration Input and the Camera Shake.

The prompt asked us to give the movement personality. I achieved this by making the “camera” (the viewport) physically shake when the user pushes the acceleration slider to the max. It simulates the physical exertion of flapping wings hard against the wind. It bridges the gap between the math (acceleration numbers) and the feeling (struggle/speed).

Here is the snippet that handles that logic:

// === PHYSICS SECTION ===
  let accVector = createVector(0, accInput);
  playerVel.add(accVector); 
  
  // === CAMERA SHAKE EFFECT ===
  // Add shake when accelerating hard (makes it feel more dynamic)
  let shakeX = 0;
  let shakeY = 0;
  
  // Only shake if we are putting in significant effort (> 0.05)
  if (accInput > 0.05) {
    // Map the shake intensity to the acceleration input
    let shakeAmt = map(accInput, 0, 0.5, 0.5, 6); 
    shakeX = random(-shakeAmt, shakeAmt);
    shakeY = random(-shakeAmt, shakeAmt);
  }

  // Later, in the drawing section:
  translate(width/2 + shakeX, height/2 + shakeY);

The Simulation

To finalize the piece, I added a circular clipping mask to create a “binocular” or “focus” effect, simulating the bird’s vision. I also added wind lines that react to the player’s speed to create a parallax effect, enhancing the sensation of forward momentum.

Instructions:

  1. Use the slider at the bottom to control your Acceleration (how hard you are flapping).

  2. Try to catch up to the bird in front of you.

  3. Notice how the view shakes and the wind rushes faster as you exert more energy.

Reflection & Future Work

This project was a great exercise in using simple variables (acceleration and scale) to create a 3D illusion. The hardest part was tuning the “drag” or air resistance. If the drag was too high, it felt like flying through soup; too low, and the bird felt like a rocket with no weight.

I’m happy with how the beak breathing animation and the camera shake added life to the static shapes.

For the future: Currently, the movement is linear (forward/backward). I would love to introduce steering, allowing the player to move left and right to chase the target bird as it weaves through the sky. I also think adding a Stamina bar would add a game-like element, forcing the player to choose when to glide and when to sprint.

Amal – Assignment 1a

The Computational Beauty of Nature – Ch1

The concepts explored in this reading were very central to how we view things and analyze not only nature but also human-made systems like the stock market. What left a strong impression on me is how important it is to analyze interaction in order to truly understand what something is. At the beginning of this chapter, Flake introduces the idea of reductionism, which is the process of reducing something into increments to better understand its true nature.

In my understanding, we are invited to look at this from a rather “scientific” lens in order to see how we could apply a similar concept in computing. This leaves me with the impression that it is very important for us to first understand how dissecting something in terms of meaning can then help us introduce that understanding to a computer.

The Concept

My concept is inspired by fireflies. Having never experienced them, I have always been curious about what it would feel like to interact with one, so why not simulate it?

For the sake of simulating human-to-firefly interaction, I did not want the firefly to simply float around randomly. I wanted it to follow the mouse around the sketch in order to translate a sense of curiosity between both the firefly and the user.

I implemented a Gaussian random walk (List 1) and mapped the motion to color and brightness to create a firefly glow effect (List 2).

Code that I am proud of
let glow = 220 + randomGaussian() * 20;
glow = constrain(glow, 140, 255);

I’m proud of this part of the code because I wanted the firefly’s glow to feel as natural as possible. Using Gaussian randomness makes the brightness fluctuate gently instead of jumping unpredictably, and constraining the values keeps the light within a realistic range.

The Sketch

Reflection

Initially, I wanted to mimic bacteria and binary fission, but that idea felt a bit too ambitious at this stage. I decided to step back and focus on exploring motion in a simpler way, which led me to this firefly concept. I was interested in creating something that felt organic and calm rather than complex.

For future work, I wanted to place the firefly over an image of a forest, but I realized that doing so would either cause the firefly’s trail to disappear or require the background to fade over time. I think finding a way to balance a real forest image with the artificial movement of the firefly could be an interesting direction to explore further.

Saeed Lootah – Assignment 1

The Computational Beauty of Nature
by Gary William Flake

Immediately during the author’s section on reductionism I began to think about determinism but specifically a concept called Laplace’s demon. Coined by Pierre-Simon Laplace a French philosopher in the 19th century, it refers to the idea that if you reduced the world to its most fundamental particles and had complete knowledge of all existing particles and the forces acting upon them and the forces that they can act upon other particles with a strong enough calculator you could predict anything. Free-will, and randomness would be illusions. It’s the most reductionist concept I know of.

However, as the author continued he did not begin to discuss free will and the purpose of life. Rather:

We have, then, three different ways of looking at how things work. We can take a purely reductionist approach and attempt to understand things through dissection. We also can take a wider view and attempt to understand whole collections at once
(pg. 2)

…Or we can take an intermediate view and focus attention on the interactions of agents
(pg. 2)

I appreciated the middle approach that the author wanted to take since I believe it would be more practical than Laplace’s demon for example.

As he began to discuss the examples across nature I realized that the concept’s I’m going to have to keep in mind for the rest of the course are in the three paragraphs on page 4. They are too long to paste here but to keep it as short as I can: Parallelism, Iteration, and Learning. Other words were used but I picked those because I find them the most memorable.

My Code

(Click on the sketch and click and drag your mouse)

For this assignment I picked the following from List 1 and List 2 respectively:

– Try implementing a self-avoiding walk
– Walk through RGB or HSB space (as opposed to XYZ)
What you’re looking at is a snake like shape which moves around in 3 pixel increments (step_size in the code) and it goes in whichever direction it wants to until it collides with itself at which point it stops.
At the head of the snake is a circle and there are lines for the path’s that it’s traversed previously.
In addition, the color of the lines or head of the snake changes depending on where it’s located on the canvas. I based it off of the color mode HSL which stands for Hue Saturation Lightness. Hue is an angle from 0-360 degrees (search up HSL color wheel) and the canvas is just set to be the window height and not a hard coded value. So I used the map function. I did the same for Saturation but I kept lightness at 50, if it was at 100 it would always be white, if it was at 0 it would be black. I could have used HSB and kept B at 100 and it was HSB which is why in the class Walker it’s b: 100, I forgot why I changed it to be honest.

My Personal Highlight

placement_calculation(x, y) {

    let x_remainder = x % step_size
    let y_remainder = y % step_size

    let new_coordinate = new Coordinate(x - x_remainder, y - y_remainder)

    return new_coordinate;
}

The reason I picked these few lines of code was because it was something I had come up with myself and had not done before. To ensure that all of the snakes/walkers stay on the same grid/lattice when placed I used this function. It takes the modulus of x, and y, with step_size and then for the new coordinate that’s being outputed its the x/y value given minus the remainder.

This ensures that the x,y coordinate that the snake is placed on is always a multiple of the step_size. I’m not sure if that made sense but it was the most efficient method I could think of to keep everything on the same grid.

Reflection

I’m happy with how the sketch looks and I think the code is somewhat easy to read. Going into this project I’ve been trying to make more readable code using variable names that explain what the variable is rather than an abbreviation and relying on comments. In the event that I did use an abbreviation I wrote a comment above (in the is_surrounded function).

With that being said there are some things I would like to change. Most importantly rather than relying purely on random chance I would like to implement some kind of formula or iterative design that can make the snake/walker last longer. And, a function to ensure that walkers don’t cross the paths of other walkers.

 

Buernortey – Assignment 1

Concept

For this project, I created a random walker that moves using dynamic probabilities instead of fixed directions. At every step, the walker makes a decision: it has a 50% chance to move toward the mouse and a 50% chance to move in a random direction. This creates motion that sometimes feels intentional and sometimes unpredictable.

To connect motion to another medium, I mapped movement into color by letting the walker walk through HSB color space. As the walker moves, its hue slowly shifts, leaving a trail of changing colors. This makes the motion visible not only through position, but also through color.

Code Highlight

The part I am most proud of is the simple probability rule that controls the walker’s behavior:

// 50% chance: move toward mouse
if (random(1) < 0.5) {
  let target = createVector(mouseX, mouseY);
  let dir = p5.Vector.sub(target, pos);
  dir.setMag(step);
  pos.add(dir);
} 
// 50% chance: random move
else {
  let angle = random(TWO_PI);
  pos.x += cos(angle) * step;
  pos.y += sin(angle) * step;
}

With only one small decision, the system creates two very different behaviors: attraction and randomness. This balance makes the motion feel alive without being complicated.

Embedded Sketch

Reflection and Future Work

This project showed me how simple rules can create expressive motion. Even with only two possible choices, the walker feels responsive and unpredictable at the same time. I also liked how color helped reveal the path and rhythm of the movement.

In the future, I would like to change the probability based on the distance to the mouse so the attraction becomes stronger or weaker depending on position. I would also like to add multiple walkers with different behaviors and experiment with Gaussian step sizes to create smoother motion. Another idea is to map movement to sound, such as pitch or stereo pan, instead of color.

Overall, this project helped me understand how probability and interaction can shape motion in simple but interesting ways.

 

Buernortey-Computational beauty of nature, Reading response

While reading the introduction of The Computational Beauty of Nature, I realized that the author is challenging the way we usually try to understand systems. We often break things into smaller parts, but Flake explains that this is not enough to explain how complex behavior appears. Even if we understand each part well, we still may not understand what happens when many parts interact together. This idea changed the way I think about learning and problem solving.

The example of ants stood out to me the most. A single ant behaves in a simple way, but together ants form organized colonies with complex behavior. I found this interesting because it shows that complexity does not need complicated rules. It can come from simple actions repeated many times. This reminded me of programming, where small pieces of code can create systems that behave in surprising ways.

I also liked the idea that nature itself “computes.” Systems react to their environment, adapt, and evolve over time. Seeing learning and evolution described in this way made me realize that computer science is connected to many other fields, not just technology.

Overall, this chapter made me more curious about how simple rules can lead to complex behavior, and it helped me see computation as a way to understand patterns and intelligence in the world, not only as something done by machines.

Reflection on Chapter 1 – The Computational Beauty of Nature

The whole reductionism vs. emergence thing really clicked for me this week, especially after coding that self-avoiding creature.
Flake talks about how knowing what a single ant does won’t tell you anything about what an ant colony can do. That’s exactly what I experienced with my sketch. Each point in my creature just checks “can I move here without hitting myself?” Super simple rule. When you watch it grow though, you get these weird tentacle formations and organic shapes that I definitely didn’t program. The complexity just emerges from repeating that one simple check.
What got me thinking was his point about nature using the same rules everywhere. The collision detection in my code works the same way for anything avoiding anything else. Planets avoiding black holes, people maintaining personal space in crowds, cells not overlapping during growth. One rule, infinite applications.
The part about computers blurring the line between theory and experimentation felt super relevant too. When I was debugging my creature, I was literally experimenting with artificial life. Tweaking the growth probability or cell size and watching how behavior changes feels more like running biology experiments than writing traditional code. You make a hypothesis (“smaller cells will create more detailed shapes”), run it, observe what actually happens (nope, just slower performance), adjust and repeat.
I’m curious about the “critical region” he mentions between static patterns and chaos. My creature usually grows until it gets trapped and can’t find new space. That feels like hitting some kind of critical point where the system freezes. Maybe if I added randomness to let it occasionally break its own rules, it could escape those dead ends? Then would it still count as “self-avoiding” though?

Self-Avoiding Morphing Creature

Concept

 

For this week’s assignment, I combined a self-avoiding walk with a morphing creature shape. Basically, I wanted to create something that grows organically without ever crossing itself, like a blob that’s aware of its own body.

The creature starts as a small circle and then tries to expand outward by adding new points. Before placing each new point, it checks if that spot is already occupied using a simple grid system. If it’s clear, the point gets added and the shape grows. If not, it tries a different direction.

What makes it feel alive is the constant wiggling, each point shifts slightly every few frames, but only if it won’t cause a collision. This creates this pulsing, breathing effect that’s kinda so cool to watch.

Code Highlight

An interesting part in my code is the collision (closely distant) detection:

isBlocked(x, y, skipIdx) {
  // Check if grid cell is taken
  if (occupied[this.gridKey(x, y)]) return true;
  
  // Check if too close to other points
  for (let i = 0; i < this.points.length; i++) {
    if (i === skipIdx) continue;
    if (dist(x, y, this.points[i].x, this.points[i].y) < cellSize * 1.5) {
      return true;
    }
  }
  return false;
}

It’s doing a double-check: first looking at the grid to see if that cell is occupied, then measuring the actual distance to nearby points. The skipIdx parameter lets a point check if it can move to a new spot without counting itself as a blocker. Simple but effective.

Embedded Sketch

Future Ideas

For future improvements:

  • Add multiple creatures that avoid each other
  • Make the growth pattern follow the mouse or respond to sound
  • Different growth strategies (maybe prefer growing upward, or toward light sources)
  • Color shifts based on age or density of the creature

Reading response – Mustafa

This chapter hit me hard. Flake asks the question I’ve been circling around for years: why can’t we predict everything if we understand the parts? The ant colony example nails it. You can study individual ants all day long. You can catalog their behaviors, map their neural pathways, document their castes. You still won’t predict the emergent sophistication of millions of them working together.

I love how Flake frames computation as nature’s language. We’ve been so focused on dissecting things that we forgot to ask “what does this do?” instead of “what is this?” That shift feels enormous. A duck isn’t just feathers and bones. A duck migrates, mates, socializes, adapts. The doing matters as much as the being.

The pdf’s structure fascinates me. Fractals lead to chaos, chaos leads to complex systems, complex systems lead to adaptation. Everything connects. I’ve read excerpts on chaos theory. I’ve read excerpts on evolution. I’ve never seen someone draw the lines between them so clearly. Simple rules, iterated over time, create everything from snowflakes to stock markets.

The timing matters too. Flake wrote this in 1998, right when computers stopped being tools and became laboratories. We could finally simulate systems too complex to solve analytically. That changed everything. Meteorologists, economists, biologists: they all started speaking the same computational language.

What gets me is the humility baked into this approach. Reductionism promised we could know everything by breaking it down far enough. Flake shows us the limits. Some things are incomputable. Some systems defy long-term prediction. Understanding quarks doesn’t help a doctor diagnose patients. Understanding individual neurons doesn’t explain consciousness.

Mohammed – Assignment 1

Concept

My concept is “Nervous Fireflies” that implements a Levy Flight. Most of the time, the firefly hovers in a small area (small steps), but occasionally it gets startled and zooms to a new location (a very large step).

To visualize this, I mapped the “step size” to the size of the circle. When it’s hovering, it is a tiny dot. When it zooms, it expands into a large burst of light.

Code Highlight

I am proud of this section because it creates the Lévy Flight behavior without using complicated math formulas. I simply used random(100) like rolling a 100-sided die. If I roll a 1 (a 1% chance), the firefly takes a huge jump. Otherwise, it takes a tiny step.

I was also proud of the trigonometry part which is particularly thematic in situations where you want to convert an angle into cartesian coordinates.

step() {
    // CHOOSE DIRECTION
    let angle = random(TWO_PI);

    // CHOOSE DISTANCE (The Lévy Flight Logic)
    // Pick a random number between 0 and 100
    let r = random(100);

    // 2% chance of a BIG jump
    if (r < 2) {
      this.currentStepSize = random(50, 150);
    } 
    // 98% chance of a small step
    else {
      this.currentStepSize = random(2, 5);
    }

    // MOVE
    // convert angle/distance into X and Y
    let xStep = cos(angle) * this.currentStepSize;
    let yStep = sin(angle) * this.currentStepSize;
    
    this.x += xStep;
    this.y += yStep;

 

Reflection & Future Improvements

I realized that “random” doesn’t have to mean “even.” By checking if random(100) < 2, I was able to create a behavior that feels much more organic and alive than just moving randomly every frame.

For the future, I could implement:

Mouse Interaction: I want to make the firefly scared of the mouse, so if the mouse gets too close, it forces a “big jump” immediately.

Interaction Between Fireflies: Right now, the fireflies behave in isolation. It would be cool to have fireflies interact with one another using object to object communication.