Assignment 2 – Pavly Halim

The Concept

I created a dynamic grid of squares that continuously change in color and size, creating a mesmerizing animation effect. Perlin noise, sine, and cosine functions influence the grid’s behavior, which modulates the color and the size of each square in the grid based on the frame count variable. This results in a fluid, ever-changing pattern that is both visually appealing and technically intriguing.

Highlight of the Code

What stands out in the code is the use of mathematical functions to drive the animation’s dynamics. Specifically, the combination of Perlin noise, sin, and cos functions with the frameCount variable to alter the color and size of the squares over time showcases a sophisticated understanding of how to create complex visual effects with relatively simple code.

// Calculate noise-based angle and size variations using Perlin noise
let noiseFactor = noise(i * animationSpeed, j * animationSpeed, frameCount * animationSpeed);
let angle = noiseFactor * 360;

//more color and size variations using Sine Cosine 
//https://p5js.org/examples/math-sine-cosine.html
let colorShift = (sin(angle) + 1) * 128;
let sizeShift = (cos(angle) + 1) * (gridSize / 0.1);

Embedded Sketch

 

let gridSize = 20;
let animationSpeed = 0.01;

function setup() {
  createCanvas(400, 400);
  angleMode(DEGREES);
  noStroke();
}

function draw() {
  background(220);
  
  //nested for loop to go through each grid position
  for (let i = 0; i < width; i += gridSize) {
    for (let j = 0; j < height; j += gridSize) {
      push();
      
      // Calculate noise-based angle and size variations using Perlin noise
      let noiseFactor = noise(i * animationSpeed, j * animationSpeed, frameCount * animationSpeed);
      let angle = noiseFactor * 360;
      
      //more color and size variations using Sine Cosine 
      //https://p5js.org/examples/math-sine-cosine.html
      let colorShift = (sin(angle) + 1) * 128;
      let sizeShift = (cos(angle) + 1) * (gridSize / 0.1);
      
      // Apply transformations
      translate(i + gridSize / 2, j + gridSize / 0.5);
      rotate(angle);

      fill(colorShift, 100, 150, 200);
      rect(-sizeShift / 2, -sizeShift / 2, sizeShift, sizeShift);

      pop();
    }
  }
}

Reflection

The integration of Perlin noise into the animation brings a significant enhancement in terms of visual and organic dynamics. Moving away from the predictable cycles of sine and cosine functions, Perlin noise introduces a natural, fluid variability to the movement and transformation of the grid. It showcases the power of combining mathematical concepts with computer graphics to simulate natural phenomena.

Future Work

Develop an interactive landscape where users can influence the flow and form of the animation through mouse movements, clicks, or keyboard inputs, simulating natural elements like wind or water currents.

Assignment 1: Self-portrait

I embarked on a fascinating journey to bring a digital character to life using p5.js, a powerful JavaScript library. The challenge was not just to create a drawing, but to infuse it with personality and style, all through the lens of code.

Concept: A Quirky Digital Companion

My concept revolved around creating a digital character that exuded both whimsy and sophistication. Picture a figure with a charming hat, expressive eyes, and a friendly smile – a character that could be a companion on the screen, blending simplicity with a touch of elegance.

🗒️ Starting with a Blank Canvas
I began with the basics – createCanvas(600, 600) – giving myself a broad canvas for my imagination. Centering my character was crucial, so I smartly positioned it using x = width/2; y = height/2;. It felt like setting the stage for a one-of-a-kind show.

🎩 Crafting the Face and a Dapper Hat
The face had to be inviting, so I opted for a friendly, round shape using an ellipse. Then came the hat – a symbol of sophistication. Crafting it with an arc and a rect felt like adding a crown to my character.

👀 Eyes That Speak Volumes
Ah, the eyes! They were my favorite part. Getting them right was like threading a needle – a delicate balance of size and expression. With careful placement of ellipses for the whites and irises, I managed to give them a sparkle of life.

👃 A Nose with Character and a Smile to Match
The nose, created with subtle arc functions, had its own story. Not too big, not too small – just right. The mouth was a simple arc, but it carried a gentle, inviting smile, as if ready to greet the world.

👂 Ears and Neck – Bringing It All Together
The ears, though a small detail, gave the face a sense of completeness. And the neck, a sturdy rectangular foundation, made everything look harmonious.

👔 Stylish Touches with a Tie and Shoulders
Adding the tie was like putting the final piece of a puzzle. It wasn’t just about color – it was about adding character. The broad shoulders, a simple rectangle, gave the figure a sense of strength and presence.

🎨 Coloring My Creation
Choosing the colors and stroke weights was like dressing up my character for a grand ball. Every shade added a new layer of personality, turning lines and shapes into a friend I’d just made.

Proud Coding Achievement: The Eyes

The part of the code I’m particularly proud of is how I brought the eyes to life. Using the ellipse function for the whites and irises, I managed to create a gaze that was both lively and expressive. It’s these eyes that give the character its soul, making it more than just a collection of shapes.

//eyes
strokeWeight(4);
fill(255);
ellipse(3*x/4, 4*y/5, x/3.5, y/8);
ellipse(5*x/4, 4*y/5, x/3.5, y/8);

//iris
strokeWeight(3);
fill(255);
ellipse(3*x/4, 4*y/5, x/7, y/9);
ellipse(5*x/4, 4*y/5, x/7, y/9);

//pupil
fill(0);
ellipse(3*x/4, 4*y/5, x/13, y/15);
ellipse(5*x/4, 4*y/5, x/13, y/15);

Embedded Sketch: A Digital Portrait

This code, when run in a p5.js environment, brings forth a character that stands out with its unique hat and tie, set against a simple background. The colors, strokes, and shapes work in harmony to present a figure that’s both inviting and intriguing.

The code:

let x;
let y;

function setup()
{
  createCanvas(600, 600);
  x = width/2;
  y = height/2;
}
function draw() {
background(200)

//neck
fill(241, 194, 125);
stroke(205, 133, 63);
rect(x - 43, y+173, 90, 70);
  
//Face
strokeWeight(3);
fill(241, 194, 125);
ellipse(x, y, 6.5*x/5, 7*y/6);

//Hat 
fill(0); 
stroke(0);
arc(x, y - (5 * y / 12), 5 * x / 5, 200, PI, TWO_PI);
rect(x - (6.5 * x / 10), y - (5 * y / 12) - 10, 6.5 * x / 5, 20);

//eyes
strokeWeight(4);
fill(255);
ellipse(3*x/4, 4*y/5, x/3.5, y/8);
ellipse(5*x/4, 4*y/5, x/3.5, y/8);

//iris
strokeWeight(3);
fill(255);
ellipse(3*x/4, 4*y/5, x/7, y/9);
ellipse(5*x/4, 4*y/5, x/7, y/9);

//pupil
fill(0);
ellipse(3*x/4, 4*y/5, x/13, y/15);
ellipse(5*x/4, 4*y/5, x/13, y/15);


//eyebrows
strokeWeight(6);
line(3*x/4-20,4*y/5-y/10,3*x/4+20,4*y/5-y/10);
line(5*x/4-20,4*y/5-y/10,5*x/4+20,4*y/5-y/10);


//nose
noFill();
stroke(205, 133, 63);
strokeWeight(4);
arc(x+12, 5*y/6 + 10, 7, y/2.5, 0, HALF_PI);
arc(x - 23, y+30, 21, 21, HALF_PI-QUARTER_PI/3, PI+2*QUARTER_PI);
arc(x+16, y+30, 21, 21,  -HALF_PI, HALF_PI+QUARTER_PI/2);
arc(x-3, y+40, 30, 21,  0, PI);

//mouth
noFill();
stroke(0);
arc(x, y+95, 95, 21,  0, PI);
strokeWeight(7);


//ears 
strokeWeight(3);
fill(241, 194, 125);
stroke(205, 133, 63);
arc(x/3.6 + 26, y - 10, x/4, y/3.5, HALF_PI, PI+HALF_PI );
arc(x/3.6 + 26, y - 10, x/8, y/7, HALF_PI, PI+HALF_PI );
arc(x+2.9*x/4 - 26, y - 10, x/4, y/3.5, -HALF_PI, PI-HALF_PI);
arc(x+2.9*x/4 - 26, y - 10, x/8, y/7, -HALF_PI, PI-HALF_PI);

// shoulders
fill(255);
stroke(0);
rect(100, 540, 400, 80);

//tie
fill(255, 0, 0); 
triangle(x - 10, y + 240, x + 5, y + 240, x, y + 270); 
triangle(x - 15, y + 270, x + 15, y + 270, x, y + 310);

  
fill(0);
rect(x - 125, y + 240, 25, 60); 
rect(x + 100, y + 240, 25, 60);
  
}

 

Reflection and Future Directions

Reflecting on this project, I realize that while I’ve created something delightful, there’s always room for growth and innovation.

  • Animation: Bringing motion to the character, like a nodding head or blinking eyes, could add a new layer of interaction.
  • Interactivity: Allowing users to change aspects like the hat’s color or the tie’s pattern could make the character more engaging.

This project was not just about coding a character; it was about weaving a narrative through digital art. It’s a reminder that code is not just functional; it’s a canvas for creativity. As I look forward to future projects, I’m excited to explore new ways to blend storytelling with technology, creating digital experiences that resonate and delight.