Midterm Progress

 

Concept:

The design of this dynamic artpiece stems from a mixture of blackholes, and mandalas. Mandalas are intricate geometric designs that radiate out from a central point. In many cultures, they’re used for spiritual symbols, meditation aids, or just as beautiful artworks. With multiple layers composed of points connected in circular patterns, they echo the repetitive yet diverse nature of the universe. The simulation employs a rotational dynamic, making the mandalas rotate around their center. This movement, combined with the random trajectories of the particles, offers a visually entrancing experience.

 

Sketch:

Code:

  calculateLayerRadius(layerIndex) {
    return this.radius * ((layerIndex + 1) / this.numLayers);
  }

  calculateNumPoints(layerIndex) {
    return int(map(layerIndex, 0, this.numLayers - 1, 2, 12));
  }

  calculateLayerSpacing() {
    return map(sin(frameCount/10) * 0.05, -1, 1, 5, 30);
  }

  calculateLayerColor(layerIndex) {
    return map(layerIndex, 0, this.numLayers - 1, 100, 255);
  }
}
  1. calculateLayerRadius(layerIndex):
    Gives the size for each layer. Inner layers are smaller, and it grows as we move out.
  2. calculateNumPoints(layerIndex):
    Decides the number of points for each layer. Inner layers have fewer points, and outer layers have more.
  3. calculateLayerSpacing():
    Sets the space between layers. It changes over time to make the mandala look animated.
  4. calculateLayerColor(layerIndex):
    Assigns a color to each layer. Inner layers are a bit darker, and it gets lighter as we go out.

These functions help design and animate the mandala’s layers.

 

Expected Challenges:

Performance Balancing:

Merging mandalas and a particle system presented optimization challenges. Ensuring smooth animations while maintaining rich details required thoughtful code structuring.

Adding particles:

Add some sort of particle system to enhance the viewing experience.

 

Future Improvements:

Interactivity:

Incorporating possible interactive elements can elevate user engagement. Such 

Incorporate Sound:

Add a soundtrack to enhance the experience

 

 

 

 

 

 

Assignment Week #4 – DNA

Concept:

Drawing inspiration from the structure of DNA, the goal behind this project was to visually represent a DNA helix. A DNA helix is composed of two spiral strands, interlinked by rung-like structures, mimicking a twisted ladder. The project also allows interactive elements, enabling users to manipulate the visual representation of the helix. Users can control the radius and segment length of the helix by moving the mouse and can also manipulate the rotation speed using the arrow keys.

Implementation:

Helix:

  • Helix: Two helixes are drawn to represent the twisted strands of the DNA helix, each spiral strand having base pairs represented by ellipses. Lines connecting these ellipses create an aesthetic and illustrative representation of a DNA helix.

User interactivity:

  • Radius and Segment Length Control: By pressing and holding the mouse button, users can change the helix’s radius and segment length, creating varied visual effects. The X-coordinate of the mouse controls the radius, and the Y-coordinate controls the segment length.
  • Rotation Speed Control: The UP_ARROW key increases the rotation speed of the helix, while the DOWN_ARROW key decreases it, allowing users to explore the helix structure in a dynamic manner.

Sketch:

Code:

Here is a snippet of the main interactivity features implemented in the code:

for (let i = 0; i < numSegments; i++) {
    let angle1 = i * angleIncrement + angle;
    let angle2 = angle1 + PI; 
    let x1 = helixRadius * sin(angle1);
    let y1 = i * segmentLength;
    let x2 = helixRadius * sin(angle2);
    let y2 = (i + 1) * segmentLength;
    
    ellipse(x1, y1, 10, 10);
    ellipse(x2, y2, 10, 10);
    line(x1, y1, x2, y2);
}
  • It calculates two angles, angle1 and angle2, for each segment, ensuring a 180-degree phase shift between them to depict opposite points in the helix.
  • For each angle, it computes the x and y coordinates (x1, y1, x2, y2) to position the base pairs and draw the segment of the helix.
  • It uses these coordinates to draw two ellipses representing base pairs and a line between them, simulating the structure of DNA.

Challenges:

  • Interactivity Integration: Seamlessly incorporating user controls while maintaining the visual integrity of the helix structure presented a challenge. The controls needed to be intuitive and responsive, allowing users to explore the structure dynamically.
  • Visual Representation: Achieving a visually appealing and accurate representation of a DNA helix, considering the spiral strands and interconnecting lines, required meticulous calculations and adjustments.

Future Improvements:

  • Additional More User Controls: Implement more user controls, like sliders or input fields, enabling users to modify parameters such as color schemes, the density of base pairs, or introducing distortions to the helix structure.
  • Visual Aesthetics Enhancements: Infuse more aesthetic elements like dynamic colors, shadows, and reflections, elevating the visual appeal and depth of the representation.

Assignment Week #3 – MAGNETS

Concept:

My idea was to simulate a magnetic field by making attractors and movers. Attractors pull objects towards them and repel if they are too close and they also attract other attractors, while movers navigate this field of forces. The movers when in motion look like a visual representation of what a magnetic field would look like

Implementation:

  1. Attractors: These are objects that exert attractive forces on nearby movers. They are represented as red points on the canvas and move randomly. Attractors demonstrate the concept of attraction within the simulation.
  2. Movers: These are objects that are affected by the forces exerted by attractors and other movers. Each mover experiences both attraction and repulsion forces. These forces influence the motion and behavior of the movers.
  3. Turbulence: To add an extra layer of complexity and randomness, turbulence forces are applied to the movers. This turbulence causes the movers to exhibit unpredictable behavior.

Sketch:

https://editor.p5js.org/mi1171/full/TP9sdc9VE

Code:

function applyRepulsionFromAttractors(mover) {
  for (let attractor of attractors) {
    let force = attractor.copy().sub(mover.pos);
    let distance = force.mag();
    
    if (distance < repelDistance) {
      let strength = -repelStrength / (distance * distance);
      force.setMag(strength);
      mover.applyForce(force);
    } else if (distance < attractionDistance) {
      let strength = 5000 / (distance * distance);
      force.setMag(strength);
      mover.applyForce(force);
    }
  }
}

function applyRepulsionFromMouse(mover) {
  if (attractToMouse && mouseIsPressed) {
    let mouseForce = createVector(mouseX, mouseY).sub(mover.pos);
    let mouseDistance = mouseForce.mag();
    
    if (mouseDistance < repelDistance) {
      let mouseStrength = -repelStrength / (mouseDistance * mouseDistance);
      mouseForce.setMag(mouseStrength);
      mover.applyForce(mouseForce);
    }
  }
}

function applyRepulsionBetweenMovers(mover) {
  for (let j = 0; j < movers.length; j++) {
    if (mover !== movers[j]) {
      let otherMover = movers[j];
      let force = otherMover.pos.copy().sub(mover.pos);
      let distance = force.mag();
      
      if (distance < moverRepelDistance) {
        let strength = -moverRepelStrength / (distance * distance);
        force.setMag(strength);
        mover.applyForce(force);
      }
    }
  }
}

function applyAttractionToMouse(mover) {
  if (attractToMouse && mouseIsPressed) {
    let mouseAttraction = createVector(mouseX, mouseY).sub(mover.pos);
    let mouseAttractionDistance = mouseAttraction.mag();
    let mouseAttractionStrength = 500 / (mouseAttractionDistance * mouseAttractionDistance);
    mouseAttraction.setMag(mouseAttractionStrength);
    mover.applyForce(mouseAttraction);
  }
}

function applyTurbulence(mover) {
  let turbulence = createVector(random(-1, 1), random(-1, 1));
  turbulence.mult(0.1);
  mover.applyForce(turbulence);
}

function applyAttractionBetweenAttractors() {
  for (let i = 0; i < attractors.length; i++) {
    for (let j = i + 1; j < attractors.length; j++) {
      let force = attractors[j].copy().sub(attractors[i]);
      let distance = force.mag();
      if (distance < attractionDistance) {
        let strength = attractionStrength / (distance * distance);
        force.setMag(strength);
        attractors[i].add(force);
        attractors[j].sub(force);
      }
    }
  }
}

These are the functions behind the forces that are in play in the simulation:

  • applyRepulsionFromAttractors(mover): Computes forces that repel a “mover” from nearby “attractors.”
  • applyRepulsionFromMouse(mover): Calculates repulsion forces on a “mover” from the mouse cursor when a certain condition is met, simulating user interaction.
  • applyRepulsionBetweenMovers(mover): Computes repulsion forces between different “mover” objects, preventing them from getting too close.
  • applyAttractionToMouse(mover): Applies an attraction force from the mouse cursor to a “mover” when another condition is satisfied, allowing users to pull objects toward the cursor.
  • applyTurbulence(mover): Adds random turbulence forces to create unpredictable, jittery motion in the “mover” objects.
  • applyAttractionBetweenAttractors(): Calculates attraction forces between pairs of “attractor” objects, simulating magnetic attraction.

Challenges:

– Force Calculation: Calculating and applying the correct forces to achieve realistic attraction and repulsion between objects.

Future Improvements:

Some potential future improvements include:

– Additional Forces: Experiment with different types of forces, such as gravitational forces or custom-defined force fields, to create diverse and intriguing simulations.

– User Controls: Implement sliders or input fields to allow users to adjust parameters like attraction and repulsion strengths, turbulence intensity, or the number of objects in the simulation.

– Visual Effects: Incorporate visual effects like trails, color variations, or particle-like representations to add depth and visual appeal to the simulation.

Assignment Week #2 – FROG

Concept:

This assignment revolves around an interactive frog and fly simulation. In this sketch, the player can click on the canvas to spawn a fly which the frog will eat extending its tongue to catch it. The primary objective is to create an experience that simulates the movements of a fly and a frog.

Sketch:

https://editor.p5js.org/mi1171/full/aMpw5OAKN

Code:

function draw() {
  background(220);

  food.show();
  food.update();
  // Update and display the tongue
  if (choice == 1) {
    if (food && !food.isEaten) {
      food.show(); // Display the food
      if (
        tongueLength <
        dist(
          player.position.x,
          player.position.y,
          food.position.x,
          food.position.y
        )
      ) {
        player.extendTongue(); // Call the extendTongue method of the Player class
      } else if (
        tongueLength > 0 &&
        tongueLength >=
          dist(
            player.position.x,
            player.position.y,
            food.position.x,
            food.position.y
          )
      ) {
        food.isCaught = true;
        player.retractTongue(); // Call the retractTongue method of the Player class
      }

      // Check for collision between player and food
      if (
        dist(
          player.position.x,
          player.position.y,
          food.position.x,
          food.position.y
        ) <
        player.radius + food.radius
      ) {
        food.isEaten = true; // Food is eaten
        food.isCaught = false;

        tongueLength = 0; // Retract the tongue when food is eaten
        choice = 0;
      }
    }
  }
  player.update();
  player.show();

  if (millis() > nextJumpTime) {
    bool = random(0, 10);
    if (bool > 2) {
      player.randomJump();
    } else {
      choice = 1;
    }
    setNextJumpTime();
  }
}

 

This block of code is the main logic behind the frog’s behavior. It continuously updates and displays the positions of the frog and the food item on the canvas. The game logic includes extending the frog’s tongue towards the food, retracting the tongue when the food is caught, and marking the food as eaten. In addition, the random jumping and tongue extensions, are controlled based on random chance combined with time intervals.  The frog has a 20 percent chance of extending its tongue and an 80 percent chance of randomly jumping.

Challenges:

During the development of this frog game, several intriguing challenges were encountered:

Collision Detection: Implementing accurate collision detection algorithms to determine when the frog’s tongue makes contact with food.

Random frog/fly Movements: To create a somewhat realistic experience, the frogs’s random jumping behavior had to be balanced carefully along with the fly’s erratic movements. Random vectors were employed to determine both vertical and horizontal velocities.

Future Improvements:

Looking ahead, there are several exciting possibilities for enhancing and expanding upon this interactive frog game:

Additional animals: Incorporate multiple animals to simulate a full ecosystem.

Audio Enhancements: Elevate the gaming experience by adding sound effects for jumping, food catches, and background music.

Assignment Week #1 – RADAR

Concept: 

My concept this week is “RADAR”. It is an art piece in which there are multiple walkers located randomly on the canvas and walk towards the cursor and then after a few seconds they scatter back to their initial positions. There are horizontal and vertical lines which gives the image the feel of a radar.

Sketch: 

https://editor.p5js.org/mi1171/full/wgCqaP_wT

step(){
    let stepvar = (random(1));

    if(stepvar < 0.6){
      if(bool == true){
      if(mouseX>=this.x){
      this.x++} if(mouseX<this.x){
        this.x--
      }
        if(mouseY>=this.y){
      this.y++}
        if(mouseY<this.y){
        this.y--
      }
    }else{
      if(this.initialx>=this.x){
      this.x++}
      if(this.initialx<this.x){
        this.x--
      }
        if(this.initialy>=this.y){
      this.y++}
        if(this.initialy<this.y){
        this.y--
      }
    }
    } else if(stepvar < 0.7){
      this.y++
    } else if(stepvar < 0.8){
      this.x--
    } else {
      this.y--
    }
    this.x = constrain(this.x,0,width-1);
    this.y = constrain(this.y,0,height-1);
    
    if(this.r<= r2){
      this.r++
    }else{
      this.r--
    }
    
     if(this.g<= g2){
      this.g++
    }else{
      this.g--
    }
    
     if(this.b<= b2){
      this.b++
    }else{
      this.b--
    }
}

This is my step function, the part I’m particularly proud of is how I manage to make the walkers go back to their initial positions after the bool variable becomes true. (This variable flips every 400 frames)

Challenges:

In this week’s assignment, I had 1 main issue, which was the lag caused by the code. I decided to decrease the number of walkers I had from 200 to 100, which greatly decreased the amount of lag in the sketch while still maintaining the integrity of the art piece.

Future Improvements: 

There are some improvements that can be made to this assignment. For example, I can add a line that rotates and ‘detects’ the circles. When detected the circles can increase in opacity, then slowly decrease until the line touches them again. 

Reading Response – Week #1

Reductionism is a method of breaking down complex concepts into simpler, more understandable bits. It is a highly effective technique of learning how certain individual components work, but it does not always convey the complete picture. A concept must also be viewed in relation to its interaction with other concepts or with its external environment. Those relationships that an organism has with its environment can only be explored at a higher level of examination. Each element of a system can interact with one another, resulting in emergent unique traits that cannot be explained just by reductionism. Holism is a way of perceiving the world that does not focus on the individual but on the system that is made up of individuals. Using this strategy can lead to an increased understanding of how the world works since, in many circumstances, the system becomes bigger than the sum of its parts. Only via a comprehensive understanding can we find and connect these seemingly diverse domains. To achieve a more thorough understanding of the world, I feel that both reductionism and holism are necessary. These 2 methods synergize with one another, when we learn about how an individual component of a system works, then we can also gain a deeper understanding of how the whole system operates and vise versa.

Using a holistic perspective, we discovered that ideas from one field, like animal flocking, had similarities in another, like financial markets. When we view the world from a more holistic perspective, we find surprising overlaps and patterns that cut across traditional academic disciplines. Principles from one field might inspire solutions in another, so it’s helpful to think across disciplines to generate new ideas. Also, holism exposes the universality of some patterns, such as self-organization and adaptation, across other systems. With this understanding, we may foster the growth of new interdisciplinary areas and promote innovation. When confronting problems with many interconnected components, such as climate change or healthcare, which necessitate an multidimensional approach for both technical and societal dimensions, a holistic perspective is crucial.