Alec Albright – Project 02 – Variable Face

sketch

// ALec Albright
// Section B
// aalbrigh@andrew.cmu.edu
// Project 02

var hairHeight = 130;
var hairWidth = 365;
var hairRed = 230;
var foreheadH = 320;
var foreheadW = 160;
var foreheadBlue = 255;
var lowerRed = 240;
var noseBlue = 255;
var leftEyeY = 175;
var rightEyeY = 200;
var leftPupilX = 230;
var rightPupilX = 340;
var jawWeight = 30;

function setup(){
    height = 480
    width = 640
    createCanvas(width, height);
    angleMode(DEGREES);
}

function draw(){
    background("blue");
    // forehead
    fill(0, 255, foreheadBlue);
    noStroke();
    rect(140, 120, foreheadH, foreheadW);

    // lower half of face
    noStroke();
    fill(lowerRed, 0, 200);
    quad(125, 270, 475, 270, 370, 470, 250, 470);

    // mouth
    fill("black");
    arc(300, 370, 100, 40, -10, 170, PIE);

    // nose
    fill(153, 51, noseBlue);
    triangle(300, 230, 325, 320, 300, 330);

    // eyes
    fill("white");
    ellipse(240, leftEyeY, 45, 80);
    ellipse(350, rightEyeY, 60, 95);
    fill('black');
    ellipse(leftPupilX, leftEyeY + 15, 15, 30);
    ellipse(rightPupilX, rightEyeY + 20, 23, 40);

    // hair
    fill(hairRed, 130, 0);
    rect(120, 0, hairWidth, hairHeight, 160, 40, 60, 0);

    // jaw
    stroke('yellow');
    strokeWeight(jawWeight);
    line(150, 320, 250, 470);
    stroke("red");
    line(200, 445, 435, 445);
    stroke('limegreen');
    line(450, 295, 350, 505);
}

function mousePressed(){
    hairHeight = random(110, 150);
    hairWidth = random(335, 395);
    hairRed = random(0, 255);
    foreheadBlue = random(0, 255);
    foreheadH = random(300, 340);
    foreheadW = random(140, 180);
    lowerRed = random(0, 255);
    noseBlue = random(0, 255);
    leftEyeY = random(145, 205);
    rightEyeY = random(160, 240);
    leftPupilX = random(220, 260);
    rightPupilX = random(320, 360);
    jawWeight = random(10, 50);
    clear();
}

At the beginning of the process, I struggled to find what variables I would like to create, and what facial features I wanted to generate. I eventually wound up deciding that I wanted to change most structural aspects within constraints, a few color aspects, and absolutely let the pupils of the eyes cross if randomly selected to do so. Thus, I began toying with various features, dimensions, and colors until the result was a satisfying range of diversity in faces, based on my previous project.

Katrina Hu – Looking Outwards – 02

Growing Objects

Laplacian Zoetrope, 3D-printed using ABS plastic

The exhibition “Growing Objects,” designed by Jessica Rosencrantz in 2014, replicates natural growth processes using simulations and 3D printed sculptures. The piece is very effective at replicating the structural patterns in nature. I admire the complexity and accuracy of the work.

The algorithm used to generate these works of art are made by using scientific theories and models of natural pattern formation. It is very successful in allowing viewers to visualize the complex growth processes that occur in nature. The project also aims to encourage viewers to think about new ways that design and growth can influence the environment in the future.

Julia Nishizaki – Looking Outwards – 02

A piece from Marius Watz’s KBG series, this particular image depicts the music of Radka Toneff

Marius Watz (http://mariuswatz.com/) is a Norwegian artist based in New York and Oslo, who works through generative software processes. He has a wide variety of works, some of which deal in data visualization, and others which result in physical, 3D printed pieces. Watz is known for his vibrant colors and geometric forms.

The works that I chose to write about are a part of Marius Watz’s KBG series. This series was created for the Kongsberg Jazz Festival in 2010, an international jazz festival held annually in Kongsberg, Norway. I found this series particularly interesting, as Watz selected five classic and contemporary jazz tracks, by Radka Toneff, Atomic, Sonny Rollins, Håkon Kornstad and Røyksopp, and created five visual interpretations of the music. According to his website, he used Fast Fourier Transform (FFT) analysis of the sound as his data input.

I particularly admire this project because of Marius Watz’s use of color and dynamic motion to capture the fun, vibrant, and wide ranging tones and feelings of jazz. Even though these images were mainly used on posters and documentation that wasn’t moving, the geometric and dynamic nature of the forms still draw you in and engage you in a similar way to how music would, giving the audience a sense of what to expect at this festival.

Watz’s work as visuals for the Kongsberg Jazz Festival, invitation for commission and all print design by Anders Bergesen / Superultraplus

Nawon Choi— Project-02 Variable Face

nawonc-variable-face

// Nawon Choi
// Section C
// nawonc@andrew.cmu.edu
// Project-02 Variable Faces

var sushiX = 233;
var sushiType = "egg";
var browHeight = 147;
var browAngle = 0;
var eyeballSize = 33;
var eyeSize = 1.5;


function setup() {
    createCanvas(640, 480);
    background(220);  
}

function draw() {
    // background
    noStroke();
    fill("#E3CBC8");
    rect(0, 0, 640, 250); 

    // hair
    noStroke();
    fill("#6A6159");
    ellipse(304, 250, 394, 500);

    noStroke();
    fill("#6A6159");
    ellipse(382, 249, 302, 465);

    // head
    noStroke();
    fill("#F2E3C2");
    ellipse(325, 236, 356, 423);

    // fringe
    noStroke();
    fill("#6A6159");
    quad(124, 182, 270, 125, 373, 30, 198, 61);

    noStroke();
    fill("#6A6159");
    triangle(223, 57, 294, 16, 373, 30);

    // eyebrows
    strokeWeight(10);
    stroke("#8F847B");
    noFill();
    beginShape();
    curveVertex(183, browHeight + browAngle);
    curveVertex(183, browHeight + browAngle);
    curveVertex(213, browHeight - browAngle);
    curveVertex(278, browHeight + browAngle);
    curveVertex(278, browHeight + browAngle);
    endShape();

    strokeWeight(10);
    stroke("#8F847B");
    noFill();
    beginShape();
    curveVertex(365, browHeight + browAngle);
    curveVertex(365, browHeight + browAngle);
    curveVertex(430, browHeight - browAngle);
    curveVertex(460, browHeight + browAngle / 2);
    curveVertex(460, browHeight + browAngle / 2);
    endShape();

    // eyes
    noStroke();
    fill("#ffffff");
    ellipse(224, 193, 57 * eyeSize, 46 * eyeSize);

    noStroke();
    fill("#ffffff");
    ellipse(417, 193, 57 * eyeSize, 46 * eyeSize);

    // eyeballs
    var leftEye = 224;
    var rightEye = 417;
    var eyeHeight = 200;
    var sushiCenter = sushiX + 88;

    if (sushiCenter < 201) {
        leftEye = 201,
        rightEye = 394;
    } else if (sushiCenter >= 201 & sushiCenter <= 225) {
        leftEye = sushiCenter,
        rightEye = 394;
    } else if (sushiCenter > 225 & sushiCenter < 394) {
        leftEye = 240,
        rightEye = 394;
    } else if (sushiCenter >= 394 & sushiCenter <= 418) {
        leftEye = 240,
        rightEye = sushiCenter;
    } else {
        leftEye = 240,
        rightEye = 418;
    }

    noStroke();
    fill("#6A6159");
    ellipse(leftEye, eyeHeight, eyeballSize, eyeballSize);

    noStroke();
    fill("#6A6159");
    ellipse(rightEye, eyeHeight, eyeballSize, eyeballSize);

    noStroke();
    fill("#FAFAFA");
    ellipse(leftEye-4, eyeHeight-4, 12, 12);

    noStroke();
    fill("#FAFAFA");
    ellipse(rightEye-4, eyeHeight-4, 12, 12);

    // table
    noStroke();
    fill("#AA827C");
    rect(0, 250, 640, 134);

    noStroke();
    fill("#9B736D");
    rect(0, 384, 640, 30);

    noStroke();
    fill("#E1ACA4");
    rect(0, 414, 640, 86);
    
    // rice
    noStroke();
    fill("#F3EEE9");
    rect(sushiX, 250, 175, 80, 29);

    if (sushiType == 'egg'){
        // egg
        noStroke();
        fill("#F2BD39");
        rect(sushiX-20, 224, 214, 53, 7);

        noStroke();
        fill("#F8D683");
        rect(sushiX-20, 224, 214, 20, 7);

        // seaweed
        noStroke();
        fill("#424944");
        rect(sushiX+72, 220, 30, 24);

        noStroke();
        fill("#27312B");
        rect(sushiX+72, 244, 30, 33);

        noStroke();
        fill("#151916");
        rect(sushiX+72, 277, 30, 53);
    } else if(sushiType == 'salmon'){
        // salmon
        noStroke();
        fill("#EC9326");
        rect(sushiX-20, 224, 214, 53, 7);

        var space = 32;
        var sushiY = sushiX + 19;

        strokeWeight(10);
        stroke('#F6CCAF');
        line(sushiX, 229, sushiY, 272);

        strokeWeight(10);
        stroke('#F6CCAF');
        line(sushiX + space, 229, sushiY + space, 272);

        strokeWeight(10);
        stroke('#F6CCAF');
        line(sushiX + space * 2, 229, sushiY + space * 2, 272);

        strokeWeight(10);
        stroke('#F6CCAF');
        line(sushiX + space * 3, 229, sushiY + space * 3, 272);

        strokeWeight(10);
        stroke('#F6CCAF');
        line(sushiX + space * 4, 229, sushiY + space * 4, 272);

        strokeWeight(10);
        stroke('#F6CCAF');
        line(sushiX + space * 5, 229, sushiY + space * 5, 272);
    } else if(sushiType == 'tuna') {
        // tuna
        noStroke();
        fill("#F2464A");
        rect(sushiX - 20, 224, 214, 53, 7);

        var space = 30;
        var sushiY = sushiX + 17;

        strokeWeight(5);
        stroke('#FFA2A9');
        line(sushiX + 35 - space, 229, sushiY - space, 272);

        strokeWeight(5);
        stroke('#FFA2A9');
        line(sushiX + 35, 229, sushiY, 272);

        strokeWeight(5);
        stroke('#FFA2A9');
        line(sushiX + space + 35, 229, sushiY + space, 272);

        strokeWeight(5);
        stroke('#FFA2A9');
        line(sushiX + space * 2 + 35, 229, sushiY + space * 2, 272);

        strokeWeight(5);
        stroke('#FFA2A9');
        line(sushiX + space * 3 + 35, 229, sushiY + space * 3, 272);

        strokeWeight(5);
        stroke('#FFA2A9');
        line(sushiX + space * 4 + 35, 229, sushiY + space * 4, 272);

        strokeWeight(5);
        stroke('#FFA2A9');
        line(sushiX + space * 5 + 35, 229, sushiY + space * 5, 272);
    }

}

function mousePressed() {
    // variables are reassigned when user clicks
    let sushis = ['egg', 'salmon', 'tuna']
    floats = [1.0, 1.1, 1.2, 1.3, 1.4, 1.5];
    colors = ['#6A6159', '#c795b5', '#1d3f75', '#c9b75b', '#cc7a4e', '#6d1873'];
    sushiX = random(38, 430);
    sushiType = random(sushis);
    eyeballSize = random (23, 43);
    eyeSize = random (floats);
    browHeight = random(137, 160);
    browAngle = random(0, 10);


}

I made three different kinds of sushi and made them correlate to different string variables, “egg”, “salmon”, and “tuna”. I also tried to make the position of the eyes correspond to the location of the sushi so that the eyes would follow the sushi. It was fun playing around with different variables to see what types of expressions could be made just by switching around different values.

I showed this to a friend and they mentioned that it kind of looks like sushi going along a conveyor belt!

Sean Leo-Project 02-Variable Faces

sketch

//Sean B. Leo
//sleo@andrew.cmu.edu
//Section C
//Project_02

var eyeSize = 20;
var pupil = 10;
var faceWidth = 100;
var faceHeight = 150;
var red = ("red");
var green = ("green");
var blue = ("blue");
var r1 = 255;
var g1 = 255;
var b1 = 255;
var r2 = 255;
var g2 = 255;
var b2 = 255;
var A = 20;
var B = 40;
var C = 1;

function setup() {
    createCanvas(600, 500);
}
 
function draw() {
  background(red, green, blue);
  let c = color(255, 255, 255);
  
   //body
  fill(r2, g2, b2);
  ellipse(width/2, height/2 + faceHeight, faceWidth + (faceWidth/2), faceHeight + (faceHeight/2));
  //ellipse((width / 2) + faceWidth, (height / 2) + faceHieght, faceWidth * 2, faceHeight * 2);
  
  //head  
  fill(r1, g1, b1),
  ellipse(width / 2, height / 2, faceWidth,  faceHeight);


  //eyes  
  fill(255);
  var eyeHeightLX = (height/2);
  var eyeHeightRX = (height/2);
  var eyeLX = width / 2 - faceWidth * 0.25;
  var eyeRX = width / 2 + faceWidth * 0.25;
    ellipse(eyeLX, height / 2, eyeSize, eyeSize);
    ellipse(eyeRX, height / 2, eyeSize, eyeSize);
  
  //pupils
  fill(0);
    ellipse(eyeLX, eyeHeightLX, pupil, pupil);
    ellipse(eyeRX, eyeHeightRX, pupil, pupil);
  
  //eyebrows
  {strokeWeight(3);
   var eyeBrowLH1 = eyeHeightLX-pupil*2;
   var eyeBrowLH2 = eyeHeightLX-pupil*C;
   var eyeBrowRH1 = eyeHeightRX-pupil*C;
   var eyeBrowRH2 = eyeHeightRX-pupil*2;
  line(eyeLX-pupil, eyeBrowLH1, eyeLX+pupil, eyeBrowLH2);
  line(eyeRX-pupil, eyeBrowRH1, eyeRX+pupil, eyeBrowRH2);
  }
  //mouth
  fill(0);
  var mouthHeight=height/2 + faceHeight *.30;
  ellipse(width/2, mouthHeight, B, 20);
  
  //nose
  fill(r1, g1, b1);
  arc(width/2, height/2 + faceHeight*.09, A, A, C, PI + QUARTER_PI, OPEN);
  
  
}
 
function mousePressed() {
  red = random(0,255);
  green = random(0, 255);
  blue = random(0, 255);
  r1 = random(20, 255);
  g1 = random(20, 255);
  b1 = random(20, 255);
  r2 = random(0, 255);
  g2 = random(0, 255);
  b2 = random(0, 255);
  A = random(1,30);
  B = random(1,40);
  C = random(1,3);
  faceWidth = random(75, 250);
  faceHeight = random(75, 250);
  eyeSize = random(10, 30);
  pupil = random(7, 12);
}

A big part of figuring out this project was trying to wrap my head around what was spatially dependent on what. It was easier to think of things modularly; if the eyebrow is linked to the eye and if the eye is linked to the head, if the head changes everything else will follow.

Hyejo Seo-Project-02-Variable-Face


sketch

Are you forgetting something? 

Oh, yes! 

/*
Hyejo Seo
Section A
hyejos@andrew.cmu.edu
Project-02-Variable-Face
*/


var faceW = 300;
var faceH = 250;
var eyeH = 150;
var eyeW = 110;
var ex1 = 190;
var ex2 = 290;
var r = 240; 
var g = 72;
var b = 75; 


function setup() {
    createCanvas(480,640);
    
}

function draw() {
    background(47, 50, 47);
    //face
    fill(r, g, b);
    noStroke();
    ellipse(240, 530, faceW, faceH);
    // eyes
    fill(255);
    noStroke();
    ellipse(300, 520, eyeW, eyeH);
    ellipse(180, 520, eyeW, eyeH);
    // pupils
    fill(0);
    ellipse (295, 470, eyeW/2 - 20, eyeH/2 - 40);
    ellipse (185, 470, eyeW/2 - 20, eyeH/2 - 40);
    //exclamation mark
    noFill();
    stroke(221, 249, 193);
    strokeWeight(10);
    quad(ex1, 100, ex2, 100, 245, 250, 235, 250);
    circle(240, 320, 50);
}

function mousePressed() {
    faceW = random(150, 400);
    faceH = random(150, 300);
    eyeW = random(90, 130);
    g = random(0, 80);
    b = random(0, 100);
    ex1 = random(100, 190);
    ex2 = random(290,380);
    
}

Min Ji Kim Kim – Project 02 – Variable-Face


sketch

I had so much fun doing the project this week. The hardest part was trying to figure out how to use the if statement to get the single or double eye as well as understanding how to manipulate variables for the mousePressed function.

/*
Min Ji Kim Kim
Section-A
mkimkim@andrew.cmu.edu
Project-02
*/

//variables
var mouthHeight = 330;
var mouthWidth = 80;
var irisSize = 25;
var pupilSize = 12;
var headColor = 231;
var overallsColor = 130;
var eyeNumber = 2;


function setup() {
    createCanvas(640, 480);
    background(210, 210, 255);
}

function draw() {
    noStroke();
    //head
    fill(254, headColor, 81);
    rect(210, 150, 220, 300, 100, 100, 0, 0);

    //goggle band
    fill(47, 47, 41);
    rect(210, 235, 220, 20);

    //Number of eyes
    if (eyeNumber >= 2){
        //two eyes
        //goggles
        fill(201, 208, 202);
        circle(280, 245, 90);
        circle(360, 245, 90);
        //eyes
        fill(255);
        circle(280, 245, 70);
        circle(360, 245, 70);
        //iris
        fill(102, 45, 19);
        circle(280, 245, irisSize);
        circle(360, 245, irisSize);
        //pupils
        fill(0);
        circle(280, 245, pupilSize);
        circle(360, 245, pupilSize);

    } else {
        //one eye
        //goggle
        fill(201, 208, 202);
        circle(320, 245, 90);
        //eye
        fill(255);
        circle(320, 245, 70);
        //iris
        fill(102, 45, 19);
        circle(320, 245, irisSize);
        //pupil
        fill(0);
        circle(320, 245, pupilSize);

    }

    //overalls
    strokeWeight(1.5);
    stroke(172, 121, 77);
    fill(53, 96, overallsColor);
    rect(210, 400, 220, 50);

    //mouth
    fill(255);
    strokeWeight(3);
    stroke(200, 117, 0);
    arc(320, mouthHeight, mouthWidth, 80, 0, PI, CHORD);

}

function mousePressed(){
    // when the user clicks, these variables are reassigned
    // to random values within the specifed ranges.
    mouthHeight = random(300, 340);
    mouthWidth = random(30, 100);
    irisSize = random(20, 30);
    pupilSize = random(8, 16);
    headColor = random(180, 240);
    overallsColor = random(100, 250);
    eyeNumber = random(1,3);

}

Min Ji Kim Kim – Looking Outwards – 02


Quantum Fluctuations video visualizing the different events of proton collision. 

Quantum Fluctuations is a generative art piece created by digital artist Markos Kay in 2016. Working together with scientists at the CERN research institute in Geneva, Kay took the hard to understand quantum world, and used art and technology to visually display proton collision. Utilizing particle simulations from the laboratory, Kay was able to virtually paint the different stages involved in this complicated process.

Visual representation of Hadron Decay, the last stage of proton collision.

I was attracted to this art piece because of the chaotic, complex yet beautiful combination of motion, colors and sound. These different components come together to create a synergistic effect, really reflecting and mirroring the intricate process of proton collision. I really admire how Kay was able to use generative art to visualize what otherwise is not detectable to the human eye, and do so in a very aesthetically pleasing way. Looking at this artwork made me feel like I was inside the proton collision itself.

Ghalya Alsanea – Looking Outward-02

Animal Imagination by LIA

artwork consisting of 50 unique iteration

Animal Imagination, created  in 2018, is a collection of 50 unique artworks created by software artist LIA. Find her work here

Taking references from nature and animals, the works present different geometric and abstract shapes, generative patterns and colors, which evolve uniquely in each of the two-minute digital paintings. From sea, to forest and animal references, each variation connects its coded base with an organic aesthetic, providing a sense of harmony between the digital and the natural.

I admire the coherence of each piece, from the colors, to the shapes used, to the movement of the graphics. Even though it is random, it does not feel that way. Each piece is harmonious as it stands. I think this is what shows the artist’s artistic sensibilities, because of her clear knowledge of color theory and proportions. I also admire that even though it is animated art, when you take a still image, it is beautiful on its own as well.

If I had to guess how the algorithm that generated the pieces worked, I would think possibly each piece was inspired by an image of a natural element (i.e. sky or wind). Using those colors(i.e. blues), the primitive shapes in each image (i.e. ellipse and eye shapes), and how it would naturally move (whether that be in concentric movements, linear, radial, etc.) From that information, she can create this coherent art. That would be my best guess.

Here are some examples of the pieces, find more here.

Ghalya Alsanea – Project 02 – Variable Face

Gnomes of the world unite!

sketch

//Ghalya Alsanea
//Section B
//galsanea@andrew.cmu.edu
//Project-02

var eyeSize = 20;
var faceWidth = 100;
var faceHeight = 150;
var faceR = 141;
var faceG = 85;
var faceB = 36;
var eyeG = 0;
var eyeB = 0;
var shirtColor = 100;

function setup() {
    createCanvas(480, 640);
    angleMode(DEGREES);
}

function draw() {
    background(150);
    strokeWeight (1);
    stroke(0);

    // face
    fill (faceR, faceG, faceB);
    ellipse(width / 2, height / 2, faceWidth,  faceHeight);
    
    //eyes
    fill (255);
    var eyeLX = width / 2 - faceWidth * 0.25;
    var eyeRX = width / 2 + faceWidth * 0.25;
    ellipse(eyeLX, height / 2, eyeSize, eyeSize);
    ellipse(eyeRX, height / 2, eyeSize, eyeSize);
    
    //pupils
    fill (0, eyeG, eyeB);
    ellipse(eyeLX, height / 2, eyeSize / 2, eyeSize / 2);
    ellipse(eyeRX, height / 2, eyeSize / 2, eyeSize / 2);

    // //nose
    fill (185, 150, 130);
    var noseWidth = faceWidth * 0.15;
    var noseHeight = height / 2 + faceHeight * 0.15;
    triangle(width / 2, height / 2, width / 2 + noseWidth, noseHeight, width / 2 - noseWidth, noseHeight);

    //body
    fill(0, shirtColor, faceB);
    var bodyHeight = faceHeight * 4;
    var bodyX = width / 2;
    var bodyY = height/2 + bodyHeight /2 + faceHeight / 2;
    ellipse(bodyX, bodyY, faceWidth, bodyHeight);

    //hat
    fill(shirtColor, 0, faceB);
    var hatWidth = faceWidth / 2;
    var hatHeight = height / 2 - faceHeight / 3;
    triangle(width / 2, height / 2 - faceHeight, width / 2 - hatWidth, hatHeight, width / 2 + hatWidth, hatHeight);

    //mouth
    noFill();
    strokeWeight (3);
    var mouthHeight = faceHeight * 0.25;
    arc(width / 2, height / 2 + mouthHeight, faceWidth / 2, mouthHeight, 0, 180, OPEN);


    // //eyebrows
    var browLX = width / 2 - faceWidth * 0.25;
    var browRX = width / 2 + faceWidth * 0.25;
    arc(browLX, height / 2 - eyeSize, eyeSize, eyeSize, 200, 340, OPEN);
    arc(browRX, height / 2 - eyeSize, eyeSize, eyeSize, 200, 340, OPEN);

    //pupils
    fill (0);
    stroke (0, eyeG, eyeB);
    ellipse(eyeLX, height / 2, eyeSize / 2, eyeSize / 2);
    ellipse(eyeRX, height / 2, eyeSize / 2, eyeSize / 2);
}

function mousePressed() {
    // when the user clicks, these variables are reassigned
    //to random values within specified ranges.
    faceWidth = random(75, 300);
    faceHeight = random(115, 350);
    eyeSize = random(30, 50);
    eyeG = random(0, 255);
    eyeB = random(0, 255);
    shirtColor = random(100, 200);
    
    //random skin color generator
    var x = round(random (0.5, 5.5));

    // skin shade 1 -- Russet
    if (x == 1) {
        faceR = 141;
        faceG = 85;
        faceB = 36;
    } 

    // skin shade 2 -- Peru
    if (x == 2) {
        faceR = 198;
        faceG = 134;
        faceB = 66;
    } 

    // skin shade 3 -- Fawn
    if (x == 3) {
        faceR = 224;
        faceG = 172;
        faceB = 105;
    } 

    // skin shade 4 -- Mellow Apricot
    if (x == 4) {
        faceR = 241;
        faceG = 194;
        faceB = 125;
    } 

    // skin shade 5 -- Navajo White
    if (x == 5) {
        faceR = 255;
        faceG = 219;
        faceB = 172;
    } 


}

I wanted to create different gnomes and have their hat and shirt color be relative to each other, so I referenced the RGB value of the skin value. That way their outfits somehow match.

Also, I wanted to create real skin tones and used the generic 5 shade skin tones found here, and randomized it so that every time you click, the skin changes.

Finally, the eyebrows and smiles and the rest of the facial features are referencing each other so that they change proportionally with the face size and eye size.