A Self-Portrait Using Processing

Overview:

For this first assignment, I tried to utilize the principles learned in class to best create a portrait of myself using Processing. This involved the use of  Processing’s 2D Primitive shapes, including quads, triangles, arcs, lines and ellipses. I tried to stay within the bounds of what we have done thus far, but made extensive use of the basic coding principles we have covered including the use of variables to accomplish scaling and parameter specification.

Process:

For this assignment I took the warm up exercise we finished in class and continued on to make it an entire portrait. I first chose which shapes I wanted to utilize to compose a feature such as a nose or a mouth, and placed them in a 640×480 canvas. Once I was happy with how the face looked at this point I replaced everything with variables that could be easily adjusted to tweak certain features such as size or placement, as well as make it easily scalable to any 4×3 resolution just by changing the canvas size.

Code: 

In my code I made sure to divide everything out into clear sections with comments so that I could easily find and tweak features as needed. This allowed me to easily manipulate what I had already done. You will note that I initialize all my variables before running anything. These parameters define the face and could easily be tweaked to make any sort of face, not just one that looks like me! This gives futures possibilities for a UI that would allow a simple character creature.

Once all my parameters were defined I went ahead and created a larger 4×3 canvas, set certain position variables, and then continued on to draw my face with the parameters defined initially. I took advantage of how Processing layers shapes to create features such as the shirt, neck line, and ears with far less math by letting other features simple draw over the top as necessary instead of needing more complex shapes.

//Position variables
int centerX;
int centerY;
float faceScale = 1;

//Face Parameters
float faceWidth = 200;
float faceHeight = 250;

float neckHeight = 330; //arc from center
float neckWidth = 100; //arc from center

float pocketHeight = 80;
float pocketWidth = 40;
float pocketPosX = 60;  //relative to center of face
float pocketPosY = 180;  //relative to center of face

float earHeight = 0;  //0 is center of face
float earLength = 20;
float earWidth = 10;

float eyeScale = 1;
float eyeHeight = 20;  //0 is center of face
float eyeDistance = 30; //0 is pupil aligned with center

float mouthHeight = 30;  //0 is not center, center or curve
float mouthWidth = 100;
float mouthThickness = 110;

float hairLine = 70; // 0 is center
float hairHeight = 60;
float hairSweep = -30;
float sideBurnDepth = 20;
float sideBurnHeight = 60;

void setup() {
  size(640, 480); //!!Maintain 4x3 for right aspect ratio!! (640, 480), (1280, 960) etc..
  //size(1280, 960); //!!Maintain 4x3 for right aspect ratio!! (640, 480), (1280, 960) etc..
  centerX = width/2;
  centerY = height/2;
  faceScale = width/640;
}

void draw() {

  background(255);  //white
  //RGB
  stroke(0);

  //line(centerX, centerY, width, height); //draw line from center to bottom right corner

  //Shirt
  fill(#006994);  //Shirt Color
  triangle(centerX, centerY, centerX - faceScale*160, height, centerX + faceScale*160, height);
  fill(255, 233, 208);
  arc(centerX, centerY, faceScale*neckWidth, faceScale*neckHeight, 0, PIE, CHORD);//neckline
  fill(159,226,191);
  arc(centerX + faceScale*pocketPosX, centerY + faceScale*pocketPosY, faceScale*pocketWidth, faceScale*pocketHeight, 0, PIE, CHORD);//Pocket

  //Ears
  fill(255, 233, 208);
  ellipse(centerX - faceScale*faceWidth/2, centerY + faceScale*earHeight, faceScale*earWidth, faceScale*earLength);
  ellipse(centerX + faceScale*faceWidth/2, centerY + faceScale*earHeight, faceScale*earWidth, faceScale*earLength);
  

  //Face
  fill(255, 233, 208);
  ellipse(centerX, centerY, faceScale*faceWidth, faceScale*faceHeight); //(width, height, diameter)

  //EYES
  //Eyelash
  noFill();
  arc(centerX + faceScale*eyeDistance, centerY - faceScale*eyeHeight - 8, eyeScale*faceScale*30, eyeScale*faceScale*15, PI+QUARTER_PI, TWO_PI-QUARTER_PI);
  arc(centerX - faceScale*eyeDistance, centerY - faceScale*eyeHeight - 8, eyeScale*faceScale*30, eyeScale*faceScale*15, PI+QUARTER_PI, TWO_PI-QUARTER_PI);
  noStroke();
  //White Part
  fill(255);
  ellipse(centerX + faceScale*eyeDistance, (centerY - faceScale*eyeHeight), eyeScale*faceScale*30, eyeScale*faceScale*15); //(width, height, diameter)
  ellipse(centerX - faceScale*eyeDistance, (centerY - faceScale*eyeHeight), eyeScale*faceScale*30, eyeScale*faceScale*15); //(width, height, diameter)
  // Blue eyes
  fill(0, 0, 255);
  ellipse(centerX + faceScale*eyeDistance, (centerY - faceScale*eyeHeight), eyeScale*faceScale*15, eyeScale*faceScale*15); //(width, height, diameter)
  ellipse(centerX - faceScale*eyeDistance, (centerY - faceScale*eyeHeight), eyeScale*faceScale*15, eyeScale*faceScale*15); //(width, height, diameter)
  //Outline to see pupil
  fill(255);
  ellipse(centerX + faceScale*eyeDistance, (centerY - faceScale*eyeHeight), eyeScale*faceScale*6, eyeScale*faceScale*6); //(width, height, diameter)
  ellipse(centerX - faceScale*eyeDistance, (centerY - faceScale*eyeHeight), eyeScale*faceScale*6, eyeScale*faceScale*6); //(width, height, diameter)
  //Pupil
  fill(0);
  ellipse(centerX + faceScale*eyeDistance, (centerY - faceScale*eyeHeight), eyeScale*faceScale*5, eyeScale*faceScale*5); //(width, height, diameter)
  ellipse(centerX - faceScale*eyeDistance, (centerY - faceScale*eyeHeight), eyeScale*faceScale*5, eyeScale*faceScale*5); //(width, height, diameter)
  
  
  //Nose
  stroke(0);
  line(centerX, centerY, centerX + faceScale*20, centerY + faceScale*30);
  line(centerX, centerY + faceScale*30, centerX + faceScale*20, centerY + faceScale*30);
  
  //Mouth
  stroke(191, 112, 104);
  fill(255);
  strokeWeight(faceScale*8);
  arc(centerX, centerY + faceScale*mouthHeight, faceScale*mouthWidth, faceScale*mouthThickness, QUARTER_PI, PI-QUARTER_PI, CHORD);
  strokeWeight(faceScale*1);
  
  //Hair
  noStroke();
  fill(227,204,136);
  quad(centerX + faceScale*faceWidth/2, centerY - faceScale*hairLine, centerX - faceScale*faceWidth/2, centerY - faceScale*hairLine, centerX - faceScale*faceWidth/2 + faceScale*hairSweep, centerY - faceScale*hairLine - faceScale*hairHeight, centerX + faceScale*faceWidth/2 + faceScale*hairSweep, centerY - faceScale*hairLine - faceScale*hairHeight);
  triangle(centerX + faceScale*faceWidth/2, centerY - faceScale*hairLine, centerX + faceScale*faceWidth/2 - faceScale*sideBurnDepth, centerY - faceScale*hairLine, centerX + faceScale*faceWidth/2, centerY - faceScale*hairLine + faceScale*sideBurnHeight);
  triangle(centerX - faceScale*faceWidth/2, centerY - faceScale*hairLine, centerX - faceScale*faceWidth/2 + faceScale*sideBurnDepth, centerY - faceScale*hairLine, centerX - faceScale*faceWidth/2, centerY - faceScale*hairLine + faceScale*sideBurnHeight);
}

 

Going Forward:

As mentioned previously, there is a lot more that could be done with this project. The goal was to use simplistic shapes and drawing techniques to make the best portrait we could. Using future techniques such as loops I would create more complex shapes such as eye lashes, or control statements to create a UI. This would all allow greater customizability overall.

Leave a Reply