Haris – Midterm

The Digital Milky Way

Concept

When thinking about the midterm project I was trying to come up with a design that would be both enjoyable to build and beautiful for the viewers to experience. Something that has always fascinated me with both intrigue and beauty is the space, endless galaxies, start, planets… So my goal was to recrate some of that in p5 and try to make an artwork out of it.

I had also worked on space design for my previous assignments and found that those were the assignments I enjoyed working on the most and the ones that in my opinion turned out the most beautiful so the decision was obvious and quickly made.

Like many other projects of mine I didn’t want the user to be just a viewer. I wanted everyone to be able to experience the artwork by interacting with it. So besides adding the 3 modes that can be accessed with pressing numbers 1,2 and 3 on the keyboard I also implemented a click function which pushed away the particles creating interactive art.

The three modes

The project is divided into 3 different states all showing another beautiful part of space.

1. Planet with a ring

The first mode is inspired by Saturn which is known for its beautiful ring that circles it. It is also inspired by  my previous work where all my planets had rings. I think this brings depth to the planets and makes them more than just colored circles on the screen. For the ring I decided to integrate a particle system that we have been using in class which did make the project look way better, but also did give my laptop some troubles which I will talk more about later.

2. Black hole

The second mode of the project takes us into the fascinating world of black holes. To be more precise, the second mode gives the user the ability of the black hole at their fingertips, or should I say, mouse pointer. The particles are now start being dragged into the black hole as the planet disappears outside of the users view.

2.1 Black hole “sub-mode” (It’s not a bug its a feature!) 

When testing and implementing all the different modes I discovered something very interesting. If, during the 2nd mode, the user puts their mouse in the middle and lets the particles come together and then quickly removes the mouse it makes the particles explode in different directions creating a beautiful scene. I decided to leave the bug and use it as a feature in the design.

3. Galaxy

The third and final mode is the galaxy mode. Inspired by our galaxy, The Milky Way, it is supposed to represent the beautiful formation of galaxies in and outside of our observable universe. Particles are the main theme of this mode as they create a loop like shape that simulates galaxies. But since I felt that this mode could have some extra interactivity I implemented the click mechanic that pushes particles away.

I believe all the modes turned out how I wanted them to be and one of my favorite things to do is switch between modes and watch how the particles react to the different states they are given and I hope the users will enjoy them too.

Milestones

The road from the blank canvas to the finished product was a fun one but it did bring some challenges along the way. In the following passage I will try to explain some of the systems implemented in the project and how they work as well as walk you through some challenges I faced and what I did to overcome them.

From the start of the project I knew I was going to work with the particle system and guided by previous experience from class where my laptop kind of struggled to run the basic particle system I knew I was in for a ride. But to make my life easier, before implementing the particle system using textures and WEBGL I decided to create them with simple dots that my laptop would be able to run and which I could later replace for particles.

This turned out to be a great idea as it helped me develop the logic without making my laptop work too hard so I could focus on the logic more than worrying about performance.

Orbit mode

The orbit mode was used as a base for the whole project. Essentially, I wanted to simulate a static planetary system where all objects moved in a predetermined circular pattern. Instead of coding circular motion, I wanted to implement a combination of forces to simulate such a system.

Each particle is assigned a target radius, which determines the ring it belongs to. These radii are grouped into bands to create multiple layers of rings:

let targetR =
  band < 0.60 ? random(115, 170) :
  band < 0.90 ? random(185, 245) :
                random(265, 335);

There are also multiple forces that act on the particles to create the orbit effect.

Gravity like attraction:

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

Tangential force:

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

Spring force:

let err = d - p.targetR;
let spring = toCenter.copy().mult(err * 0.008);

Together all of these help create the ring like structure we see on the screen.

Galaxy mode

One of the most important design decisions was to re-seed particle positions when switching to galaxy mode:

initGalaxy();

Instead of placing particles in discrete rings, they are distributed in a dense radial disk, with higher concentration near the center:

let diskR = 18 + (-log(1 - u)) * 60;

Also a characteristic of galaxies is the fact that particles closer to the center rotate faster than those further away. I implemented this using:

let orbit = 1.0 / sqrt(r * 0.85)

Thankfully I didn’t have any major challenges other than my laptops performance and the rest of the project went smoothly. I had to increase the pixel density when I was saving the photos but since my laptop struggles so much to run it I returned it to 1 so I could actually watch my project.

Video documentation

Video showcasing the interaction withing the project:

Final sketch

Reflection and Future Improvements

Working on this project was very fun and scary at the same time. It was fun to get to implement things that we have worked on in previous classes and to bring everything together into one project, but it was scary to think about everything that could go wrong on such big project and to have to worry about laptop performance holding me back.  But overall I am very happy with how the project turned out and am excited for others to experience it also.

As for the future improvements I would definitely love to play with colors and add more planets and different galaxies to the project. I would also maybe explore implementation of sound in some way but am not sure what kind at this moment.

Haris – Assignment 7

Inspiration

The inspiration for this project comes from Team Lab’s Graffiti Nature and Beating Earth from Team Lab Phenomena Abu Dhabi. I was inspired by the fact that the installation uses digital ecosystems to create something that feels alive, immersive, and responsive to human presence. The creatures within the installation are soft, glowing, and constantly moving, while the environment does not necessarily feel like an animation, but rather something that feels alive and responds to the things that are happening within it.

This does not simply show moving creatures and plants within an environment; rather, it feels like an entire ecosystem that incorporates life, growth, and death. This became the basis of my project and the reason I choose this visual.

My twist

My initial twist was to introduce the idea of healing versus pollution. While the original project centers on a living, breathing ecosystem, I wanted to take it a step further to highlight the effect of human intervention on such an ecosystem.

In my sketch, I wanted to provide the user with some power. Glowing flower-like seeds, spawn around the canvas and serve as an energy source for the fish. The user also has the power to spawn flowers on click which gives the user a constant choice between helping and damaging the environment. This would enable the fish to thrive and reproduce. On the other hand, I wanted to provide the user with another power: to introduce pollution blobs to the environment. The fish would start avoiding the place of pollution simulating real life where our pollution and wrongdoing force away the creatures, or in this example fish, from their natural habitat. This twist provided more depth to the project. Instead of simply recreating an animated ecosystem, I was able to transform it into a system where the user was responsible for creating a world.

Process

At first I started with the simplest step, the background. I noticed that in the Team Lab space the background had subtle lines that would give the space more depth and maybe try to simulate being under water.

This was done just by using simple lines and playing withe the color and placement. Once I was happy with the background it was time to go onto more exciting stuff and that was adding the fish. At first I was a bit scared of tackling this task as I was afraid simple design would make the project look too bland so I decided to add some glow effect and transparency as well as adding a subtle trail behind the fish to make the project look like a real time piece of art.

After the fish were done it was time for the final steps of adding the seeds spawning and the ability for the user to spawn pollution.

Code I am proud of

One part of the code I am particularly proud of is the logic that allows the fish to detect and move toward the nearest seed. I like this section because it makes the creatures feel more alive and intentional. Instead of moving randomly across the screen, the fish respond to the environment by seeking out glowing seeds, which helps create the feeling of a living digital ecosystem.

// attracted to healthy seeds
let closestSeed = null;
let closestSeedDist = Infinity;

for (let s of seeds) {
  if (!s.healing) continue;
  let d = dist(this.pos.x, this.pos.y, s.pos.x, s.pos.y);
  if (d < closestSeedDist) {
    closestSeedDist = d;
    closestSeed = s;
  }
}

if (closestSeed && closestSeedDist < 180) {
  let desired = p5.Vector.sub(closestSeed.pos, this.pos);
  desired.setMag(0.12);
  this.applyForce(desired);
}

This simple implementation makes the world feel so much more alive and brings my recreation much closer to the original Team Lab project.

Future improvements

I am already really happy with the final result, but if I was to add anything new it would probably be the explosion mechanism that the Team Lab uses. This would be a fun implementation and I could probably use the particle system that we learned in class how to use, but because of the timeframe I decided not to include that in the current state of the project. Overall I am happy with the final result and have learned that recreating someone else’s work with a twist is actually an amazing way to learn and practice p5.

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.