Week 2 – Reading Response

I think humans are really fascinating because we’re full of contradictions. We long for order; familiar, predictable, structured patterns in our lives. But at the same time, we crave chaos; the unfamiliar, the unexpected, the little bit of disruption that shakes us out of routine. A very obvious example is how much we rely on having a daily routine. Most of us feel disoriented without some kind of order: a set time to wake up, a rhythm to our workday, the same coffee order every morning. Especially now, when distractions are just a notification away, that structure is often the only thing that keeps us grounded. But then, almost paradoxically, there comes a point where too much order starts to feel suffocating, and we search for a dose of chaos. That’s why vacations, spontaneous trips, or even small detours from our daily habits feel so refreshing. What’s interesting is that this balance between order and chaos looks different depending on where you are in life. For instance, I’ve talked to people a few years out of college who told me that the desire to explore the unknown is strongest at my age. Later, they said, you find more comfort in the predictability of routine.

This makes me think about how randomness in art isn’t just a visual effect, but also a negotiation between control and surrender. From the artist’s perspective, it’s about deciding how much control to let go of : how far to allow chance to shape the outcome? As humans, we instinctively want to manage and predict everything, but there’s something powerful, even humbling, about letting unpredictability take over and seeing what emerges. From the viewer’s perspective, though, the experience is different: our brains are wired to search for patterns, even in what looks chaotic. That tension, between the artist releasing control and the viewer trying to find some meaning in the randomness, creates a space of curiosity and engagement.

Another thing I couldn’t help but think about was that the randomness in computer art isn’t truly random at all. It’s pseudo-random, generated by algorithms. Yet even though it’s artificial, it still produces the illusion of chaos. I find it interesting that machine-made randomness can still tap into the same feelings we get from natural chaos. To me, the perfect balance is when order provides familiarity but randomness introduces curiosity, surprise, and the possibility of discovery. That’s what makes a piece feel alive.

Week 2 – Shahram – The Interruption

One part of the video that really caught my attention was the phrase “natural unreasonable order.” It made me think that the more humans chase perfection and efficiency, the more our way of living starts becoming unsustainable. We often wonder how people managed without all the technology and advancements we have today, but the truth is life on earth has always sustained itself regardless of technology.

In my piece, I wanted to capture the balance by mixing randomness and structure. The randomness in how the grid gets colored helps keep the viewer’s attention, while my choice of squares over circles represents order versus chaos. Squares feel more rigid and structured, while circles feel looser and more chaotic. It takes a few seconds for the grid to gradually fill with color, almost like watching the slow formation of nature itself.

But here’s the twist: as long as you let the process run undisturbed, the artwork stays vibrant. The moment you interfere by clicking, the cells start turning white. If you keep interfering, the whole grid could eventually end up blank – an analogy to what happens when humanity disrupts nature’s delicate, chaotic order: color fades, and life disappears. I was debating whether or not to have a reset option, but ended up not having it, because life never gives us the chance to go back and fix our mistakes anyways. 

There’s also another layer to this idea. We usually celebrate curiosity, but there’s a point where too much curiosity can lead to destruction. Curiosity kills the cat, right?

Here’s the Interruption:

 

I like this code because it’s kind of the main part but it uses nested for loops to create a grid, where each cell has a random chance of being filled with a random color, unless it has been disabled by a click :

function draw() {
  for (let c = 0; c < cols; c++) {
    for (let r = 0; r < rows; r++) {
      if (!disabled[c][r] && random() > p) {
        fill(random(palette));
        rect(c * cell, r * cell, cell, cell);
      }
    }
  }
}

For improvements and future work, I would like to add a slow fade effect so that when a cell is clicked, instead of instantly going white, it gradually fades away, almost like nature decaying over time. It might also be interesting to add sound to the clicks, so that human interference is not only seen visually (through the white cells) but also felt in other ways.



The More I Smile, The Less I See – A Self Portrait

For my project, I decided to present myself from the perspectives of my closest friends. As in, I gathered all the descriptive words and little jokes they’re made about my appearance. Ever since I changed my hair and got bangs, I’ve been called “Dora The Explorer”, hence my avatar is inspired the character from the childhood show. Moreover, I can’t hide my expression, so if I’m feeling something, my whole face contorts to a completely different person, almost. I was told I “look a different race” when I laugh the hardest, with my eyes closed shut and teeth bared out, hence the title.

let currentView; 
//defining a variable, which is going to decide what is going to be displayed 

function setup() {
  createCanvas(570, 400); //making a landscape scene
  currentView = noLaugh(); //the initial view is set to my resting face, variable is defined to a value 

} 
                  
function mousePressed() //when the mouse is clicked 
{ 
  if (mouseX > 212 && mouseX < 350 && mouseY > 285 && mouseY < 400) //setting limits to where you can click to make the view change 
  { 
    currentView = meLaugh(); //initial view changes because the variable is defined to another value 
  }
} 
function mouseReleased() //when the mouse is released 
{ 
  currentView = noLaugh(); //view changes to initial setting 
}

In my work, the snippet that I found the hardest to figure out and code is the angle and rotation of “waves”, nose and basically all the features of my face. But a piece of code that I’m incredibly proud of is making my sketch somewhat dynamic. After watching some youtube videos, I had it down. Since I’m ticklish, I added that element into my avatar, where if you click the mouse in certain parts of my body, the display changes to me laughing, from the usual death stare.

Although creating this project was fairly simple, I’d like to work more on limiting the “mousePressed” coordinate to specific areas, using a nested function if possible, rather than just putting coordinates of a regular rectangle. I would also like to work more on making smoother shapes with shading, instead of blocks of shapes on top of the other.

Week 1 – Settling a Tree

My idea was to create a portrait that represents growth, experience, and the things that shape us. Instead of a face, I wanted to make my self-portrait a fluid, continuous scene, through which we see the diorama of a life being lived.

  • The Tree: Me. It starts as nothing and grows over time, with its branches reaching out in unique, unpredictable directions. Its placement on the field is random, symbolizing the random circumstances we’re all born into.
  • Yellow Lights: These are the fleeting, positive moments. They could be ideas, bursts of inspiration, happy memories, or moments of creativity. They fall gently, glow for a while, and then fade away, leaving a subtle impression but more deeply, imprints on the tree leaves that catch them.
  • Grey Stones: These represent the heavier, more permanent things in life. They could be foundational beliefs, significant life lessons, or more often than not, burdens and responsibilities. They fall with more weight, and once they hit the ground, they settle and become part of the landscape permanently. A sufficient number of stones would pave a road through the screen, from left to right.

The entire process is automated. I press play, and the code “paints” the portrait for a set amount of time before freezing, leaving a final, static image that is unique every time it’s run.

The choice of background was a key point of hesitation during the creative process. I first tried a pure black canvas, but the branches and their few leaves seemed too sparse and lonely. My next step was a semi-transparent black background, which created lovely trails but didn’t feel quite right visually. I finally settled on a semi-transparent dark grey, as it softened the high contrast while preserving the beautiful “ghosting” effect.

Below is the first version of the background.

One of my favorite tiny discoveries during this project was a simple interactive feature that lets you control the flow of time: By simply holding down the mouse button, the entire animation slows to a crawl, creating a quiet but reflective moment on the scene as it unfolds. It doesn’t alter the final portrait, but it changes how you experience its creation.

// Mouse press animation, simple but I found quite effective
if (mouseIsPressed === true) {
  frameRate(10); // Slow down the animation
} else {
  frameRate(60); // Resume normal speed
}

Self portrait – Khatira

Assignment 1 – Self Portrait

For this weeks assignment, I wanted to create a simple image of myself but have the mood / expression and weather change depending on the user’s interactivity. As a hijabi, I like to change the colour of my hijab and so I wanted it be changeable by the user pressing the mouse. I also enjoy the city life so I wanted to replicate some sort of simple skyline.

Emotions

I decided to go with 4 different emotions inspired from the following emojis.

cheesing. I wanted this one to be me at my happiest with a simple rainbow in the background.

sad. I wanted it to rain in the background and have my facial expression be a simple upside down arc.

neutral. I wanted this one to be me just meh, with nothing interesting in the background.

happy. I wanted this one to be me just normally happy with the sun in the background.

Previous coding experience with p5.js

I took Decoding Nature with Aya so I have had exposure to replicating natural patterns in p5.js so I wanted to replicate the rain pouring down with my old skill set learnt from her class.

For the rain pouring down effect,  I wanted to have simple white lines

// Draw rain
stroke(255, 255, 255); // 'white' rain
strokeWeight(2);
for (let i = 0; i < 20; i++) {
  let x = random(0, 600);
  let y = random(0, 400);
  line(x, y, x + 1, y + 5); // rain drops
}

Here I am generating lines and having their starting (x,y) coordinates randomly generated from any x coordinate of the screen and y coordinates of 0 to 400. I then have the line stretched out a little to the x by one pixel to create a more angled look.

For the eyes, I wanted them to also be interactive so I made them follow the cursor of the user.

else {
      // normal eyes - white background and black pupils that follow cursor
      noStroke();
      
      // white eye 
      fill(255);
      ellipse(270, 180, 25, 25); 
      ellipse(330, 180, 25, 25); 
      
      // black pupils that follow mouse
      fill(0);
      
      // calculate pupil position based on mouse location
      let leftEyeX = 270;
      let leftEyeY = 180;
      let rightEyeX = 330;
      let rightEyeY = 180;
      
      // calculte teh angle from eye to mouse
      let leftAngle = atan2(mouseY - leftEyeY, mouseX - leftEyeX);
      let rightAngle = atan2(mouseY - rightEyeY, mouseX - rightEyeX);
      
      // LIMIT pupil movement within eye bounds
      let pupilDistance = 4;
      
      let leftPupilX = leftEyeX + cos(leftAngle) * pupilDistance;
      let leftPupilY = leftEyeY + sin(leftAngle) * pupilDistance;
      let rightPupilX = rightEyeX + cos(rightAngle) * pupilDistance;
      let rightPupilY = rightEyeY + sin(rightAngle) * pupilDistance;
      
      // drawing the pupils
      ellipse(leftPupilX, leftPupilY, 8, 8); 
      ellipse(rightPupilX, rightPupilY, 8, 8);

From decoding nature, we learnt how to have particles follow our cursor by making use of the mouseX, mouseY variables. I had the pupils initial X,Y coordinates be the same as the white circles and then limit their distance to 4 so that they don’t go out of bound of the white circles.

The use of atan2() is used to calculate the angle from each eye center to the mouse position and returns an angle in radians. It is then used in the sin and cos formulas with basic trigonometry to create a new X,Y coordinate. Because the value of sin and cos will always be between -1 and 1, when multiplied by our pupilDistance (constraint we implemented earlier)  it will never go out of bound of the white part of the eye.

Final solution

Week 1 – Self Portrait

My look-alike animal I chose to portray myself is an owl. It didn’t have to be an animal, but I chose it simply because I like cute animals. It was tough trying to pick between an owl and a raccoon, but I stuck with an owl because when I during my military service, my teammates called me “angry bird” because of my sharp-looking eyebrows. The fact that I was bold probably made it worse. I combined both “angry bird” and owl to create “angry owl”.

Simplistic, but straight to the point. I added 2 animations during my work on this project. Please feel free to find both of them.

I love working at night because it’s quiet and it’s the time of day when I feel most focused. So if you try to get the owl’s attention by clicking, it will lift its eyebrow as a warning. It’s a do-not-disturb signal.

//eyebrow only moves at night
 if (!morning && eyebrow) {
   move += direction * 1.2; //speed of animation

   if (move <= -20) { //moved distance is max 20, if greater, change direction to go down
     direction = 1;     
   }
   if (move >= 0) { //when it reaches its original position
     move = 0;
     eyebrow = false;   //stop animation
     direction = -1;    //reset direction
   }
 }

That is the animation code for the eyebrows. One of the hardest parts of this code was changing the direction of the movement. If the position changes by 20 pixels, then it changes the sign of the direction so that it goes in the opposite direction. It was also difficult to trigger the animation. I have two animations that are played in different conditions: night and day. So coordinating the timing was probably the most difficult part of coding. I will explain the coordinating part after showing the code for morning animation.

(Explanation of Code, Skip this if this is a bit boring)

move+= direction is for the speed of the animation. But the sign of the direction indicates whether it goes up or down. If the animation moves for 20 pixels upwards, it satisfies the first condition, and the sign is changed. It was set to -1 before. So now, the eyebrow moves downward back to its original position. Since the sign has flopped, move slowly turns positive as it goes through the move+=direction line. At some point, it will reach 0, where the variable named eyebrow, which is set to true when the user clicks on the owl, turns false, and the direction changes to positive.

As you could guess, if you click on the moon, it changes the time of day. Also, if you click on the owl during the day, it will show the ZZZ animation.

function mousePressed() {
  //if position of sun/moon is pressed
  if (dist(mouseX, mouseY, X, Y) <= D) {
    //change day/night
    morning = !morning;
    //stop eyebrow
    eyebrow = false; move = 0; direction = -1;
    return;
  }

  // start Z animation in morning
  if (morning) {
    zActive = true;
    zStart = millis();
    return; // don't trigger eyebrows
  }

  //night means eyebrows haha
  if (!eyebrow){
    eyebrow = true;
  } 
}

I used two flags to trigger the animation: zActive and eyebrow. I set these values to true when the screen was clicked based on the time of day. I also had to carefully coordinate so that the flags were triggered where I wanted them to be.

(Explanation of Code)

When the mouse is pressed, it first checks if the user clicks on the area where the sun and moon are placed. If it is, then moring = !morning changes from day to night, vice versa. When the time of day changed, I made sure once again to reset variables just in case the animation plays. Now, if that was not the case, and the user clicks, it checks if it is morning or night. If it is morning, the zActive variable is set to true, and this sets off the ZZZ animation. If it is not morning, then it sets the eyebrow flag to true, which triggers the eyebrow animation. Figuring out this logic was probably the most difficult part of the code.

Finally, this is my ZZZ animation. 

/ZZZ animation
if (morning && zActive) { //only when morning and user clicked
  const elapsed = millis() - zStart; //measure time

  //number of Zs
  let visible = 0;
  if (elapsed >= 0){
    visible = 1;
  }
  if (elapsed >= 300){ //basically every 300ms, add one
    visible = 2;
  }
  if (elapsed >= 600){
    visible = 3;
  }

  ZZZ(width/2 + 70, height/2 - 120, visible);

  // after all Zs have appeared and held, hide all at once
  if (elapsed >= 3 * 300 + 600) { //600 is extra time just in case
    zActive = false; // disappears together
  }
}

I used millis(), which is used to measure the timing of animation. I wanted the Zs to play out one by one, so I had to time them by 300ms. The logic here is quite straightforward. 

function ZZZ(x, y, count) {
  noStroke();
  fill(0);                
  textAlign(LEFT, BASELINE); //aligns text to left and at baseline of font
  
  if (count >= 1) {
    textSize(20); 
    text('z', x, y); 
  }
  if (count >= 2) { 
    textSize(24); 
    text('z', x + 12, y - 12); 
  }
  if (count >= 3) { 
    textSize(28); 
    text('z', x + 28, y - 26); 
  }
}

This is the helper function to create the ZZZ effect. visible and count shows how many Zs are present, and it is incremented with time elapsed, measured with the millis function. Any further explanation of the code can be provided in class. 

For improvements, I was thinking about adding another condition. For now, when the owl is disturbed, it just repeats the animation. However, adding another animation when the owl is disturbed more than 10 times might be interesting. Owl spreading its wings and flying away sounds good. 

P.S. I was scrolling through the posts and found a post that is quite similar to mine (haha), although the contents were totally different. It was nice to see a fellow owl.

Self Portrait – Guli

Our hometask for the first week was to create a self portrait to practice using the simple drawing functions in p5js. For the assignment, I had an idea to use my avatar in Duolingo as a refernce. I really liked my Duolingo avatar — the colors, the shape, and the style, thus recreated it while adding more ideas.

The colors in the avatar are yellow for the background and orange for the dress. The avatar has smiling eyes that are curved at the bottom, along with sparkles. For the body, I simplified the design by making the head float, rather than directly being attached to the body. The idea of a floating head came from one of my chilhood cartoons Phineas and Ferb.

The curls and the curious expression with sparkles in the eyes are the highlights of the portrait. I am proud of myself for thinking off using human face color circles under the eyes to give the impression of smiling eyes. Drawing the curls also proved to be not a straightforward task, with me adjusting and readjusting the position and size of each brown circle untl  achieved the look I wanted.

In my future works, I could make the design interactive, so the art changes color or moves as the viewer comes into contact with the work. In terms of the design itself, I can use codes like arc() and  rotate(), adding more creativity to the work.

function setup() {
  createCanvas(600, 400);
  noStroke();
}

function draw() {
  background(255, 241, 167); // yellow bg

  // Face --------------------------------------------------->
  fill(255, 226, 214); // face color
  rect(200, 120, 200, 150, 40); // face shape
  
  
  // Eyes --------------------------------------------------->
  fill("white"); 
  ellipse(width/2 - 40, height/2 - 20, 75, 70); // left eye
  ellipse(width/2 + 40, height/2 - 20, 75, 70); // right eye

  // Pupils
  fill(61, 61, 61); // dark pupil
  ellipse(width/2 - 40, height/2 - 20, 45, 45); // left
  ellipse(width/2 + 40, height/2 - 20, 45, 45); // right

  // Blue part of pupil
  fill(57, 94, 130, 200); 
  ellipse(width/2 - 40, height/2 - 10, 35, 30); // left
  ellipse(width/2 + 40, height/2 - 10, 35, 30); // right

  // Sparkles
  drawSparkle(width/2 - 35, height/2 - 27, 15); // left eye sparkle
  drawSparkle(width/2 + 35, height/2 - 27, 15); // right eye sparkle

  // Under-eye curves 
  fill(255, 226, 214); 
  ellipse(width/2 - 40, height/2 + 20, 90, 60); // left
  ellipse(width/2 + 40, height/2 + 20, 90, 60); // right

  // Nose --------------------------------------------------->
  fill(248, 172, 148); // nose color 
  beginShape(); 
  vertex(width/2, height/2 - 10); // top 
  vertex(width/2 - 7, height/2 + 10); // left 
  vertex(width/2, height/2 + 17); // bottom 
  vertex(width/2 + 7, height/2 + 10); // right 
  endShape(CLOSE);

  // Mouth --------------------------------------------------->
  fill(179, 93, 110); // lip color
  ellipse(width/2, height/2 + 45, 20, 20); // lip position
}

// sparkle in the eye function ---->
function drawSparkle(cx, cy, size) {
  fill("white"); // sparkle color
  quad(
    cx, cy - size/2, // top
    cx + size/2, cy, // right
    cx, cy + size/2, // bottom
    cx - size/2, cy  // left
  );
  
  // circular sparkle
  fill("white"); // circle sparkle color 
  ellipse(width/2 - 50, height/2 - 15, 8); // left 
  ellipse(width/2 + 50, height/2 - 15, 8); // right
  
  // HAIR --------------------------------------------------->
  fill(84, 54, 41); // hair color
  // Top
  ellipse(width/2, height/2 - 120, 120, 90); // top middle
  ellipse(width/2 + 60, height/2 - 115, 110, 85); // top right 
  ellipse(width/2 - 60, height/2 - 115, 110, 85); // top left 

  // Left 
  ellipse(width/2 - 120, height/2 - 60, 90, 100); // left top 
  ellipse(width/2 - 140, height/2 + 10, 95, 110); // left bottom 
  

  // Right 
  ellipse(width/2 + 120, height/2 - 60, 90, 100); // right top 
  ellipse(width/2 + 140, height/2 + 10, 95, 110); // right bottom 
 

  // BODY --------------------------------------------------->
  fill(243, 161, 63); 
  ellipse(width/2, height - 10, 170, 200); // body position 
}

 

 

Week 1 – Self Portrait on p5js

CONCEPT:
For this assignment, I built a self-portrait entirely out of shapes in p5.js. I wasn’t trying to make something realistic, instead, I went for a cartoon version of myself: a round face, messy hair, glasses, and a simple smile. The idea was to see how much “me” I could get across with just ellipses, arcs, and lines. The output is far from realistic; come on, I am not trying to replace my passport photo with this. The portrait is simple, but I like how it balances between looking generic and still recognizably like me.

HIGHLIGHTED CODE:
The glasses ended up being my favorite part. Without them, the face felt empty, but adding two circles and a line suddenly made it feel right:
  noFill();
  stroke(0);
  strokeWeight(3);
  ellipse(167, 170, 60, 60);
  ellipse(233, 170, 60, 60);
  line(200, 170, 200, 170); // bridge

REFLECTION AND FUTURE WORK:
This was my first attempt at drawing myself, and that too using code; and it showed me how powerful even basic shapes can be. It doesn’t need shading or complex details to read as a face, and luckily identify a person if the components are placed right.

However, if I had more time, I’d like to:
– Make the eyes blink or move with the cursor (saw many do that, i can’t just yet)
– Give the background more personality
– Fix the hair so it looks less like a helmet and more like actual messy hair (pretty doable with multiple ellipses but i reckon there are more efficient ways)
Even with its simplicity, I like how it turned out, it’s definitely not a mirror image, but it’s “me” enough.

Week 1 – self portrait

Concept

For the self portrait I decided to show not exactly my picture, but the picture of my inner animal.

Initially, I drew a sketch of myself, holding a camera, because photography is on of my favorite hobbies. However, I then thought of giving more meaning to my portrait, because I had a call with my mom and remembered how she always called me an owl when I was a child (reason being my sleep schedule that is still very bad). So I thought, if my sleep schedule harms my health, let me at least use it to benefit my academics.


my initial sketch

what I decided to create

Creation

It was a little challenging for me to get started on p5.js, because of my limited coding skills, but after some experiments I was able to actually create something using simple circles, triangles and lines. One of the most challenging parts was creating the feathers on my Owl’s body, so I used some help from AI. I tried not to simply copy the code, but learn how to do it on my own as well. And because this was one of the most confusing part for me, I am proud because I eventually created it.

Interactivity

I made my drawing clickable: the owl sleeps during the day but if you click it, night comes and it wakes up (just like me).

Improvements

There are a lot of things I would like to improve in my project, one of them being enhanced interactivity. I would love to add moving clouds, more complex shapes for the owl, stars at night, and many others things that could make my owl more “likable”.