Reading Reflection- Week 2

Before watching the video, I assumed that “randomness” in art meant something purely spontaneous—an idea that suddenly appears in an artist’s mind. After watching it, I started to understand randomness differently. In generative work, the artist often writes a set of rules or instructions for a computer (or a system) to follow. The computer then runs those rules, and the final image can turn out in ways the artist didn’t fully predict. That surprise is part of the point.

But this also makes me wonder: is this still “randomness”? If the artist designs the rules, then the outcome isn’t completely uncontrolled. At the same time, the result can still feel unpredictable. The projects shown in the video seem to hold both chaos and structure at once—patterns emerging from something that still looks messy—and that combination is what confuses me.

This connects to a larger debate about whether AI-generated work counts as “real” art, and if it does, who the artist actually is. Is it the person who sets the prompts and constraints, or the AI that produces the final output? Generative art raises a similar question. The human chooses the system, the limits, and the type of randomness, but the machine carries out the process and generates the final form. In a way, the artwork is created through collaboration between human intention and machine unpredictability.

At the same time, I keep coming back to the purpose of this kind of work. Are we amazed mainly because a system can produce something that looks complex and meaningful from simple rules? And what happens if nothing surprising appears—if the output feels flat, repetitive, or uninteresting? Would it still count as art, or would it just feel like a technical exercise? These questions make me realize that “randomness” in generative art isn’t the absence of control—it’s more like a tool the artist uses to invite uncertainty, so that structure and surprise can exist together.

In my project, I think I have to set up some boundaries, but at the same time leave the computer some spaces that it can actually have options. But I am still very confused about what counts as a success in such an art project? This kinds of process is confusing: we are doing something logical and follow the instructions but we expected something unpredictable and surprising.

Week 2 – Loop Art

My Concept:

I started by looking at the links to computer graphics magazines. provided. A recurring theme I noticed is the repeated use of squares, circles, and other geometric shapes. So I knew that I wanted my design to incorporate a heavy geometric theme. As a beginner P5 coder, I wanted to make sure I could execute this idea with what I had learned so far. I ended up creating a square-oriented piece that offers the user interactions to play with, inspired by old computer art magazines. The piece features a canvas covered with animated squares across the grid that change color depending on the mouse’s position (left or right). On top of the dynamic background is a moving square that changes direction with a mouse click, creating a final artwork that evolves through loops. 

Highlight of Sketch:

// i is the variable used for the outer loop and controls the x positions across the canvas.
// j is the variable used for the inner loop and controls the y positions down the canvas. 
for (let i = 0; i <= width; i += 25) {
  for (let j = 0; j <= height; j += 25) {
    
    // r and g represent red and green values, and this line of code generates random color values adding some variation to the work.
    // mouseX controls the blue values and allows the user to move the mouse to change the color of the grid.
    let r = random(200,255);
    let g = random(100,200);
    let b = mouseX;
    
    //stroke created by using the red, green, and blue values initiated above. 120 represents the transparency of the circles.
    // ellipse uses the variables i and j to generate squares at each point of the grid.
    stroke (r, g, b, 120);
    noFill();
    rect(i, j, 20, 20);
  }
}

A particular part of the sketch I am proud of is the use of loops in my code. It was something new we had learned this week, and my incorporation of the inner and outer loop resulted in an outcome I am quite satisfied with and proud of. I am also proud of the randomized color variables in my code and of using mouseX to add user interaction with the colors.

Embedded Sketch:

How this was Made:

I started the process by setting my mind on what I wanted my piece to look like. After setting my mind on a specific idea, I then had to plan out how to execute it. I started my code by initializing my global variables, x and y, to store the current position of the moving square. Then I set speedX and speedY to control the direction and speed of the square’s movement. Then I set a lower frame rate with the frameRate() function to make the animation look cleaner and smoother. Then I used nested loops. An inner and outer loop that controls the grid background. The outer loop moves horizontally across (rows) the canvas, and the inner loops move vertically (columns) across the canvas. I set the red, green, and blue values and created random variables for them to add variety to the grid. The blue values are controlled by mouseX, so the user can change the grid color depending on whether the mouse is on the left or right side of the screen. Then I added the lines of code to create the main moving square. Then, using logical conditionals (or), I was able to have the square’s direction reverse once it hits any edge of the canvas. Finally, to add interaction to the code, I added the mousePressed() function, which allows the user to click the mouse to reverse the square’s direction. Using what I have learned so far, I created this fun final artwork.

Reflection and Future Ideas:

Overall, I am quite satisfied with my final piece and how I was able to combine what I have learned so far to create a fun, interactive piece with p5. Although the loop part and randomized variables part came with some trial and error, at the end I was able to overcome those obstacles and have an outcome I am proud of. For the future, I hope to learn more about p5 and create even more impressive pieces of work, specifically, more dynamic animations.

Assignment_2: loop art

Concept

I looked throught some of the old computerarts provided and some of the organized and innerric graphs reminded me of the golden curve and the related math arts that I have seen. I remembered that the seeds of the sunflower followed a certain mathematical pattern and decided to use that as the model for my computer art.

I did use AI in this assignment to understand the pattern and mathematical logic the sunflower seeds followed, and to figure out some basic formulas that would allow me to recreate such shapes, but the codes were my own.

Code chunk

for (let pointn = 0; c * sqrt(pointn) <= 150; pointn++) {
    let angle = pointn * 137.5;
    let x = c * sqrt(pointn) * cos(angle);
    let y = c * sqrt(pointn) * sin(angle);
    
    //The code can be played with using many math functions, I tried some and attached them below
    
    //without sqrt
    //let x = (c * (pointn)/10) * cos(angle);
    //let y = (c * (pointn)/10) * sin(angle);

    // logarith(also looks good when made 1*c)
    // let x =5*c * log(pointn) * cos(angle);
    // let y =5*c * log(pointn) * sin(angle);

    //1/log
    // let x =100*c * 1/log(pointn) * cos(angle);
    // let y =100*c * 1/log(pointn) * sin(angle);

    let r = map(x, -300, 300, 80, 255);
    let g = map(y, -300, 300, 80, 255);
    noStroke()
    fill(r, g, (r + g) / 1.65);
    circle(x, y, 3);

The full code is relatively short so I picked the for loop section because I think it shows exactly what loops are helpful for. This chunk of code greatly utalizes the efficency of loops. It would be extremely difficult and time consuming to draw all the dots with accurate spacing by repeated lines of code. The for loop allows drawing and editing of the dots in one line, making it much easier. I also thouht it is intereating that I am able to create different patterns using only change in the mathematical function and slight adjustment to numbers, so I included those modified codes as well.

I was able to recreate the sunflower pattern in resting first, but I thought it looked a bit dull. Because it was a round pattern and included curves, I decided to make it rotate around the center to have a bit of a dillusional effect. I looked up a video tutorial on youtube and learned how to move start point to the center of the canvas and how to rotate it. The effect is pretty good.

Reflection

Drawing a mathematical pattern probably does not really fit the requirement of doing computer art, but I believe the Fibonacci numbers and its related curves do all look quite artistic, and the massive amount of dots needed is an excellent medium for praticing loops. My finished work seems a bit easy and a bit short for an assignment, and I might decide to try something more complicated and in accordance with class difficulties in future assignments.

Another thing is that AI really is quite helpful in the case of understanding scientific or math related concepts. I wouldn’t have been able to figure out all the formulas myself. I will attach my conversation with Gemini in the reference section

References

  • https://www.youtube.com/watch?v=i5bs3SPpHdM
  • https://www.youtube.com/watch?v=z9d1mxgZ0ag
  • https://www.youtube.com/watch?v=3U8-9_WeuKE
  • https://www.youtube.com/watch?v=_GkxCIW46to
  • https://gemini.google.com/share/4c9531505d04

Assignment 2: Box Hit

Here is my final sketch:

Concept:

For this project, I was inspired by the game Smash Hit, where a ball hits glass and causes it to shatter. Also, while looking through the computer art magazines, I came across Boxes I by William Kolomyjec. I decided to combine these two ideas by creating a grid of squares with a circle in the center that acts as a button that triggers the distortion of the squares. 

The circle turns green when the viewer hovers over it and turns red when clicked. Once you click on it, the circle causes the squares surrounded by it to distort, kinda like in the artwork I was inspired by. I wanted a controlled system that slowly breaks apart, while having a game-like effect. 

Here is the artwork I was inspired by that was in the magazine:

Code Highlight:

The code that I am particularly proud of is the section that distorts the boxes based on their distance from the center and the randomness to its position and sides. It gave the visual effect I wanted. 

//distortion control using the radius
if (ruined && radius < 155) {
  //so if the disortion is on and the radius hasn't reached its maximum, expand the radius. I chose the number 155 because I didn't want the disortion to go all the way out.
  radius += 4; //to increase the radius gradually (like a firework effect)
}

if (!ruined) {
  //if the distortion is off to reset the radius back to 0.
  radius = 0;
}

//the grid of boxes
for (
  let x = 0;
  x <= width - size;
  x += size //so it can loop horizontly
) {
  for (
    let y = 0;
    y <= height - size;
    y += size //so it can loop vertically
  ) {
    let d = dist(x, y, width / 2, height / 2); //to get the distance from the squares to the center of the canvas

    //to make the grid distorted
    if (ruined && d < radius) {
      // if the distortion is on and the square is in near the radius
      rect(
        x + random(-5, 1),
        y + random(-5, 1),
        size + random(-5, 1),
        size + random(-5, 1)
      ); //to make random x and y positions and change the width and height for a random messy effect. (for the disorted squares)
    } else {
      // if the squares are not within the radius.
      fill("white");
      rect(x, y, size, size);
    } // let the rest of the boxes to be straight and untouched
  }
}

Reflection/future work:

In class, we used loops to create a grid of circles, so I applied the same concept using nested for loops to build a grid of squares. At first, the size of each box was 50, but I felt that it was too large for the distortion effect to look effective. The larger size also caused some of the boxes to be cut off at the edges of the canvas. So I decided to reduce the size of the boxes to 20, which made the grid feel more refined and detailed. 

Also, the distortion effect was happening too fast it felt overwhelming. I tried to slow it down by reducing the values inside the random function, but this did not work the way I expected. So I just did the frameRate function and put it inside the setup function, like how you showed us in class. I think slowing down the frame rate helped the movement feel more controlled and intentional.

When the circle was clicked, all the boxes that were within the radius distorted at the same time. I was going to leave it this way, but I showed my friend, and she told me that I should try to make the distortion spread outward gradually, like a firework. I did this by using a radius that slowly increases over time, allowing it to expand from the center instead of appearing all at once. I think it made it more visually interesting, so I stuck with it.

While working on this project, I sometimes needed help with the order of the functions and how everything should be structured so the sketch would work properly. I already knew the functions from the slides and reference materials and wrote the code myself, but I was not always sure how to organize them in an order that would work. So I used ChatGPT and Google searches to help clarify those details, specifically how to control the distortion using a radius value and why that needs to be placed at the top of the draw function so it could update consistently, and where the mouse-pressed function should be placed. But most of my understanding came from the class examples, lecture slides, and trial and error with my code. 

In the future, I would like to add more details and incorporate more concepts that were previously discussed. I am interested in exploring different types of distortion and animation that really enhance the experience. 

Reading Reflection Week 2: Order and Complexity in Digital Art

Going into Reas’ talk about the length of using order or complexity in a digital artwork, I find it striking just how different the artworks are made depending on the level of randomness used. I mean looking at the Commodore 64 program, it’s very clear that logic and clearly defined patterns are sort of the bedrock of the artwork. Whilst there is a slight bit of randomness in terms of the direction of the lines, it’s interesting that the core of it, is quite literally a random coin flip. Starting from a random coin flip and then giving it symmetry, it’s clear that while on the surface there is a sense of unity and structure to it, the very first base layer is randomness. The level of randomness used is certainly not as heightened as other art pieces but I find it interesting how it is still present.

Whereas for the art piece “Articulate” there is a much higher level of randomness and noise, but the bedrock level is actually a unifrom, straight line. The artwork starts out from logic, in the form of a line, but then it branches out in random directions. It doesn’t have any sense where it goes to and what’s even more interesting is that it is able to make an art piece with actual depth to it. This is vehemently clear as some parts of the artwork are lighter than others, giving a pop feel and something that can be more so passed off as an art piece. So even still, it is possible to have a coherent art piece even if the starting layer is randomness.

For my own art, I would utilise the second approach. I’d start perhaps even with a uniform pattern of dots or lines, and then really go from there. I’ve used this practice even for drawings with acrylic colours, as it gives me more of a lovely sense of chaos as the drawing progresses. I feel like that’s what we sort of strive for in art, as we feel as though throughout the drawing process, we need a sense of rebellion to get our emotions across.

But how do we balance chaos and order? Personally I believe we need a good amount of intial grounding at the beginning of our drawing. And then as we go, we should have a very good degree of randomness. But not so much it actively ruins our order. Translating it into percentages, I would say a good 5-10% of order at the beginning, with a decent sized 70% randomness and 30% of order throughout the drawing process. But of course, at the end we are our own artist, so we set our limits and I’d always welcome more randomness.

Madina – my first p5.js self portrait

For my first Intro to Interactive Media assignment, I created a simple self-portrait using p5.js and basic geometric 2D shapes. My goal was to capture a few key things about myself: my long brown hair, pale skin, brown eyes, and my favorite color. I chose soft colors and a minimal one-color background so the focus stays on the face and shoulders, which feel the most “me.” One of my favorite parts of the code is how I drew the shoulders and upper body using an arc() instead of a rectangle. The code looks like this:

 // shoulders/body
fill("pink"); 
arc(300, 600, 400, 260, PI, 0);

At first I was not sure how to draw the upper body in a way that looked rounded and soft instead of like a flat block. While exploring “The Coding Train” Youtube tutorial’s reference for shapes, I found the arc() function and realized I could use it as a big curved shape at the bottom of the screen to suggest shoulders. The last two numbers in arc() are angles in radians: I used PI as the start angle and 0 as the end angle to draw a half-circle shape for the shoulders. As i learned, in p5.js, PI is a built-in constant that represents the mathematical value of π (about 3.14159), which is the ratio of a circle’s circumference to its diameter. By using PI and 0,  the arc draws from the left side of the circle to the right side, creating a smooth curved top edge that looks like a rounded shoulder line. I like this part because it looks nicer than a rectangle,  also because I filled it with pink, which is my favorite color, so this area feels very personal and represents my personality as a light color lover.

Embedded Portrait:

I built the self-portrait with shapes 2D drawing functions in p5.js such as ellipse(), rect(), line(), arc(). The face and eyes are made from ellipses, the body and neck use rectangles and the pink arc for the shoulders, and the hair is constructed from overlapping rectangles and ellipses to suggest long brown hair. I also adjusted the fill () colors for the skin tone, hair, and clothing, somewhere I used colors just typing them, other ones such as the shoulders, skin and hair I  tested different RGB values until the skin looked pale, the hair read as brown, and the pink for the shoulders matched the color I had in mind.

For learning how to code the portrait, I mainly used the official p5.js tutorials and followed Youtube tutorials from “The Coding Train” channel to get more comfortable with the general structure of a p5.js sketch. This assignment helped me get more comfortable with thinking in coordinates and breaking down a portrait into geometric shapes. Discovering that I could use arc() and the PI constant to create a curved shoulder shape was a small but important moment, because it made me realize how much control I have over shapes. In the future, I would like to add small details like accessories or texture in the hair using more line () and ellipse() shapes, experiment with simple interactivity, changing background colors or facial expressions when the mouse is pressed. Overall, the portrait is still quite minimal, but I feel it already captures some of my identity through the color choices and the simplified representation of my face and shoulders.

Reading Reflection – Week 2

One thing I really loved in Casey Reas’ Eyeo talk on chance operations was how much inspiration came from bundling architecture. Looking at real neighborhoods and constructions, and then creating them into systems of rules and geometry, made the work really interesting and intentional. That approach really resonated with me, especially because I see a lot of overlap with Casey’s lecture and what we talked about in my Understanding IM class. We talked about the Dada movement and how chance was used as a response to control and structure after WWI, and many of the artworks, like the Jean Arp piece shown in the video, overlapped with examples we’ve already studied. In both of these cases, chance is used within a structure, which allowed forms to emerge rather than be fully planned. Moreover, to me, this video felt like a short history of digital art, showing how artists moved from pure experimentation to systems where form and behavior emerge over time, reminding me of the book he showed of a million random digits with 100000 normal deviations. I also really liked the idea of making things that are clearly artificial, but still giving them an organic quality.

Before watching this video, I mostly thought of randomness as something that makes things messy and out of control. I think that came from my own experience, when I tried to make a random background for my self-portrait, and the words kept filling the space until it turned completely black. This video helped me realize that randomness is not completely random, but is intentional and planned. There is always a set of instructions and the use of precise geometry behind it. I remember Reas said something along the lines of “pure randomness with symmetry, you start to see faces, and triggering our imagination,” and that stuck with me. In my own work, I will now set clear rules first and then allow small random changes, like with the position or scale. I think that feels like the best balance between control and chaos for me because I still design the system, but do not fully control the outcome. The results can be something better than I planned from the start. I do believe the author is biased in a way by portraying chance positively, like yes, chance can open up to new possibilities, but it only works because of the structure placed around it. The video left me thinking about how much control an artist should give up. Also, I am interested in exploring ideas like a maze or a shape that grows outward from the center, similar to what was shown in the video.

Week 2 Assignment – 3D Conway game of life

Conway game of life 3D sketch below!

Concept:

The inspiration for this is Conway’s game of life, computer generated art is like an umbrella term, I started with searching up old computer generated art in the 50’s and 60’s, and there were some cool concepts like using computer parts to make some sort of art out of them, but it wasn’t exactly what I was looking for. Then it hit me! Conway’s game of life, but not just 2D, that would not work for me, I had to make it 3D, and that’s how this sketch started.

I had to tweak the rules a bit to give this a more generative art feel as well as per-determining the spawn position for the starting cells.

Implementation:

Before we get into the technical implementation of this, let me cover  the theory and rules that the sketch runs by.

Of course for 3D we had to use webgl, to get our 3rd axis (z), and also use orbital control to allow us to move around the area.

createCanvas(400, 400, WEBGL);
// Start with a view of the entire resolution
camera(0, 400, 4900, 0, 0, 0, 0, 1, 0);

orbitControl();

 

A dead cell becomes alive only if it has exactly 3 or 6 neighbours. (Neighbours are alive cells that are next to the cell we are checking)

A living cell stays alive only if it has exactly 5 or 6 neighbours, otherwise it will die.

For the starting spawn, I first started with giving each cell a random chance of 2% to become alive on initialization, it would work however sometimes the  cells would all die or I would not get a good looking design, so I decided to spawn the cells at each corner.

// Create the array for all th cells state
  for (let x = 0; x < res; x++) {
    grid[x] = [];
    next[x] = [];
    for (let y = 0; y < res; y++) {
      grid[x][y] = [];
      next[x][y] = [];
      for (let z = 0; z < res; z++) {
        // Seed with 3x3x3 clusters at corners
        let inCorner1 = x < 3 && y < 3 && z < 3;
        let inCorner2 = x >= res - 3 && y < 3 && z < 3;
        let inCorner3 = x < 3 && y >= res - 3 && z < 3;
        let inCorner4 = x >= res - 3 && y >= res - 3 && z < 3;
        let inCorner5 = x < 3 && y < 3 && z >= res - 3;
        let inCorner6 = x >= res - 3 && y < 3 && z >= res - 3;
        let inCorner7 = x < 3 && y >= res - 3 && z >= res - 3;
        let inCorner8 = x >= res - 3 && y >= res - 3 && z >= res - 3;

        grid[x][y][z] =
          inCorner1 ||
          inCorner2 ||
          inCorner3 ||
          inCorner4 ||
          inCorner5 ||
          inCorner6 ||
          inCorner7 ||
          inCorner8
            ? 1
            : 0;
        next[x][y][z] = 0;
      }
    }
  }

To check for neighbours of each cell, we use a triple nested loop and offset from -1 to 1, to check behind, center forward for each axis.

A couple things to note is, I run the rule checking code once every 30 frames, so that the cells don’t populate too fast and so that we can actually see what is happening and enjoy the chaos that is happening.

A couple things I am proud of is my optimization and coordinate calculation.

Context: There are 2 grids that we are using, our “present” grid and the “next” grid, to not confuse the computer, we apply our rule application and calculation to our present grid, but store the results in our next grid, now originally to switch between the 2 I would turn grid into a long string JSON, then parse it tot equate it to next, but that would lead to thousands of operations. So what I figured out was actually something from c++ and dealing with pointers, and it’s simply just changing the name. To provide context, in javascript you can’t equate the 2 grids to each other to change them, because then they would be connected and if you affect one grid the other is also affected which defeats the purpose of having 2 grids.

let temp = grid;
grid = next;
next = temp;

These 3 lines may not seem much, but it saves our computers from doing thousands of operations every 30 frames, and reduces those thousand of operations to simply 2 operations.

Now, I had to limit the cells to spawn in a specific area of our canvas, otherwise the calculations would get too much, and wordpress would not be able to handle that many calculations.

let cellSize = 50;
let res = 20;

Resolution is basically how many cubes we want, or in this case we want a dimension of a 20 by 20 by 20 cubes, which is 8000 cubes, and 8000 operations every 30 frames, anymore and the browser would slow down tremendously so 20 was the sweet spot.

for (let x = 0; x < res; x++) {
    for (let y = 0; y < res; y++) {
      for (let z = 0; z < res; z++) {
        // Check if the cell is alive
        if (grid[x][y][z] === 1) {
          // Calculate the position of the cell in the canvas using the res and size as reference.
          let xPos = x * cellSize - (res * cellSize) / 2;
          let yPos = y * cellSize - (res * cellSize) / 2;
          let zPos = z * cellSize - (res * cellSize) / 2;
          push();
          translate(xPos, yPos, zPos);

          // Map scales our rgb colors based on the location so the cube looks like a spectrum.
          let r = map(x, 0, res, 0, 255);
          let g = map(y, 0, res, 0, 255);
          let b = map(z, 0, res, 0, 255);
          fill(r, g, b);
          stroke(0, 50);
          box(cellSize);
          // Take the pointer back to 0,0,0
          pop();
        }
      }
    }
  }

Our coordinate system of the resolution is going to be different to the canvas coordinate system, so with a little bit of math, we could take our raw x y z coordinate and convert them into our resolution coordinates to allow us a proper bounded area.

Finally giving us that beautiful color spectrum, we use the map functions which allows us to scale our resolution with the rgb values, for example at 10 (half way into resolution) the  r value would be 127 (half of 255).

Reflection and Improvements:

Honestly I am particularly happy about how this turned out, I thought it would be quite difficult to implement but it turned out a lot better and easier than I expected it to and I am happy that I went through with it.

A couple ways I would think about improving it is adding a gradient color background, and maybe implement more shapes for cells to be rather than simply a cube.

Week 1 – self-portrait

my concept: My self-portrait is a very simple one, I’ve gotten the idea of the shape from the koala example we’ve seen in class. I wanted to make it look cool (even though it didn’t go that well), so I added an interaction where a sword shows up. I’ve gotten this idea while playing a video game called “Elden Ring” where one of the characters would make swords show up.

A section of the code I feel a bit proud of is this:

if (hasSword && swordPosY < swordStopY) swordPosY += 6;
if (!hasSword && swordPosY > -200) swordPosY -= 6;

it was quite confusing getting it to work right, and took time for me to find a good position and make it work the way I want it.

How was this made: I tried keeping the portrait simple, so I mostly used things like ellipse, arc and rect from the references section on the p5 website. I also used AI to look for functions I could use with the swords, cause it seemed faster than me looking them up, it ended up giving me some functions that were quite new and complicated. from AI I ended up using the mousePressed() function to move the sword, which I remember we did see soemthing similar being used in last week’s class. Another function it suggested was lerp() which I didn’t use.

Reflection: I’ve never used Js before, so this was a new experience to me especially with the p5 library, where I got to learn how to arrange shapes and manage coordinates. Making a portrait from such basic things was really fun. If I had more time I would’ve tried adding another animation with the sword instead of it just dropping down. Another thing I could’ve done was making the facial expression more personal and less goofy. The last thing was making a better background like it being night with the moon and stars up there.

Week 1 – Self-Portrait

Your concept

For my self-portrait, I had two main ideas I wanted to portray. First, I wanted to include something from Egypt. I landed on including the Pyramids as the background of the portrait. I really like how it looks and how it’s a subtle detail in the background that gets my idea across. The other detail I wanted to include some interactivity to do with taking off/putting on my glasses, since I recently started wearing contacts. I was showing my friend the self-portrait, when she gave me the idea to also change the background when I added the glasses, which I decided to incorporate. During the day, I included clouds as well as the sun in the background, at night, it’s replaced with stars and the moon (in addition to adding glasses on my face)!

A highlight of some code that you’re particularly proud of
// glasses
if (mouseIsPressed) {

strokeWeight(2);
fill(211, 211, 211, 100);
stroke("brown");
circle(305, 256, 50)
circle(378, 256, 50)

line (330, 253, 352, 253)
line(280, 253, 271, 246)
line(403, 253, 410, 246)
}

I’m proud of the code to add the glasses on my face. The code is pretty simple but I was excited to add something interactive to my code, so I like that the user can press to change up somethings in the portrait. After adding the glasses code, I added the code to change up the background (day/night).

// pyramids
  let s = color ("#D6BF6F");
  let c = color('#e2ca76');
  fill(c);
  stroke(s);

  // pyramid of khufu
  triangle(436, 400, 586, 166, 720, 377);
  
  // pyramid of khafre
  triangle(139, 390, 342, 40, 575, 400);
  
  // pyramid of menkaure
  triangle(0, 386, 147, 140, 298, 390);

I’m also proud of my code for the Pyramids, as simple as it may seem, it took me a while to get all the coordinates right. What I found especially helpful was using the cursor & printing the values of the coordinates to find where I should place each point of the triangles. I really like how the pyramids overlap over each other and I like that the outline becomes more visible at night.

Embedded sketch

How this was made

The first thing I completed was the Pyramids and sand in the background. Initially, I had place this code in the setup() function, rather than the draw() function, since I wasn’t planning to change the background. However, after deciding to have an interaction of changing the background between day and night, I moved the code to the draw() function. Throughout the code, the most helpful thing to figure out coordinates was definintely the print(mouseX, mouseY) line (which is commented out at the end of my code).

After completing the Pyramids, I started working on the actual portrait. I was a bit unsure on how I wanted to do my hijab, and I landed on an ellipse with a rectangle at the bottom. I also added a semi-circle with a rectangle at the bottom to mimic my body. For the face, I used ellipses, circles, semi-circles, triangles, lines, and rectangles, to complete all the features. Something that I found so tedious was the eyelashes. It was a bit to annoying to manually find the coordinates for each point on the line, especially since it was so small, so it took more time than I expected. I expected that drawing my eyebrows would be a bit difficult as I wasn’t sure how to draw a curve, and a line would’ve been too thin. However, after looking through the references, I realized I can just edit the stroke weight so that was helpful. The glasses were what I was most excited for in this portrait, and I love how they turned out since they look very similar to my current glasses.

The clouds, stars, sun, and moon were the last few details that I added. At first, I was struggling with getting the cloud shape correct as I was trying to do using an ellipse and the circles on the outside., but it didn’t look right. I decided to just find a YouTube tutorial and as soon as I started the video, I realized I was overcomplicating it for myself. I just used three circles for each cloud, the left and right circles are smaller and similar in size, while the middle circle is bigger than both circles. As for the sun, it was just a simple yellow circle, I just decided to add the transculent circle in the background as I thought it looked pretty. For the stars, I wanted to play around with the random() feature  so that each star would be randomly placed everytime the user pressed the mouse. However, it didn’t really go as expected as the stars were just moving around instead. I tried playing around with some functions but it didn’t really work the way I wanted so in the end, I just manually wrote around 10 random coordinates for each star. The moon was pretty simple, I just placed it at the same location as the sun but just made it a tad bit smaller.

Throughout the code, I mostly referred to the p5.js reference page and just trial-and-error to get everything looking the way I wanted. I also used Google to find hex codes for everything, as well as also just selecting directly from the color gradients.

Code
function setup() {
  createCanvas(700, 600);
}

function draw() {
  
  // background is blue sky & sand at the bottom
  // sky
  if (mouseIsPressed) {
      background('#00022e')
  } else {
    background('#448ee4');
  }
  
  if (mouseIsPressed) {
    // moon
    fill("white");
    stroke("white");
    circle(601, 79, 130)
      
    color("white")
    strokeWeight(5);
    point(23,45);
    point(100,76);
    point(500,25);
    point(340,132);
    point(265,156);
    point(45,190);
    point(650,200);
    point(130,10);
    point(123,143);
    point(600,12);
    point(696,109);
    point(210, 63)
    point(462, 97)
    point(484, 148)
    point(318, 27)
    
  } else {
    // clouds
    fill("white");
    stroke("white");
    circle(75, 67, 60)
    circle(128,55, 80)
    circle(176, 59, 60)

    circle(275,111, 80)
    circle(337,110, 120)
    circle(407, 111, 80)

    // sun
    fill("orange");
    stroke("orange");
    circle(601, 79, 150)

    fill(255, 255, 0, 50);
    stroke(255, 255, 0 , 50);
    circle(601, 79, 170)
  } 
  
  // pyramids
  let s = color ("#D6BF6F");
  let c = color('#e2ca76');
  fill(c);
  stroke(s);

  // pyramid of khufu
  triangle(436, 400, 586, 166, 720, 377);
  
  // pyramid of khafre
  triangle(139, 390, 342, 40, 575, 400);
  
  // pyramid of menkaure
  triangle(0, 386, 147, 140, 298, 390);
  
  // sand 
  // i added the code for the sand after the pyramids to cover the bottom outline of the pyramids
  fill(c);
  stroke(c);
  rect(0, 389, 700, 600);
  ellipse(118, 388, 264, 20);
  ellipse(263, 429, 500, 100);
  ellipse(577,400, 264, 50);
  ellipse(646,400, 400, 60);
  
    strokeWeight(1);
  
    // hijab 
    let h = color("#808080");
    fill(h);
    stroke(h);
    ellipse(340, 310, 200, 280);
    rect(241, 335, 198, 100);
  
    // face
    let f = color("#f3c37e");
    fill(f);
    stroke(f);
    ellipse(340, 290, 150, 210);
    
    // eyes
    fill("white");
    stroke("white");
    ellipse(305, 256, 40, 15);
    ellipse(378, 256, 40, 15);
  
    fill("#371d10");
    stroke("black");
    circle(305, 256, 15);
    circle(378, 256, 15);
  
    // eyelashes
    line(292,250,289, 243);
    line(297, 248, 295, 241);
    line(302, 247, 301, 240);
    line(307, 247, 307, 240);
    line(312, 248, 313, 240);
    line(317, 249, 319, 242);
  
    line(366, 249, 362, 242);
    line(370, 248, 369, 240);
    line(375, 248, 374, 240);
    line(380, 249, 380, 240);
    line(384, 248, 386, 241);
    line(388, 249, 392, 242);
  
    // eyebrows
    strokeWeight(8);
    line(320, 230, 294, 228);
    line(282, 234, 294, 228);
  
    line(360, 230, 388, 228);
    line(398, 234, 388, 228);
  
    strokeWeight(1);
    
    // nose
    fill ("#DAB073");
    stroke("#DAB073");
    triangle(331, 311, 340, 280, 350, 311);
  
    // body
    let b = color("#800080");
    fill(b);
    stroke(b);
    arc(340, 490, 210, 150, PI, TWO_PI);
    rect(235, 490, 210, 110);
  
    // mouth
    fill("#a90830")
    stroke("#a90830")
    arc(340, 328, 85, 80, 0, PI);
  
    // teeth
    fill("white")
    stroke("rgb(240,235,235)")
    rect(305, 328, 9, 10);
    rect(314, 328, 9, 10);
    rect(322, 328, 9, 10);
    rect(331, 328, 9, 10);
    rect(340, 328, 9, 10);
    rect(349, 328, 9, 10);
    rect(358, 328, 9, 10);
    rect(367, 328, 9, 10);
  
    rect(324, 357, 9, 10);
    rect(334, 358, 9, 10); 
    rect(343, 358, 9, 10);
    rect(353, 356, 9, 10); 
  
    // glasses
    if (mouseIsPressed)  {
    
      strokeWeight(2);
      fill(211, 211, 211, 100);
      stroke("brown");
      circle(305, 256, 50)
      circle(378, 256, 50)

      line (330, 253, 352, 253)
      line(280, 253, 271, 246)
      line(403, 253, 410, 246) 
    }
  
    // print(mouseX, mouseY);

}
Reflection and ideas for future work or improvements

Overall, I’m proud of my work, and I hope to continue improving in p5.js, especially when it comes to smaller details and learning to use more shapes (such as curves and quadrilaterals). I’m really happy I was able to add interactivity, and am especially happy with how the background turned out, and I hope to continue learning how to work with all the interactive features.

I do think there’s a lot of room for improvement in my work. I would love to work on the hijab in my portrait and try to make it more realistic. Additionally, I would’ve liked to have more realistic facial features which I hope will become easier the more familiar I become with p5.js.