School of fish – Week 8

https://editor.p5js.org/oae233/sketches/0fc6TGzO4

Concept / Idea

For this assignment, I had already done bird flocking for a previous assignment so I wanted to do something slightly different this time, but still try to capture the essence of watching some of the flocking behaviours in real life. I wanted to recreate the vibe of an underwater camera capturing the motion of fish flocking behavior, and how they reflect light as they move through water.

Implementation:

I wanted the fish to be 3d so I used a for loop that draws boxes consecutively with varying sizes using a sin wave, then used another sin wave to move these boxes from left to right, and another one with a longer wavelength for up and down movement, this gives me the movement of the fish swimming.

For the effect of depth in the water (fish further away from the camera are more blue and faded while closer fish are whiter and clearer) I drew planes at 5 percent opacity each and placed them spread out along the Z-axis. I’ve found that this successfully mimics the effect I was looking for.

Some code I want to highlight:

    

for (let i = -10; i < 10; i++){

      let x = map(i,-10,10,0,PI);

      let y = map(i,-10,10,0,TWO_PI);

      this.z += 0.01;

      this.changeInDir = p5.Vector.sub(this.initDir,this.vel);

      this.changeInDir.normalize();

      push();

      this.changeInDir.mult(45);

      

      angleMode(DEGREES);

      rotateX(this.changeInDir.y);

      rotateY(-this.changeInDir.x*2);

      rotateZ(this.changeInDir.z);

      angleMode(RADIANS);

      translate(2*cos(y+this.z*3),5*cos(x+this.z/5),i*3);

       strokeWeight(0.2);

      fill(130);

        specularMaterial(250);

      box(10*sin(x),20*sin(x),3);

      pop();

    }

This code block is from the render() function of the boids/fish. You can see that I’m using the change in direction to rotate the fish’s body to face the direction it’s swimming in. It was challenging for me to figure this out exactly, especially in 3 dimensions. This setup I’ve found works best through some trial and error. It is not perfect though.

Future work:

I’d love to fix the issues with the fish rotating abruptly at some point. I’d also love to add more complex geometry to the fish body, add some variations between them, and increase the number of fish.

Final Project Draft #2

Concept development

I believe I was able to achieve my initial concept and allow the user to control the CA simulation by body movements.

I have developed 2 versions of my concept, one with video displayed and the other without. I hope to pick the final version after the user testing stage. Here are the 2 versions (open in full screen, camera access required):

Here are some of my thoughts on the different versions.

Advantages of Displaying Video:

  1. Enhanced Engagement: Seeing live video might enhance user engagement, especially since the interaction involves real-time reactions to movements.
  2. Visual Feedback: Video provides visual feedback that helps users understand how their actions are affecting the system, creating a more clear experience.
  3. Creative Expression: Video display adds to the creative expression, allowing users to be part of the visual outcome.

Advantages of Not Displaying Video:

  1. Focus on Visualization: Without the distraction of the live video, users may focus more on the visual elements generated by the application, such as patterns, colors, and the CA element.
  2. Aesthetic Choice: Absence of video results in a cleaner, more stylized look. It is more aesthetically appealing.
  3. Reduced Cognitive Load: The absence of a live video stream may reduce cognitive load, allowing users to concentrate on specific interactions without additional visual input, thus enhancing focus on the visual outcome.

To make a better decision about which version to proceed with, I am planning to track the engagement time as well as record the different opinions and reasoning of the participants in the user testing.

Next steps:

I want to advance my project by adding an event, either a change in colors or in the rules of CA when a certain pose is detected. I believe that such an addition would enhance the interactivity aspect, as it would provide additional feedback to the user’s movements.

week 11 assignment

Inspiration

For this weeks assignment, I want to replicate shooting stars because with cellular automata, we can see them be born/ die and spread. Also the sporadic movement of the cells replicates the stars glowing. I want to use the following basic program to show it simplified with just black and white.

I wanted to adapt from this and add a 3rd state as a dying state and to adapt the colours. After making these adjustments, I got an effect that is much more natural and here are the following adjustments. ‘

show() {
    // stroke(0);
    if (this.previous === 0 && this.state == 1) {
      stroke(255,255,0);  //yellow
      fill(255, 255, 0);
    } else if (this.state == 1) {
      stroke(255);    //black
      fill(255);
    } else if (this.previous == 1 && this.state === 0) {
      stroke(218,165,32)    //gold
      fill(218,165,32);
    } else {
      stroke(0);      //white
      fill(0);
    }
    square(this.x, this.y, this.w);
  }

I really wanted to add another level of user interactivity and have the mouse be able to add more life into the program and this is the following code I used. Where the mouse goes, more cells are added and that state is changed, when close to other live cells, the cell catches ‘fire’ and have it expand. The shooting stars effect started and would carry on once the cells die.

function mouseDragged() {
  // Update cell state when the mouse is dragged
  for (let i = 0; i < columns; i++) {
    for (let j = 0; j < rows; j++) {
      // Check if  mouse is within the  boundaries
      if (
        mouseX > board[i][j].x &&
        mouseX < board[i][j].x + w &&
        mouseY > board[i][j].y &&
        mouseY < board[i][j].y + w
      ) {
        // Update the cell state to 1 (alive)
        board[i][j].state = 1;
        board[i][j].previous = board[i][j].state;
      }
    }
  }
}

And this is my following code and my final product.