I first started off with hand sketch:
The hand sketch is then vectorized in Sketch with simple geometric shapes keeping in mind that this will be written with code.
The program is constructed proportions. Every variable is based on the width (w) and height (h) of the canvas. Half way through writing the program, I realized that it would be efficient to be able to visually see the proportions of the screens I am working with, so I quickly wrote a program.
Because the code is based of proportions rather than pixels, I can quickly mirror my facial features with 1-.xx. Just as I leave traces of sketch marks on my drawings, here I’ve chosen to leave the traces of code I’ve used to proportionally construct my drawing.
//
// Supawat Vitoorapakorn
// Svitoora@andrew.cmu.edu
// Section E
//
// Self Portrait of Supawat Vitoorapakorn
// Global
s = .65
var w = 768*(600/768);
var h = 1024*(650/768);
// Face Var
var f_w = (424/768) *w; //face width
var f_h = (553/1024)*h; //face height
// Neck Var
var neck_w = .27;
var neck_y = .75;
var neck_h = .1;
var neck_w2 = .365;
// V-neck Var
var v_x1 = (w/2) - (neck_w/2)*w ;
var v_x2 = (w/2) + (neck_w/2)*w;
var v_x3 = (w/2);
var v_yshift = 0;
var v_y2 = .795*h;
var v_y1 = v_y2+((83/h)*h);
var v_y3 = v_y1
// Color
var SKIN = "#ffe4b2";
var T_SHIRT = "#5C5C5C";
var BLACK = (0,0,0);
var SKIN_GLASS = "#ffe9c1";
var RED = "#ed2024";
var SHADOW = 255*.125;
// MAIN FUNCTION
function setup() {
createCanvas(w,h);
background(255);
rectMode(CORNER);
// Backdrop
fill(0);
noStroke();
noFill();
strokeWeight(1);
fill(216, 216, 216);
rectMode(CORNERS);
rect(w*.015, (.075)*h, w*(1-.015), h*.915);
rectMode(CORNER);
// Neck
noStroke();
fill(SKIN);
rectMode(CORNERS);
rect(w*neck_w2, h*.7, w*(1-neck_w2),h*.8)
rectMode(CORNER);
// Shirt
fill(T_SHIRT);
neck_size = .36;
quad( neck_size*w, .795*h,
(1-neck_size)*w, .795*h,
(1-.015)*w, .915*h,
.015*w, .915*h);
// V_Neck
fill(SKIN)
triangle( v_x1, v_y2, // left
v_x3, v_y1, // mid
v_x2, v_y2); // right
// Neck Shadow
neck_shadowH = (143.9/h)*h;
neck_y = h*.6175;
var n_x1 = w*.5 + (neck_w*w)*.5;
var n_x2 = w*.5 - (neck_w*w)*.5;
var n_x3 = w*.5 + (neck_w*w)*.5;
var n_x4 = w*.5 - (neck_w*w)*.5;
var n_y1 = 0+neck_y;
var n_y2 = 0+neck_y;
var n_y3 = neck_shadowH+neck_y;
var n_y4 = (neck_shadowH-(1/25)*h)+neck_y;
fill(0,0,0,SHADOW)
quad( n_x1,n_y1,
n_x2,n_y2,
n_x4,n_y4,
n_x3,n_y3
);
// Face
noStroke();
fill(SKIN);
ellipse(w*.5,h*.475,f_w,f_h);
// Hair
fill(BLACK);
h_y = h*.33
h_h = -h*.175
var h_x1 = w*.5 + (neck_w*w)*.9; // Right Base
var h_x2 = w*.5 - (neck_w*w)*.9; // Left Base
var h_x3 = w*.5 + (neck_w*w)*1.33; // Right Tip
var h_x4 = w*.5 - (neck_w*w)*.77; // Left Tip
var h_y1 = h_y;
var h_y2 = h_y+20;
var h_y3 = h_y+h_h; // Right Tip
var h_y4 = h_y+h_h*.9; // Left Tip
quad( h_x1,h_y1,
h_x2,h_y2,
h_x4,h_y4,
h_x3,h_y3
);
// Facial Features
// Facial Features Left
var glass_size = .20;
var nose_bridge = .13;
var eye_size = .04;
var eye_y = .51;
var side = 1; //1 for left; -1 for right
// Glasses Bottom Shadow
var shadow_yshift = .015;
noStroke();
rectMode(CORNERS);
fill(0,0,0,SHADOW);
rect( .223*w, side*((.485+shadow_yshift)*h),
(1-.223)*w, (eye_y+shadow_yshift)*h);
// Glass Frame
fill(SKIN_GLASS);
strokeWeight(10);
stroke(BLACK);
strokeJoin(ROUND);
arc( w*(.5-nose_bridge), h*(.5), //+nose bridge to flip
w*glass_size, w*glass_size,
0-(1/15*PI), PI+(1/15*PI),
CHORD);
// Eyes Round
fill(BLACK);
noStroke();
arc( w*(.5-nose_bridge), h*(eye_y), //+nose bridge to flip
w*eye_size, w*eye_size,
0-(1/15*PI), PI+(1/15*PI),
CHORD);
// Eyes Line
strokeWeight(5);
stroke(BLACK);
strokeCap(SQUARE);
line( (.5-nose_bridge-.05)*w,h*(eye_y-.001),
(.5-nose_bridge+.05)*w,h*(eye_y-.001));
// Glasses Side
rectMode(CORNERS);
strokeJoin(MITER);
rect( side*(.223*w),side*(.485*h),
.27*w, eye_y*h);
rectMode(CORNER);
rectMode(CORNER);
// Top Shadow
strokeWeight(15);
stroke(0,0,0,SHADOW);
line( (side*.28)*w, .48*h,
(side*.46)*w, .48*h);
// Eyebrow
var e_x1 = (side*.27)*w;
var e_y1 = .46*h;
var e_x2 = (side*.335)*w;
var e_y2 = .44*h;
var e_x3 = (side*.45)*w;
var e_y3 = .45*h;
// strokeWeight(7.5);
stroke(BLACK);
line( e_x1, e_y1,
e_x2, e_y2 );
line( e_x2-(3*side),e_y2,
e_x3, e_y3 );
// Facial Features Right
var side = -1; //1 for left; -1 for right
// Glass Frame
fill(SKIN_GLASS);
strokeWeight(10);
stroke(BLACK);
strokeJoin(ROUND);
arc( w*(.5+nose_bridge), h*(.5), //+nose bridge to flip
w*glass_size, w*glass_size,
0-(1/15*PI), PI+(1/15*PI),
CHORD);
// Eyes Round
fill(BLACK);
noStroke();
arc( w*(.5+nose_bridge), h*(eye_y), //+nose bridge to flip
w*eye_size, w*eye_size,
0-(1/15*PI), PI+(1/15*PI),
CHORD);
// Eyes Line
strokeWeight(5);
stroke(BLACK);
strokeCap(SQUARE);
line( (.5+nose_bridge-.05)*w,h*(eye_y-.001),
(.5+nose_bridge+.05)*w,h*(eye_y-.001));
// Glasses Side
rectMode(CORNERS);
strokeJoin(MITER);
rect( (1-.223)*w,.485*h,
(1-.27)*w, eye_y*h);
rectMode(CORNER);
//Cast Shadow
rectMode(CORNER);
// Top Shadow
strokeWeight(15);
stroke(0,0,0,SHADOW);
line( (1-.28)*w, .48*h,
(1-.46)*w, .48*h);
// Eyebrow
var e_x1 = (1-.27)*w;
var e_y1 = .46*h;
var e_x2 = (1-.335)*w;
var e_y2 = .44*h;
var e_x3 = (1-.45)*w;
var e_y3 = .45*h;
// strokeWeight(7.5);
stroke(BLACK);
line( e_x1, e_y1,
e_x2, e_y2 );
line( e_x2-(3*side),e_y2,
e_x3, e_y3 );
// Facial Features Symetrical
// Glasses Side
var side = 1;
noStroke();
fill(BLACK);
rectMode(CORNERS);
strokeJoin(MITER);
rect( (.5-.03)*w, (.485*h),
(.5+.03)*w, eye_y*h);
rectMode(CORNER);
// Nose .
var nose_y = .63;
var nose_width = .025
strokeWeight(7.5)
stroke(BLACK);
line( (.5-nose_width)*w, nose_y*h,
(.5+nose_width)*w, nose_y*h);
// Mouth .
var mouth_y = nose_y+.05;
var mouth_width = .035*1.5
strokeWeight(7.5)
stroke(BLACK);
line( (.5-mouth_width)*w, mouth_y*h,
(.5+mouth_width)*w, mouth_y*h);
// Mouth Shadow
var mouth_shadow_y = nose_y+.05+.02;
var mouth_shadow_width = .035*.75
strokeWeight(7.5)
stroke(0,0,0,25);
line( (.5-mouth_shadow_width)*w, mouth_shadow_y*h,
(.5+mouth_shadow_width)*w, mouth_shadow_y*h);
// Hair Side
strokeWeight(0);
noStroke();
fill(0,0,0);
quad (w*.275, h*.34,
w*.24, h*.45,
w*.215, h*.47,
w*.20, h*.37);
quad (w*(1-.275), h*.32,
w*(1-.24), h*.45,
w*(1-.215), h*.47,
w*(1-.2), h*.35);
}
// Creates Mouse Guider
function draw() {
setup();
noStroke();
fill(255,240,0,255*.30);
ellipse(mouseX, mouseY, 200, 200);
var X = (mouseX/w).toFixed(3);
var Y = (mouseY/h).toFixed(3);
var XY = str("("+X+","+Y+")");
fill(RED);
textSize(24);
strokeWeight(1);
text(XY,mouseX,mouseY);
}