Haris – Midterm Progress

Concept

For the midterm I decided to go back to space theme like I did in assignment 3. I really liked the design of the planets I came up with and wanted to possibly further explore that design with adding particles as an addition. I want again to use the planets as attractors but I would like to explore the idea of using the particle systems as little particles in space that go around these planets and make different constellations like Saturn’s ring.

Implementation

  • Background atmosphere

    • Stars placed in the background randomly.

    • A starfield with subtle twinkling for texture and scale.

  • Planet body

    • A solid planet drawn with  shadows and rings to give depth.

  • Ring particle system

    • Each particle is assigned a target ring radius (three radius “bands”).

    • Motion is driven by a combination of forces:

      • Inward pull (gravity-like) to keep particles bound to the planet.

      • Tangential swirl to create orbit motion.

      • A spring force that pulls particles back toward their target radius so the ring stays structured.

Light damping/drag to keep it smooth and stable.

States/variation

At this point in time I still don’t have multiple states of the sketch, I am still thinking about what I could make different exactly for now some ideas were either placing different kinds of planets that have varying gravitational pull or removing the planets to create galaxy like objects. Or potentially giving an option to add multiple planets.

Scary parts

Right now the scariest part was actually making the particles go in a circle around the planet. I achieved this by doing the following:

First I calculate the vector pointing from a particle to the planet

let toCenter = p5.Vector.sub(planet.pos, p.pos);
let d = max(toCenter.mag(), 1);
toCenter.normalize();

After which I create a tangential force which actually gives the particles the circular motion

let tangential = createVector(-toCenter.y, toCenter.x);
tangential.mult(0.22 * planet.spin);
p.applyForce(tangential);

I also added some pull to keep the particles from going away

let grav = toCenter.copy().mult(0.14 * planet.massScale / (1 + d * 0.006));

And that’s how I created the ring around the planet. I am just a little worried if making the galaxy style sketch would bring more complexity to the design and if I will need to use something different for the particle movement.

 

Haris – Assignment 4

Concept

When looking at Memo Akten’s work there was one piece that really took my attention. It was the “Simple Harmonic Motion #12 (2015)”. This although seemingly simple work with people hitting drums with their flashlight really caught my attention by the way it was done with playing with the lights and having all the actors “controlled by the computer”. So I decided that this is the perfect piece to somehow try to recreate in a similar way in p5.

Process

To begin with i first made the “map”. I decided to go with a “stage” looking design to fit the theme so to create something that fits what I imagined I made a completely black background with gray boxes to indicate stages where the people could move.

After it was time to create the performers. I created a performer class where I could create each of the human like performers that would move around the screen. I also decided to give them hands to give them some personality.

At first I experimented with random timing for movements, but this did not feel intentional or rhythmic. The animation looked chaotic rather than composed. To fix this, I replaced random triggers with sine wave oscillators, meaning that every action was driven by harmonic motion instead of randomness.

let g = (sin(frameCount * 0.02 + this.pid * 0.7) + 1) * 0.5;
this.onStage = g > 0.65;

let a = (sin(frameCount * 0.05 + this.pid) + 1) * 0.5;
this.armTarget = a > 0.75 ? 1 : 0;

After motion was working, I implemented the spotlight effect. Rather than drawing a single circle of light, I layered multiple translucent ellipses. This creates a gradient glow that visually resembles stage lighting and feels more organic than a flat shape.

The final step was adding sound. Each time a performer raises their arms while in the spotlight, a drum sound is triggered. I detect this moment by checking for a transition from arms-down to arms-up. This event-based logic ensures the sound only plays at meaningful moments instead of continuously.

Code Highlight

The proudest part of my project was definitely the movement.

let g = (sin(frameCount * 0.02 + this.pid * 0.7) + 1) * 0.5;
this.onStage = g > 0.65;

let a = (sin(frameCount * 0.05 + this.pid) + 1) * 0.5;
this.armTarget = a > 0.75 ? 1 : 0;

I am particularly proud of this part because it captures the entire conceptual idea in just a few lines of code. Instead of manually controlling each performer or assigning scripted movements, each performer is moved by a sine wave with a slightly different phase offset. This means every performer follows the same rule but behaves differently over time.

Future Improvements

If I were to continue working on this project I would maybe like to add some interactivity into it. At this point in time I am not sure how interactivity would work on this project and in what sense it could be implemented so I would love some suggestions. I would also maybe work a bit on visuals, but overall I am really happy with the final project.

Haris – Assignment 3

Concept

For this week’s assignment I wanted to recreate one of the most beautiful motions in nature, shooting stars. My idea was to have the stars fall from the top but be affected by the planets gravity which changes their direction. I also decided to add a path (line) behind the shooting starts which slowly filles up the screen and creates this beautiful drawing of all the paths the stars took. The users can also click on the screen to move the planets around and thus create completely unique paths every time.

Process

First order of business was to create the star filled background and to add planets. This is also when I added the click to add planets function so I wouldn’t have to deal with it later.

After this was done it was time to get started on adding shooting stars. I decided to also give them a trail so they would actually look nicer while “falling” and wouldn’t just be a ball passing by.

This is done by first saving the last position of the star as the first one in the array:

// save tail
this.tail.unshift(this.pos.copy());
if (this.tail.length > this.tailMax) this.tail.pop();

After which we draw the tail on the last position of the star with this:

draw() {
  // Tail
  for (let i = 0; i < this.tail.length - 1; i++) {
    let a = map(i, 0, this.tail.length - 1, 220, 0);
    let w = map(i, 0, this.tail.length - 1, 10, 1);
    stroke(255, 255, 255, a);
    strokeWeight(w);
    line(this.tail[i].x, this.tail[i].y, this.tail[i + 1].x, this.tail[i + 1].y);
  }

And now we have a tail following the star. I also added the “this.tail.pop()” to make sure the last position in the array (not the starts last position, technically the “first” ones) is deleted to keep the array shorter. And now we had shooting stars in the sketch.

But I felt like something was missing so I added the lines that are left behind the start so add a nice trail like drawing to the experience. To do this I decided to use createGraphics to keep it cleaner and more organized and to make sure the paths will always be visible. Using createGraphics also allowed the trail drawing to persist independently of the main animation loop, which clears each frame. This separation made it possible to accumulate motion into a lasting visual pattern.

pathLayer = createGraphics(width, height);
pathLayer.clear(); // transparent at the start

let prev = s.pos.copy();
s.update();
// draw path
pathLayer.stroke(255, 35);
pathLayer.strokeWeight(1.2);
pathLayer.line(prev.x, prev.y, s.pos.x, s.pos.y);
s.draw();

The prev stores where the star was before updating and the update moves the star. Then we use .line to create the path which when run every frame creates the path that we see in the final product.

Code Highlight

Even though my proudest part of code is the path layer one where I create a path behind the shooting stars, since I went over that part of the code I will explain my second proudest.

function solarWind(x, y) {
  let a = noise(x * 0.01, y * 0.01, frameCount * 0.01) * TWO_PI * 2;
  return p5.Vector.fromAngle(a).mult(WIND);
}

This, even though simple code I believe adds a nice touch to the overall feel and vibe of the sketch. Rather than applying random turbulence, I used Perlin noise to generate a smooth directional field across space. The noise value is converted into an angle and then into a vector, producing gentle, continuous variations in star motion. This force adds complexity without visual chaos, allowing trajectories to subtly diverge while still being primarily governed by planetary gravity.

Future Improvements

I am incredibly proud of how the final code turned out, but if I was to change anything in the future I would probably play with the color of the path that follows the shooting stars and or maybe it’s thickness. I would also explore the possibility of adding more planet options or maybe even planet star collision system.

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.

 

Haris – Reading Response

One idea that really stood out to me was the critique of reductionism and emphasis on emergence. The author argues that while breaking a system into parts can help us understand structure, it fails to explain the behavior when many parts interact together. I really liked the example of the ant colonies as the every single ant follows just simple rules, but together the colony displays intelligence, coordination and problem solving. This really made me think how intelligence doesn’t really require complexity at an individual level, it can arise from interactions.

What also really stood out to me was the idea that we should focus less on “What is X” and more on “What will X do in the presence of Y”. This feels really connected to interactive media and computation in general as behavior emerges through systems rather than  isolated elements. The reading made me really think about if complex systems can immerge from simple rules how much creative control do we really have when designing a system? But overall I really enjoyed the reading and I can surely say it has changed how I think about complexity and the connection between systems and nature in general.

Haris – Assignment 1

Concept

While talking to my friends about randomness in nature we discussed about different organisms in nature and how they move. Specifically we discussed the Brownian motion which explores the seemingly random motion of particles in liquids. I decided that I would try to recreate this motion of particles in a colorful and a bit more hectic way so it has its own twist to it. For this I decided to use Lévy flight which in simple terms would allow the object to “walk” in shorter or longer distances at a time. I also wanted to bring some hue to the mix to make the experience more colorful and in my opinion prettier.  This makes the whole project more expressive and more engaging and brings it to another level. 

What we get in the end is an interesting yet beautiful play of particles on the screen. I also added a shadow to the ellipse, precisely behind it, that changes color depending on the distance the particle has covered. So the hue is actually affected by the random distance.

Code highlight

if (step < 0.1) {
  step = random(20, 90); // the big jump
} else {
  step = random(1, 6); // the small jump
}
let angle = random(TWO_PI);

x += cos(angle) * step;
y += sin(angle) * step;

// wrap around screen
if (x < 0) x += width;
if (x > width) x -= width;
if (y < 0) y += height;
if (y > height) y -= height;

I am proud of this code as this is the main code that controls the movement logic of the “simulation”. I think it was really fun figuring out how to translate something from the real world into code/computer and I think I did a pretty good job at keeping the code clean and short but functional.

Reflection and future improvements

Overall this project was fun to work on and I really enjoyed “translating” real life movement into a program. Also since I haven’t worked in p5js for a bit I think this was a great way to get back into the habit and restart my p5 journey. In the future I would like to possibly add a functionality to add more particles (ellipses) and have them collide with each other.

Version 2.0

Based on the feedback, I revised the movement and color logic to more clearly represent traversal through RGB space. For the movement, I replaced a fully random direction with a Perlin-noise–driven angle. This change preserves the nature of a Lévy flight while producing slower and more readable motion.

For the color, I updated the sketch so that the RGB values of the particle are directly dependent on its position, with the x-coordinate mapped to red, the y-coordinate mapped to blue, and the step size mapped to green. This makes the movement through RGB space explicit and directly tied to the particle’s motion.