Assignment 1: Self-Portrait

Inspiration and Concept 

I wanted my self-portrait to highlight two main things: my glasses and my big curly hair. There were also a few artistic elements I identified early on that I wanted to incorporate. Growing up, the first thing I learned to draw was flowers. Since then, I have incorporated flowers, specifically sunflowers, into much of my artwork. Hence, I planned to have flowers as a recurrent motif in my self-portrait. Another thing I wanted to stand out in my self-portrait is good color coordination. A specific self-portrait I found that resonated with all of these ideas and captured the essence of what I wanted to create is by Erika Norma, which can be found in this Medium article she wrote.

Process and Implementation

I started by creating a rough sketch of the outline. The majority of the outline is composed of curves and smooth lines. To ensure that my shapes looked smooth, I relied on curveVertex() to specify vertices (points) along which a curve would be drawn. I used curves to draw the face and the hair. To make the self-portrait look more animated, I decided to add a wave movement animation to the hair. I was able to create the desired effect by adding curves with vertices whose x and y coordinates are defined by sinusoidal functions (this example was a very helpful demonstration of simulating sine waves in p5.js and I derived inspiration from it as I animated the hair). I played around for some time with different angle increments, amplitude, and shifts until I was happy with the result. Although it is not perfect and is probably not the cleanest way to implement this effect, I would say this portion of the code for drawing and animating the hair is the one I am most proud of as it perfectly demonstrates how mathematics can be directly used to generate art. It also took me the most amount of time to get right so I was very satisfied once all the components fell into place.

function hair() {
  push();
  beginShape();
  fill(72, 60, 50);
  stroke(72, 60, 50);
  // right side
  for (let i = 0; i < 20; i++) {
    // calculate x and y positions dynamically using the counter i and sinusoidal functions to create wave movement 
    // used helpful demonstration of using sinusoidal functions for waves https://p5js.org/examples/math-sine-wave.html
    let x = 350 + i * 20;
    let y = i * 15 + sin(hairAngle + (i * PI) / 2) * 10 + 90;
    // add vertex to the curve
    curveVertex(x, y);
  }
  // left side
  for (let i = 20; i > 0; i--) {
    let x = 310 - i * 20 ;
    let y = i * 13 - sin(hairAngle + (i * PI) / 2) * 10 + 50;
    curveVertex(x, y);
  }
  endShape(CLOSE); // close the shape to connect the last and first points

  // bottom of the hair
  noFill();
  strokeWeight(200); // use large stroke to cover the bottom edge of the conjoined left and right hair shape
  beginShape();

  for (let i = 0; i < 30; i++) {
    let x = i * 40 + cos(hairAngle + (i * PI) / 2) * 10 - 100;
    let y = 400 + sin(hairAngle + (i * PI) / 2) * 10;
    curveVertex(x, y);
  }
  endShape();
  pop();
}

One obstacle I had with the hair was creating one closed-shaped curve that would be the moving hair. When I attempted to join the two sides of the hair by closing the shape formed by them, I realized that the bottom would be automatically closed with a straight line. I resorted to a rather gimmicky way of resolving this by adding a bottom moving curve with a large stroke that would cover that straight line. If I were to redo this, I would try and dynamically create all sides of the hair using one shape and be more careful with calculating the vertices.

I also used curves and cosine functions to animate the movement of the earrings using the same principles.

The implementation of the flowers was a modification of this reference. The flowers were used to create the dress and are a part of the interactive background that is displayed when the mouse is clicked. The flower petals are implemented using ellipses. To create the rotation animation, all flower components rotate by an angle that is dynamically changing each frame. For the sake of generalization, I implemented the following drawFlower() function to allow for the creation of all the different colors, shapes, and types of flowers (including sunflowers!) that I needed.

function drawFlower(
  r,
  g,
  b,
  dx,
  dy,
  petalX,
  petalY,
  petalW,
  petalH,
  centerR,
  rotationAngle,
  isSunFlower = false
) {
  // helpful guide: https://editor.p5js.org/xinxin/sketches/0j7vGT3u6
  push();
  noStroke();
  ellipseMode(CENTER);
  translate(dx, dy);
  rotate(radians(rotationAngle));
  fill(r, g, b);

  for (let i = 0; i < 20; i++) {
    // flower petals
    ellipse(petalX, petalY, petalW, petalH);
    rotate(PI / 10);
  }

  // fill center with a darker color if sunflower
  if (isSunFlower) {
    fill(r - 11, g - 22, b);
  }

  ellipse(0, 0, centerR, centerR);
  pop();
}

To add a small interactive component, the background of the sunflower would display a falling sunflower animation once the mouse is clicked. The original background and the animated background alternate with every click. In the setup function, a number of sunflower object literals with x, y, and speed attributes are defined. All values are randomized from a certain range (e.g. the y position is randomized between -1000 px and -50 to ensure that each flower is initially displayed above the canvas). Each flower is then added to a global array,fallingFlowers.

The animation itself was done by incrementing each flower’s y position by its speed attribute in every frame, ensuring its position is reset again above the canvas at a random position once it hits the bottom.

Reflections and ideas for future work or improvements

I am overall satisfied with the outcome. It was close to how I envisioned it would look like. I especially loved the aesthetics of the moving hair and earrings. I also enjoyed playing with colors – especially daring to choose yellow and purple for the glasses  – and the process of making creative decisions, such as adding in lips last minute. As I mentioned, however, I would have loved to find a cleaner way to implement the hair shape and animation without having to resort to adding in an extra curve shape. In my next projects, I aim to delve deeper into creating more complex curves and exploiting mathematical relations to create interesting animations.

Assignment 1 – Self Portrait (Redha Al Hammad)

For this assignment I have produced a self portrait of myself with two defining features: my glasses and my camera.

Initially, the concept I wanted to pursue involved a simplistic rendering of my face with mouse tracking applied to the eyes and camera. I am most proud of the fact that I managed to achieve this idea with the eyes (albeit with some help from the p5js reference page). The main difficulty with this for me was trying to understand how the mouseX and mouseY functions worked in relation to the constrain function. However, with lots of experimentation, I managed to figure out how to implement mouse tracking the way I intended for the eyes. I have included the code for it below:

 // eyeballs
 fill(255)
 ellipse(150, 175, 50, 40)
 ellipse(250, 175, 50, 40)
 
   // pupils
 fill(80, 40, 10);

let leftPupilX = constrain(mouseX, 140, 160);
 let leftPupilY = constrain(mouseY, 170, 180);
 ellipse(leftPupilX, leftPupilY, 25, 25);

 let rightPupilX = constrain(mouseX, 240, 260);
 let rightPupilY = constrain(mouseY, 170, 180);
 ellipse(rightPupilX, rightPupilY, 25, 25);

 

This leads onto the many aspects which I wanted to implement but could not with the main one being the implementation of mouse tracking on the camera. Ideally, the intended outcome was to have the eyes track the camera as it moved around with the mouse in order to create a more dynamic and interactive experience. However, I could not figure out how to apply mouse tracking to multiple shapes. Some other details which I wished to include were facial hair (I was unsure how to go about it and ran out of time) as well as the curve in my glasses which connects the two lenses (I wanted to make a curved rectangle but could not find how). Moreover, I was unsure of how to present my hair so I just opted for a rounded rectangle which may be perceived as a hat.

In terms of the code itself, I feel that I should have made use of variables in order to make the act of placing the different shapes on the canvas in relation to each other easier. One point that I liked which came as a result of not using variables was that certain features were slightly off centre (e.g mouth, nose) which made the outcome feel more playful and hand drawn.

Assignment 1 – “Self-Portrait” by Sara Al Mehairi

Overview

For this assignment, I initially had a bit of uncertainty about the theme involved with creating a self-portrait using JavaScript. Stick figures seemed like a starting point, but I decided to draw inspiration from the cartoon TV show Gravity Falls. My goal was to capture the same facial structure that made the show so memorable from my childhood, appreciating its cool graphics. So, let me introduce you to Sara, the new character on Gravity Falls!

Challenges

Drawing inspiration from Gravity Falls presented several challenges, particularly in replicating the facial structures of the original characters using only ellipses, rectangles, and triangles. Coordinating the shapes, especially the triangles, definitely tested my patience. Gladly & after several attempts, I sought assistance from Desmos (advanced graphing calculator) to recreate and visualize my canvas in terms of coordinates, I found that pretty helpful!

reflection

My initial intention was to animate multiple objects on the screen, including the sun transforming into a darker color against an ombre background to symbolize sunset (ideally, user-controlled). However, I underestimated the time required for the graphic design itself & hope to implement animations in future projects. While I consider myself familiar with other languages, I wouldn’t claim that p5.js is my expertise. Overall, I found great enjoyment in this project and am proud of the results, particularly the implementation of a simple animation for the “Mukhawar” or Emirati traditional wear. If anyone is interested in the code, you can find it below!

// Welcome to the behind-the-scenes of Sara's self-portrait!

function setup() {
  createCanvas(500, 600);
  frameRate(10);
}

function draw() {
  background(153, 175, 191);
  
  // sun
  noStroke();
  fill(242, 209, 44);
  ellipse(0, 0, 300, 300);
  
  // clouds
  noStroke();
  fill(240);
  
  ellipse(100, 200, 60, 50);
  ellipse(60, 200, 60, 50);
  ellipse(20, 200, 60, 50);
  ellipse(75, 180, 60, 50);
  ellipse(45, 180, 60, 50);
 
  ellipse(500, 170, 70, 60);
  ellipse(460, 170, 70, 60);
  ellipse(420, 170, 70, 60);
  ellipse(485, 140, 70, 60);
  ellipse(445, 140, 70, 60);
  
  ellipse(300, 80, 70, 60);
  ellipse(260, 80, 70, 60);
  ellipse(220, 80, 70, 60);
  ellipse(280, 60, 70, 60);
  ellipse(245, 60, 70, 60);
  
  // ground
  fill(54, 99, 57);
  rect(0, 500, 500, 100);
  
  // neck
  fill(138, 98, 134);
  rect(190, 295, 130, 100);
  
  // hijab
  noStroke();
  fill(138, 98, 134);
  ellipse(245, 300, 190, 140);
  rect(165,180,175,120)
  triangle(325, 158, 410, 480, 300, 680);
   
  // face
  noStroke();
  fill(214, 176, 150);
  ellipse(240, 295, 160, 120);
  rect(175,180,145,120)
  
  //eyelashes
  push();
  stroke(0);
  strokeWeight(2)
  line(160, 240, 200, 255);
  line(170, 230, 200, 255);
  line(295, 240, 200, 255);
  line(285, 230, 200, 255);
  pop();
  
  // eyes
  fill(255);
  stroke(0)
  ellipse(200, 250, 60, 60);
  ellipse(255, 250, 60, 60);
  
  fill(0);
  ellipse(200, 245, 7, 7);
  ellipse(255, 245, 7, 7);
   
  // hair
  noStroke();
  fill(38, 20, 2);
  push();
  rotate(PI/9);
  rect(280, 45, 98, 50);
  rotate(PI/-6);
  rect(135, 200, 80, 30);
  pop();
  
  // hijab 2 (top part)
  fill(138, 98, 134);
  arc(253, 180, 175, 100, PI, TWO_PI);
  rect(165, 185, 10, 30);
  
  // hair 2
  fill(38, 20, 2);
  arc(250, 185, 155, 60, PI, TWO_PI);
  
  // mouth
  fill(255);
  stroke(0);
  arc(230, 305, 60, 37, 0, PI, CHORD);
  
  // hijab 3
  fill(138, 98, 134);
  noStroke();
  rect(166, 177, 9, 30);
  rect(320, 170, 17, 60);

  // eyebrows
  push();
  stroke(21, 19, 19);
  strokeWeight(2);
  noFill();
  arc(195, 215, 35, 10, PI, TWO_PI, OPEN);
  arc(255, 215, 35, 10, PI, TWO_PI, OPEN);
  pop();
  
  // body
  fill(163, 106, 145);
  rect(130, 385, 240, 255, 20, 15, 10, 5);
  push();
  rotate(PI/14);
  rect(210, 343, 65, 225, 20, 15, 10, 5);
  rotate(PI/-9);
  rect(260, 427 , 65, 220, 20, 15, 10, 5);
  pop();
  
  // sleeves
  fill(138, 98, 134);
  triangle(330,440,350,600,340,600);
  triangle(165,440,140,600,130,600);
  
  // dress
  fill(50, 46, 82);
  rect(210, 390, 65, 220, 20, 15, 10, 5);

  // crystal animation
  // inspired by https://editor.p5js.org/nanou/sketches/rJ-EMpxa
  var spot = {
  x:50,
  y: 25,
  };

  var col = {
      r:255,
      g:0,
      b:0,
  };
  
  spot.x= random (215, 270);
  spot.y= random (390, 480);

  noStroke();
  col.r = random (100, 255);
  col.g = (0);
  col.b = random (100, 200);
    
  fill (col.r, col.g, col.b, 120);
  ellipse (spot.x, spot.y, 10, 10);
  
  // neckline
  fill(138, 98, 134);
  arc(240, 384, 100, 80, 0, PI, CHORD);
  
  // mark
  fill(0,95);
  ellipse(280,290,2,2);
  
  // nose
  fill(214, 176, 150);
  stroke(0);
  arc(228, 279, 15, 25, 0, PI/3 + PI);
  
}

// Thank you so much!

 

Assignment 1: Self Portrait

Concept

My p5.js self-portrait is more than simply a picture of my face; it’s a story that illuminates my path to enroll in the “Introduction to Interactive Media” course. The artistic representation of that voyage is this portrait. My conversation with my friends regarding me not being able to enroll in this course until senior spring revolved around how I might be in the hall of fame for not being able to complete my minor because of an introductory course.

The goal of my portrait is to elevate the accomplishment by placing my face on a pedestal and using a lighted stage as the background. It acts as a metaphor for the significant problems I faced since freshmen fall to enroll in this course to complete my minor. Pedestals are typically used to display objects of significant worth or significance. I also thought of adding an interactive element (by clicking the mouse button) that allows me to change the emotions on my face. The face changes from a smile to a laughing face which serves as a cathartic release for the difficulties during the journey.

Sketch

Code 

The code that I am proud of is how I was able to illustrate two different expressions with an easy mouse-click interactive technique. Initially, the value of isLaughing is set to false and when the mouse clicks the value changes to true.

function mouseClicked() {
  // Toggle the laughing state
  isLaughing = !isLaughing; 
}

The drawFace function is the core code for making this sketch possible. This code uses the mouse-toggled laughing boolean variable to show different expressions. The portrait has a lot of facial details that resemble me in real life. The addition of stud-adorned ears, a neck, and a cap enhances the portrait’s authenticity and individuality.

function drawFace(laughing) {
  
  
  // Ears
  fill(skinColor);
  // Left ear   
  ellipse(135, 156, 30, 40);
  // Right ear   
  ellipse(265, 156, 30, 40); 
  
  // Making studs on both ears   
  fill(255,255,255); 
  // stud on left ear   
  ellipse(131, 167, 8, 8);
  fill(255,255,255); 
  // stud on right ear 
  ellipse(269, 167, 8, 8);
  
  // Drawing the neck
  fill(skinColor); 
  rect(175, 206, 50, 60); 
  
  // Drawing the head
  fill(skinColor);
  ellipse(200, 156, 125, 170);
  
  
  // Cap
  fill(0);
  arc(200, 120, 115, 125, PI, TWO_PI, OPEN);
  strokeWeight(10);
  line(150,115,110,115)
  strokeWeight(1);

  if (laughing) {
    // Laughing face
    // Eyes closed
    fill(0);
    // left eye closed    
    ellipse(170, 136, 30, 10); 
    // right eye closed    
    ellipse(230, 136, 30, 10); 

    // Tears
    fill(0, 191, 255);
    // tears from left eye    
    ellipse(165, 151, 10, 25); 
    // tears from right eye
    ellipse(235, 151, 10, 25); 

    // Open mouth - laughing state
    fill(255);
    arc(200, 206, 60, 40, 0, PI, CHORD);

  } else {
    // Smiling Face
    // Eyes
    fill(255);
    // left eye
    ellipse(170, 140, 35, 25); 
    // left eye
    ellipse(230, 140, 35, 25); 
    
    // Pupil     
    fill(0);
    // left eye - pupil  
    ellipse(170, 145, 15, 15); 
    // right eye - pupil 
    ellipse(230, 145, 15, 15); 

    // Mouth
    noFill();
    arc(200, 206, 60, 15, 0, PI); 
  }

  // Nose (same for both faces)
  line(200, 165, 200, 190);
}

Lastly, the concept was achieved by using the pedestal in the center of the room with spotlights showing a significant person.

// Background image of pedestal
function preload(){
  bgImage = loadImage("https://st2.depositphotos.com/1051355/6256/i/450/depositphotos_62569733-stock-photo-illuminated-empty-stage-podiums-for.jpg")
}

Challenges

There were a few challenges that I faced while doing this assignment. Initially, I planned on giving hair to my portrait, however, I was not able to achieve that. So I had to improvise and I made a cap instead.

Another challenge was to determine the x and y coordinates. To solve this issue I printed the cursor’s x and y values in the console using the draw function.

function draw() {
  // finding the value of x and y
  print(mouseX, mouseY)
}

Reflection and Improvements

All the IM courses that I have taken have encouraged me to find meaning behind what I am doing or to show a story. I am happy with the portrait that I have made, it is close to what I look like in real life and also can show the story behind making it.

There is always room for improvement. For example, the portrait may show various emotions depending on which keyboard keys are pressed. Also, the portrait does not have eyebrows, so the eyebrows can follow the mouse when hovering over the portrait.

References

  1. I took a reference from schemecolor.com to use the exact skin color for my portrait.
  2. Another reference was the background image of the pedestal.

Assignment 1 – “Self-Portrait” by Pi Ko

First, below is the p5 js Editor embedding.

In case p5js Editor website is down, below is the recording of working demo on YouTube.

1) 🤔 Conceptualization

As below, I wanted my self portrait to reflect my silhouette, not too realistic but not too cartoony, but something in the style of graphic novels or marvel/DC comics. I am an artist and engineer, and hence, I also would like to include some bells and whistles which define both my art and engineering aspects. Normally for my everyday casual wear, I usually wear the black Chinese long dress – Changshan (長衫), with a red and black Tangzhuang (唐裝) coat on the top, with my long hair properly tied with a red ribbon as below. 

Moreover, I also wanted the portrait to show my personal emblem, the stylized rectangular Greek letter Pi.

As below, my usual real life portraits will feature me wearing my Chinese traditional outfit, with floating glowing code in futuristic HUD (Head-up display), and some equations that either I derived, or some equations I use in my work frequently. And of course the Pi emblem. This concept perfectly “marries the traditions from the past with the technology of the future, and hence justifying my existence as the artistic engineer in 2024 at present.”

While doing this portrait, here are the constraints I would like to adhere to.

  • Implement the portrait purely in p5js without any external libraries, external files in a single sketch.js file – such that when you copy and paste and run, it will run without additional configuration.
  • Follow the rubrics of the course assignment (do not import any existing image or do not use mouse to draw, and must not be realistic – A manga style silhouette is ‘not’ realistic)
  • In addition to the portrait, have items around me that defines me.
2) ⚙️ Technical Plan of Attack & Implementation

Since this is a “self-portrait” it should contain all the elements that gives the viewer a super brief introduction about a fraction of my life. Hence, below are the individual components used for the composition of the portrait.

  • Portrait : I am a manga/anime artist and animator. The entire portrait is implemented using bezierVertex() functions to allow me greater control over the shapes, and obtain the sketchy graphic novel/manga style I want to achieve. This has to combine 1) the line art and the 2) color. Colors are added in between the bezier curves to fill the shape.  Therefore, a component of my portrait would look like
beginShape();
vertex(324, 76);
bezierVertex(323, 76, 322, 76, 321, 75);
...
bezierVertex(324, 76, 324, 76, 324, 76);
endShape(CLOSE);
fill("#010101");
  • Animated Gears : I am a roboticist, and very fond of gears and servos. The gears are nothing but circles with partial opacity, and rectangles rendered on the side of the circles programmatically.
  • Animated Cubes : I am an XR/VR/AR developer, a 3D artist and a mathematician. Hence, I want to do some maths to show some interactive floating 3D cubes around me to symbolize this aspect of my life. Just because p5 js is a 2D canvas technology does not mean I should not attempt my beloved 3D art here. And just because webGL is available in p5  does not mean I have to follow what everyone is doing. Who needs webGL when we can just do some readings in linear algebra, define the vertices of the cubes, and do some matrix multiplication through rotation matrices in 3D space, and project them to the 2D p5js canvas? The matrix multiplication, and the rendering the projection is coded in my single sketch.js file, a snapshot of the code is as follows.
// Rotation matrices for X, Y, and Z axes
let rotationZ = [
  [cos(angleCube), -sin(angleCube), 0],
  [sin(angleCube), cos(angleCube), 0],
  [0, 0, 1],
];

let rotationY = [
  [cos(angleCube), 0, sin(angleCube)],
  [0, 1, 0],
  [-sin(angleCube), 0, cos(angleCube)],
];

let rotationX = [
  [1, 0, 0],
  [0, cos(angleCube), -sin(angleCube)],
  [0, sin(angleCube), cos(angleCube)],
];
  • Personal Emblem : I am a citizen Sinologist, and have always been inspired by East Asian culture. Traditional Japanese clans have their own family emblems called Mon (紋). I also have one myself, visually designed similar to that used by Nakagawa clan. I can draw my emblem by defining the  (x,y) coordinates of my emblem through an array, and letting vertex function loop through the shape.
function drawPiEmblem(x, y, scale) {
  const points = [
    { x: 46.3, y: 72.7 },
    ...
    { x: 73.3, y: 72.7 },
  ];

  beginShape();
  fill("#903C37");
  for (let i = 0; i < points.length; i++) {
    vertex(x + points[i].x * scale, y + points[i].y * scale);
  }
  endShape(CLOSE);
}
  • Quine Code : I am a Computer Engineer, and quite fond of cool code tricks. In Computer Science, a quine is a computer program which takes no input and produces a copy of its own source code as its only output.  Since I usually put code in my real life portraits, I thought it would be cool for my self portrait to print out its own p5js code at my back. The approach is simple, I just copy the first a few lines of my code and just let it print like a terminal. This would have been a lot cooler if I can go under the hood of p5js, and overwrite its event loop + file reading permissions to read its own source code and print it out dynamically, rather than me hardcoding it.
  • Custom font without using a custom font : I also wanted to use a better font, but I do not want to import anything into my single sketch.js implementation, hence I just produced some other good looking unicode characters using Stylish Text Generator (https://lingojam.com/StylishTextGenerator), if it works it works.
  • Falling Pi Digits : My name is Pi, the infinite mathematical constant which never repeats. This means a lot to me since that name allows me to pull out infinite ideas from my brain, which never repeats (but pratically work, and aesthetically beautiful) at will. Hence, in my portrait, the mouse pointer will drop the digits of pi, as a particle system, in a repeated fashion (because you can’t hard code infinite Pi digits)… So, the mouse pointer at time intervals will drop the digits three, point, one, four, one , five , nine, two ….
  • Backpropagation Equations : I am a published machine learning researcher, and deep learning is my default weapon of choice. Therefore, I wanted to honor the basic four equations which allows me to do my everyday work (sorry Maxwell, your equations take the second priority in my heart). Hence, I have the equations floating around me in my portrait.
  • Accompanying music : I am a multi instrumentalist and a composer, and I wanted to give a background music to my portrait. However, since I am not using any external libraries, and I still want to implement a basic metal guitar riff, I ended up defining two oscillators to symbolize the top two guitar strings in dropped D tuning, and hard coding a metal riff  – but only using the simple waveforms 🙁 . I could have done the wave superpositions to simulate the acoustics and distortion pedal signal processing of the electric guitar, but let it be for now.
3) 🎨 Artistic Plan of Attack & Implementation

Vignette : The white background is bland, and as a big fan of Assassin’s Creed Animus Loading Screens, I wanted a pale vignette effect. However, since I am not importing anything, I just loop over the entire canvas and painting each of the background pixels the right intensity and alpha values.

Rule of third placement : A good rule of thumb in visual composition is to divide the entire canvas in three and place the subjects on these lines. My portrait is on the left line. Checklist checked.

Whitespace consideration : I could have added more because this portrait paints a very limited aspect of my life. I could have added more computational chemistry, professional Game Development, martial arts choreography, epidemiology simulation models, Web Dev , Dev Ops and linguistics and so on – but stopped, to keep the whitespace visually clear, I let the majority of dark colors sit on the left side, and right side of the portrait contains the main whitespace.

Mouse Interactivity : Also, I find my self portrait after coding to be very static, so I browsed through old archives of this Intro to IM blogs. My friend Naz did something cool and interactive with the mouse pointer to give a parallax effect, so I ended up stealing her idea from Self-Portrait by Naz (https://editor.p5js.org/iremnaz/sketches/oxRGnv701).

4) 💪 Challenges

There was zero challenge. I became one with the machine, and implemented the entire sketch.js in one sitting in one boring afternoon, sipping Jasmine tea.

5) 💡 Potential Improvements

One tricky thing is how quick my self portrait code runs (on computers which are slow). Since I am generating a lot of objects and doing a lot, I could have refactored my code more to run more smoothly. For instance, for the falling Pi digits, I can implement an Object pool pattern and reuse the previous particles as soon as they are out of frame. But these are just off the top of my head.

As a bonus, through obfuscation and clever syntax formatting, I could have made the source code of the program actually look like my portrait ascii art, just like how this donut generation code is in the shape of a donut (https://www.a1k0n.net/2006/09/15/obfuscated-c-donut.html). But let it be this time.

6) 🖥️ Source code

🖥️ Source code is just a single sketch.js file at : https://github.com/Pi-31415/Intro-To-IM/blob/main/Assignment-1/sketch.js

📖 References :

Rendering a rotating 3D cube in 2D (https://rosettacode.org/wiki/Draw_a_rotating_cube#JavaScript)

Backpropagation Equations (http://neuralnetworksanddeeplearning.com/chap2.html#the_four_fundamental_equations_behind_backpropagation)

Quine (https://cs.lmu.edu/~ray/notes/quineprograms/)

Stylish Text Generator (https://lingojam.com/StylishTextGenerator)

FREQUENCY CHARTS FOR NOTES ON THE GUITAR (https://douglasniedt.com/frequency-chart-for-notes-on-the-guitar.html)

Self-Portrait by Naz (https://editor.p5js.org/iremnaz/sketches/oxRGnv701)

Japanese crest Nakagawake kurusu (https://en.wikipedia.org/wiki/File:Japense_crest_Nakagawake_kurusu.svg)

Note: GPT-4 is utilized in the implementation of the code.

 

Assignment 1 (Self-Portrait) Shereena AlNuaimi

For this assignment, I aimed to incorporate one of my favorite things to do, that instantly fills my entire body with peace and happiness. Watching the sunset. The plan was ideally to make the background more ombre other than fading, however, as it’s my first time using p5js I found it difficult to implement that into my background. For future assignments, I’m hoping to create more interactive projects and master the ombre affect as well as getting more familiar with coding.

let rectWidth;
let rectHeight;
let rectX, rectY;
let eye1X = 170;
let eye2X = 230;
let speed = 8;

function setup() {
  createCanvas(400, 400);
  rectWidth = width/4;
  rectHeight = height/4;
  rectX = 0;
  rectY = height/2;
  angleMode(DEGREES);
}

function draw() {
  background(255, 255, 153, 10);

  //SUNSET BG
  
  rectMode(CENTER); //LIGHT ORANGE TOP
  stroke(255, 204, 0)
  fill(255,204, 0);
  rect(rectX, rectY-120, rectWidth+50, rectHeight+50);
  
  rectMode(CENTER); //D.ORANGE MID
  stroke(255, 153, 0)
  fill(255,153, 0);
  rect(rectX, rectY, rectWidth+50, rectHeight+50);

  rectMode(CENTER); //BOTTOM
  stroke(255, 102, 0)
  fill(255,102, 0);
  rect(rectX, rectY+120, rectWidth+50, rectHeight+50);
  

  
  rectX = rectX + speed;
  
  if (rectX > width){
  rectX = 0;
  }
  
  //hair
  fill(43, 28, 17);
  stroke(0, 0, 0);
  rect(200, 220, 205, 330, 90);
  
  //neck
  fill(240,190, 120);
  stroke(0,0, 0);
  rect(200, 239, 100, 100, 20);
  
  //face
  fill(240,190, 120);
  stroke(0,0, 0);
  ellipse(200, 150, 150, 175);
  
  //nose
  noFill();
  arc(198, 175, 20, 15, 270, 90);
  
  //shirt
  fill(136, 189, 242);
  rect(200, 380, 190, 270, 50);
  
  //bangs
  noStroke();
  fill(43, 28, 17);
  rect(200, 81, 100, 40, 58);
  strokeWeight(1.5);
  
  //right eye
  fill(255);
  ellipse(eye2X, 143, 40, 40)
  
  //left eye
  fill(255);
  ellipse(eye1X, 143, 40, 40);
  
  //right pupil
  fill(51, 0, 0);
  ellipse(eye2X, 143, 15, 20);
  
  //left pupil
  fill(51, 0, 0);
  ellipse(eye1X, 143, 15, 20);
  
  //mouth
  fill(0);
  arc(200, 192, 50, 50, 0 ,180);
  
  
  
}

 

Assignment 1 (Self-Portrait) Shaikha Alkaabi

While working on this assignment, I wanted to recreate my middle school self. I had some experience with Processing so working with P5.js wasn’t so hard to navigate and work with. The thing I struggles with the most in this assignment was the bow. The idea is simple but I never worked with triangles in code before so it was quite difficult trying to figure out the right coordinates. For future assignments I’d like to make my projects much more interactive and fun.

 

function setup() {
  createCanvas(400, 400);
  background(250, 195, 231);
  rectMode(CENTER);
 

}

function draw() {
  
  //Hair
  fill(99, 64, 18, 20);
  rect(200, 235,160, 250, 70);

  //Dress
  fill(232, 133, 12);
  rect(200, 390, 190, 200,60);
    
  //Neck
  fill(250, 207, 150);
  rect(200, 245, 70, 150);

  //Face
  fill(250, 207, 150);
  ellipse(width/2, height/2, 130, 150);
  
  //right eye
  fill(255,255,255);
  ellipse(173, 200, 25, 25);
  //pupil color
  fill(0),
  ellipse(173, 200, 11, 20);

  //left eye
  fill(255,255,255);
  ellipse(226, 200, 25, 25);
  //pupil color
  fill(0);
  ellipse(226, 200, 11, 20);  

  // Eyebrows
  strokeWeight(3);
  noFill();
  //Left eyebrow
  arc(173, 183, 35, 20, PI, TWO_PI); 
  //Right eyebrow
  arc(226, 183, 35, 20, PI, TWO_PI); 
  
  //Nose
  fill(166, 128, 78);
  ellipse(200, 220, 10, 15);

  //Mouth
  fill(255,255,255);
  arc(200, 240, 40, 40, 0, PI + 0, CHORD);
  
  //Bow
  fill(171, 50, 66);
  ellipse(250, 120, 20, 20);
  triangle(240,120,210,90,230,150);
  triangle(260,120,270,90,300,145);

  
  //Earings
  fill(237, 192, 66);
  //right earing
  ellipse(134, 210, 10, 10);  
  //left earing
  ellipse(267, 210, 10, 10);  


}

 

Assignment 1 – “Self-Portrait” by Khalifa AlShamsi

Concept:

My initial Idea was to create a realistic picture of a self-portrait of how I look in the traditional clothes I would wear when I am out.

Reflection and ideas for future work or improvements:

I would say that in the future, I would truly write down the numbers I try when it comes to centering things on the sketch because I kept going around in circles trying to center everything and because I kept placing the same numbers for the different heights and length due to me constantly forgetting what numbers I already tried so It just unnecessarily prolonged the process.

Code Implementation:

I have never used Javascript before, and my understanding of coding is somewhat simple. I had a tough time managing to create hair that looked normal at first, so I tossed that Idea out and wanted to create something else without knowing it was going to be a more complex idea in terms of coding, which was the Ghutra, thinking I would have to create a rectangle and be done with it. However, it did not look like anything close to what I wanted it to be, so I had to use a circle to show that the portrait was wearing it while using three different rectangles layered at different heights so that it shows the way I would personally tie it around my head. But now, looking back at the finished sketch, I would say that I was glad to take the long road of creating a Ghutra to showcase a more realistic portrait of the whole look I have going on.

function setup() {
  createCanvas(400, 400);
  background(255);
}

function draw() {
  
  // Body
  fill("white")// Body base color.
  ellipse(200,420,240,300)// Body base.
  
  // Face
  fill(210, 180, 140); // skin color
  ellipse(200, 200, 160, 200); // head shape
  
  // Ghutra
  fill("white");
  arc(200, 130, 130, 90, PI, 0); 
  rect(125, 120, 150, 30); 
  rect(125, 110, 150, 25);
  rect(125, 130, 150, 10);
  
  // Eyebrows
  fill("black"); 
  rect(150, 160, 40, 10); // left eyebrow
  rect(215, 165, 40, 10); // right eyebrow
  
    // Eyes
  fill("white");
  ellipse(170, 190, 40, 20); // left eye white
  ellipse(230, 190, 40, 20); // right eye white
  fill("black");
  ellipse(170, 190, 20, 20); // left pupil
  ellipse(230, 190, 20, 20); // right pupil
  
  // Mustache
  fill("black");
  arc(200, 248, 80, 30, PI, TWO_PI);

  // Beard
  fill("black");
  arc(200, 245, 140, 120, 0, PI);
  
  // Mouth
  fill("white");
  arc(200, 250, 50, 20, 0, PI);

  // Hair
  fill("white");
  
  noLoop(); // Stops draw loop
}

Assignment 1 Self-portrait

The first assignment was different than any assignments I have done, it was a fun activity to me. I learned a lot from the past two classes and learned more by doing this task, using my skill of self learning and learning something new at the moment when i think of it.

The portrait itself, initially I tried to make a portrait of myself but I thought after that it would be cliche and everybody will do the same. I came up afterwards with the alien head which is an emoji that I always use and everyone knows me remembers me instantly, so it is me in another universe. I tried to make the same shape of the aliens head but It got challenging, and tried to shape the eyes with the big black pupils, with a tiny circle that shows the reflection of the light. Afterwards I got an idea of drawing some stars behind the head, I tried to draw the quad and shape it afterwards to look like a star but I found it hard fixing the dimensions and not the way I wanted it to be. I came up with an idea of making tiny points all over the canvas behind the head, going back to the reference page in P5 website, I created a starry universe by using the dots and with the command random() and made them infinite by using a loop function to create the starry effect.

Through this assignment I learnt a lot and loved the process of doing it. As a freshman I want to improve my self learning skills and this assignment is  helping me achieving this skill that will help me in my future courses throughout my four years at the university.

 

function drawAlien(x, y) {
  // Alien face
  fill(0, 200, 120, 50);
  ellipse(x, y, 100, 110); // Head

  // Eyes
  fill(0);
  ellipse(x - 20, y - 10, 30, 40); // Left eye
  ellipse(x + 20, y - 10, 30, 40); // Right eye

  // Pupils
  fill(255);
  ellipse(x - 29, y -17, 5, 10); // Left pupil
  ellipse(x + 29, y -17, 5, 10); // Right pupil

  // Smiling mouth
  noFill();
  stroke(0);
  strokeWeight(3);
  arc(x, y + 20, 10, 15, 0, PI);
}

 

self portrait: Afra Binjerais

In my first coding project, I decided to represent myself through a unique concept, creating a digital persona that reflects my identity.

I used a triangular shape body to symbolize my abaya and incorporated a head turban, adding personal elements to the visual representation. Choosing lilac as the background, my favorite color, not only adds aesthetic appeal but also creates a connection to my preferences. I took pride in successfully integrating my name into the background and even discovered the possibility of including an emoji through my research, which was a pleasant surprise. Looking ahead, I aspire to advance my coding skills by incorporating more details like hands and feet, aiming for a more realistic depiction of a human figure.

Taking small steps and exploring the possibilities at my own pace is part of my learning journey, and I’m excited about the potential for future improvements in my coding projects.