Assignment 3

Concept

For this project, the goal was to apply the concepts learned in class, including loops, arrays, and Object-Oriented Programming (OOP), to create an interactive visual experience.  The initial goal was to create a dynamic piece where a single spiral would be generated with each mouse click. However, I wanted to enhance user engagement by adding a feature that allows spirals to change color when clicked inside. So, I decided to use mouseDragged function to generate spirals and mouseClicked for spirals to change colour. Therefore, the application now produces multiple spirals during a single drag action across the screen. Furthermore, if a spiral is clicked, it temporarily changes color before reverting to its original hue.

To make the application more visually appealing, I attempted to introduce a feature where waves are generated whenever two spirals collide. I added a trailing effect to these waves, aiming to create a mesmerizing interaction between the spirals and the waves produced. Additionally, I implemented a functionality to clear the screen by pressing the ‘c’ key, allowing users to reset the canvas and start anew.

Sample

Embedded Canvas

Drag your mouse and see the magic.

Code

let spirals = [];

function setup() {
  createCanvas(800, 800);
  background(0);
}

function draw() {
  background(0, 25); // Semi-transparent background for a trail effect
  for (let i = 0; i < spirals.length; i++) {
    spirals[i].update();
    spirals[i].display();
    // Check for collision with other spirals
    for (let j = i + 1; j < spirals.length; j++) {
      if (spirals[i].collidesWith(spirals[j])) {
        createWaveBetween(spirals[i], spirals[j]);
      }
    }
  }
}

function mouseDragged() {
  let newSpiral = new Spiral(mouseX, mouseY);
  spirals.push(newSpiral);
}

// Function to chnage colour of the spiral after mouse ci clicked inside the spiral
function mouseClicked() {
  for (let i = 0; i < spirals.length; i++) {
    if (dist(mouseX, mouseY, spirals[i].pos.x, spirals[i].pos.y) < spirals[i].radius) {
      spirals[i].transform();
     
    }
  }
}

class Spiral {
  constructor(x, y) {
    this.pos = createVector(x, y);
    this.radius = random(5, 20);
    this.angle = 60;
    this.color = color(random(255), random(255), random(255), 100);
    this.transformed = false;
  }
  
  update() {
    this.angle += 0.05;
    this.radius += 0.5;
  }
  
  display() {
// Itsaves the current drawing style settings and transformations applied to the canvas
    push();
//   moves the origin to the position of the spiral
    translate(this.pos.x, this.pos.y);
    stroke(this.color);
    noFill();
    beginShape();
    for (let i = 0; i < this.angle; i += 0.1) {
//  Calculate the x and y coordinates of each vertex of the spiral
      let x = this.radius * cos(i);
      let y = this.radius * sin(i);
//  This function adds a vertex to the shape of the spiral
      vertex(x, y);
    }
    endShape();
    pop();
  }

  transform() {
    this.transformed = true;
    this.color = color(random(255), random(255), random(255), 100);
  }

  collidesWith(other) {
    let d = dist(this.pos.x, this.pos.y, other.pos.x, other.pos.y);
    return d < this.radius + other.radius;
  }
}

function createWaveBetween(spiral1, spiral2) {
// Calculates the start and end points of the line connecting the centers of the two spirals
  let startX = spiral1.pos.x + spiral1.radius * cos(spiral1.angle);
  let startY = spiral1.pos.y + spiral1.radius * sin(spiral1.angle);
  let endX = spiral2.pos.x + spiral2.radius * cos(spiral2.angle);
  let endY = spiral2.pos.y + spiral2.radius * sin(spiral2.angle);
  
  let wave = new HorizontalWave(startX, startY, endX, endY);
  wave.display();
}

class HorizontalWave {
  constructor(x1, y1, x2, y2) {
    this.start = createVector(x1, y1);
    this.end = createVector(x2, y2);
    this.amplitude = 20;
    this.frequency = 0.1;
    this.color = color(255);
  }
  
  display() {
    push();
    stroke(this.color);
    noFill();
    beginShape();
    for (let x = this.start.x; x < this.end.x; x += 5) {
      let y = this.start.y + this.amplitude * sin(this.frequency * x);
      vertex(x, y);
    }
    endShape();
// This function restores the drawing state that was saved with the most recent 
    pop();
  }
}

Challenges & Reflections:

One of the significant challenges I encountered was the implementation of the wave generation when two spirals collide. The vision was to have the spirals transform into waves upon collision, with the spirals disappearing and the waves remaining on screen. However, I faced difficulties in realizing this feature due to my current level of understanding and technical limitations. This project has not only been a fun exploration of interactive graphics but also a valuable learning opportunity. I look forward to revisiting this project in the future, armed with more knowledge and experience, to incorporate the envisioned features and further enhance its interactivity and visual appeal.

References:

E. J. C. (2021, February 17). Excel – Adding and Graphing Sine Waves with Any Amplitude or Phase. YouTube. https://www.youtube.com/watch?v=2SdAtjoYEXo

Leave a Reply