Project 05 – Wallpaper – srauch

Here is my palm frond wallpaper. Vibes.

sketch
//sam rauch, section B, srauch@andrew.cmu.edu, project 05
//this code makes a wallpaper pattern with overlapping palm leaves

function setup() {
    createCanvas(400, 400);
    background(220);
    text("p5.js vers 0.9.0 test.", 10, 15);
}

function draw() {
    background(16, 28, 48);

    //drawing pattern
    var direction = 1 //flips direction leaves are facing as they're drawn in the j loop
    for (var i = 0; i <= width+110; i+=110){
        for (var j = 0; j<= height+100; j+=70){
            stem(i,j, 45*direction);
            direction = direction*-1;
        }
    }

    noLoop();
}

function portLeaf(a,b,radius, spin){ //make left leaves. must be called at 0,0
    push();
    translate(a,b);
    rotate(radians(spin));
    noStroke();

    push(); //bottom half
    fill(20, 50, 23);
    translate(a-(cos(radians(70))*radius), b-(sin(radians(70))*radius));
    arc(0, 0, radius*2, radius*2, radians(70), radians(110), CHORD);
    pop();

    push(); //top half
    fill(37, 87, 42); 
    translate(a+(cos(radians(250))*radius), b-(sin(radians(290))*radius));
    arc(0,0, radius*2, radius*2, radians(250), radians(290), CHORD);
    pop();

    pop();
}

function starLeaf(a,b,radius,spin) { //make right leaves. must be called at 0,0
    push();
    translate(a,b);
    rotate(radians(spin));
    noStroke();

    push(); //bottom half
    fill(20, 50, 23);
    translate(a+(cos(radians(70))*radius), b-(sin(radians(70))*radius));
    arc(0, 0, radius*2, radius*2, radians(70), radians(110), CHORD);
    pop();

    push(); //top half
    fill(37, 87, 42);
    translate(a-(cos(radians(250))*radius), b-(sin(radians(290))*radius));
    arc(0,0, radius*2, radius*2, radians(250), radians(290), CHORD);
    pop();

    pop();
}

function stem(stemX, stemY, spin) {//make a stem, and place leaves along it 
    push();
    translate(stemX, stemY);
    rotate(radians(spin));

    //leaves at the tip
    portLeaf(0,0,50,60);
    starLeaf(0,0,50,-60);
    portLeaf(0,0,50,80);
    starLeaf(0,0,50,-80);

    //put leaves along the stem
    var radius = 45;
    for(var i = 0; i<100; i+=10){
        push();
        translate(0,i);
        portLeaf(0,0,radius, 30);
        starLeaf(0,0,radius,-30);
        radius += 3;
        pop();
    }

    //line for stem
    stroke(20, 60, 25);
    strokeWeight(3);
    line(0,0, 0, 100);

    pop();
}

Blog 05 – 3D Computer Graphics – srauch

A work of 3D computer graphics I find really interesting is a collection of digital furniture called “The Shipping”, designed by Argentinian architect Andrés Reisinger. (Here’s the collection on his website.) The collection includes ten pieces of furniture, each meticulously 3D designed and rendered, and each of which were auctioned off as NFTs for as much as $70,000. The digital furniture can be placed into any digital environment, such as the metaverse or even Minecraft. Five of the ten pieces will be produced physically as well, and one chair – the Hortensia Chair, originally deemed “impossible” to recreate in physical reality – has been put into physical production.

Digital furniture design like this pushes the imagination. Different mediums afford different creative processes, so the opportunity for furniture designers to work in a world without traditional constraints opens up the door to completely new creative mindsets. More than that, it changes the way artists can think about what work is physically possible. Beyond just creating “impossible” digital furniture, the ability to be creative in a digital environment allowed Reisinger to make real furniture that was once considered to be impossible. It’s exciting to see how access to 3D modeling and rendering will continue to develop artistic fields such as furniture design in the future.

Project 04 – String Art – srauch

Here’s my string art — when the mouse is pressed, it makes rainbow spiderwebs in each corner of the canvas. To erase the canvas and start over, press “e”.

sketch

//Sam Rauch / srauch / section B
//this code generates four "rainbow spiderwebs", one in each corner of the canvas,
//as long as the mouse is pressed. When the user presses the "e" key, the canvas
//erases. 

// two points of A line
var ax1;
var ay1;
var ax2;
var ay2;

// two points of B line
var bx1;
var by1;
var bx2;
var by2;

// endpoints of connecting lines
var x1; 
var y1;
var x2; 
var y2;


function setup() {
    createCanvas(400, 300);
    background(0);
    text("p5.js vers 0.9.0 test.", 10, 15);
}

function draw() {

    //draw spiderwebs in each quadrant of the canvas as long as mouse is pressed
    if (mouseIsPressed){
        strokeWeight(1);

        stringart();

        push();
        translate(200,0);
        stringart();
        pop();

        push();
        translate(200,150);
        stringart();
        pop();

        push();
        translate(0, 150);
        stringart();
        pop();
    }

    //erase canvas when user presses e key
    if (keyIsPressed){
        if (key == "e") {
            background(0);
        }
    }
}

//creates two lines, with 50 "stringers" between each line
function stringart() {
    //canvas size (200, 150)

    //randomly generate location of A line
    ax1 = random(10, 190);
    ay1 = random(10, 140);
    ax2 = random(10, 190);
    ay2 = random(10, 140);

    //randomly generate location of B line
    bx1 = random(10, 190);
    by1 = random(10, 140);
    bx2 = random(10, 190);
    by2 = random(10, 140);

    //assign first stringer's location connecting top of A and bottom of B
    x1 = ax1; 
    y1 = ay1;
    x2 = bx2;
    y2 = by2;

    //draw A line and B line in a random color
    stroke(random(255), random(255), random(255));
    line(ax1, ay1, ax2, ay2);
    line(bx1, by1, bx2, by2);
    strokeWeight(0.5);

    //draw 50 lines between A line and B line, incrementing 1/50th of distance between x values
    //and y values of each line
    for (var i = 0; i < 51; i+=1) {

        var x1Increment = (ax2- ax1) / 50;
        var y1Increment = (ay2 - ay1) / 50;
        var x2Increment = (bx1 - bx2) / 50;
        var y2Increment = (by1 - by2) / 50;

        //first stringer
        line (x1, y1, x2, y2);

        //changing position of stringer for each loop
        x1 += x1Increment;
        y1 += y1Increment;
        x2 += x2Increment;
        y2 += y2Increment;

    }

}

Blog 04 – Computation & Sound Art

An example of where sound and computation cross that I find interesting is Musikalisches Würfelspiel, which evidently translates from German as “musical dice game”. It was popularized in the 1700s throughout Western Europe, and many versions of the game exist as created by different composers. The gist is that someone can randomly generate a completely unique piece of music by rolling dice. The algorithm is quite simple: in each module of a table is a measure of music, and the player rolls their dice twice, first to select the column, then to select the row. The player continues randomly selecting measures this way until the song is long enough to be finished. Even with a smaller table or shorter composition, this could still produce millions of unique songs. Here’s a video of a version of the game in action. (The video is in German, but you can still see the players rolling a die to select different measures, and you get to hear the final composition.)

I find it cool that artists and composers have been embracing the affordances of algorithmically generated music long before computers were in the mix. Programs like Musikalisches Würfenspiel are a good reminder that artistic thought processes can transcend media in unexpected ways, so keep yourself open to unorthodox applications of your creative thinking.

Project 03 – Dynamic Drawing – srauch

Here is my interactive picture! As you move your mouse left to right, it gets dark outside and the moon comes up, and as you move your mouse up and down, the plant grows and its leaves open up.

sketch
//Sam Rauch / srauch / section B
//This code creates an interactive picture of a plant with a window behind it. As you move
//the mouse up and down, it gets darker and lighter outside. As you move the mouse side to
//side, the plant grows bigger and smaller. 

var windowTransparent //alpha for transparency of blue window, ie how light outside
var moonY = 300; //y position of moon
var moonview = 0; //alpha for transparency of moon
var potCenterX; //x center of pot
var potCenterY; //y center of pot
var bluefade = 0; //amount of blue added to colors as it gets darker outside
var colorfade = 0; //amount of color subtracted to colors as it gets darker outside
var plantTipY; //y tip of plant
var stemweight = 10;
var leafSizeX = 50; //width of leaf
var leafSizeY = 25; //height of leaf
var leftRotate; //rotates left-side leaves
var rightRotate; //rotates right-side leaves

var width;
var height;

function setup() {
    createCanvas(450, 600);
    background(220);
    text("p5.js vers 0.9.0 test.", 10, 15);

    width = 450;
    height = 600;
    windowTransparent = 255;
    potCenterX = 200; 
    potCenterY = 500; 
    plantTipY = potCenterY; //start the tip of the plant in the center of the pot

    leftRotate = 270;
    rightRotate = 90;

}

//draws an ellipse where the first two parameters are the ellipse's left tip
function lefttipellipse(tipX, tipY, wide, tall) {
    ellipseMode(CORNER);
    ellipse(tipX, tipY-tall/2, wide, tall);
    ellipseMode(CENTER);
}

//draws an ellipse where the first two parameters are the ellipse's right tip
function righttipellipse(tipX, tipY, wide, tall) {
    ellipseMode(CORNER);
    ellipse(tipX-wide, tipY-tall/2, wide, tall);
    ellipseMode(CENTER);
}

function draw() {

    background(230-colorfade*1.5, 230-colorfade*1.5, 120+bluefade);

    //window
    fill(240-colorfade, 240-colorfade, 230+bluefade);
    noStroke();
    rect(100, 0, 350, 450);

    //dark blue rect
    fill(26, 32, 128);
    rect(125, 0, 325, 425);

    //moon
    noStroke();
    fill(250, 250, 240, moonview); //moon white
    ellipse(300, moonY, 80);
    fill(26, 32, 128); //dark blue circle to make it a crescent
    ellipse(290, moonY-10, 70);

    //light blue sky color
    fill(185, 240, 250, windowTransparent);
    rect(125, 0, 325, 425);

    //table
    fill(110-colorfade, 60-colorfade, 37+bluefade); //brown
    rect(0, height-50, width, 50);
    //fill(100, 50, 27); //darker brown

    //plant stem
    stroke(74-colorfade, 150-colorfade, 74+bluefade); //green
    strokeWeight(stemweight);
    strokeCap(ROUND);
    line(potCenterX, potCenterY, potCenterX, plantTipY);
    noStroke();

    // the y coordinate of a point half the distance up the stem
    var yspot1 = potCenterY-(dist(potCenterX, potCenterY, potCenterX, plantTipY)/2);

    // y coordinate of a point 3/4 the distance up the stem
    var yspot2 = potCenterY-(dist(potCenterX, potCenterY, potCenterX, plantTipY)*(3/4));

    // y coordinate of a point at the top of the stem
    var yspot3 = potCenterY-(dist(potCenterX, potCenterY, potCenterX, plantTipY));

    //drawing them leaves at set points up the stem

    fill(90-colorfade*2, 180-colorfade*2, 90+bluefade); //leaf green

    //bottom right
    push();
    translate(potCenterX, yspot1);
    rotate(leftRotate);
    lefttipellipse(0, 0, leafSizeX, leafSizeY);
    pop();

    //bottom left
    push();
    translate(potCenterX, yspot1);
    rotate(rightRotate);
    righttipellipse(0, 0, leafSizeX, leafSizeY);
    pop();

    //middle right
    push();
    translate(potCenterX, yspot2);
    rotate(leftRotate);
    lefttipellipse(0, 0, leafSizeX*(7/8), leafSizeY*(7/8));
    pop();

    //middle left
    push();
    translate(potCenterX, yspot2);
    rotate(rightRotate);
    righttipellipse(0, 0, leafSizeX*(7/8), leafSizeY*(7/8));
    pop();

    //top right
    push();
    translate(potCenterX, yspot3);
    rotate(leftRotate);
    lefttipellipse(0, 0, leafSizeX*(2/3), leafSizeY*(2/3));
    pop();

    //top left
    push();
    translate(potCenterX, yspot3);
    rotate(rightRotate);
    righttipellipse(0, 0, leafSizeX*(2/3), leafSizeY*(2/3));
    pop();

    //pot
    fill(230-colorfade, 140-colorfade, 83+bluefade); //salmon
    rectMode(CENTER);
    rect(potCenterX, potCenterY, 120, 150);
    triangle(potCenterX-60, potCenterY-75, potCenterX-60,
        potCenterY+75, potCenterX-80, potCenterY-75);
    triangle(potCenterX+60, potCenterY-75, potCenterX+60,
        potCenterY+75, potCenterX+80, potCenterY-75);
    fill(240-colorfade, 150-colorfade, 93+bluefade);
    rect(potCenterX, potCenterY-90, 170, 60);
    rectMode(CORNER);

    //as move mouse left to right, the sky gets darker and colors fade to bluer shade
    windowTransparent = map(mouseX, width, 0, 0, 255);
    bluefade = map(mouseX, width, 0, 0, 40, true);
    colorfade = map(mouseX, 0, width, 0, 40, true);

    //as move mouse left to right, moon comes up
    moonY = map(mouseX, 0, width, 375, 100, true);
    moonview = map(mouseX, 0, 450, 0, 255);

    //as move mouse up and down, plant grows
    plantTipY = map (mouseY, height, 0, potCenterY, 230); //gets taller
    stemweight = map (mouseY, height, 0, 5, 25); //stem gets thicker
    leafSizeX = map (mouseY, height, 0, 50, 150); //leaves get longer
    leafSizeY = map (mouseY, height, 0, 30, leafSizeX/3); //leaves get taller
    leftRotate = radians(map(mouseY, height, 0, 270, 340)); //right leaves open up
    rightRotate = radians(map(mouseY, height, 0, 90, 20)); //left leaves open up
    //plant pot

}

Blog 03 – Computational Fabrication – srauch

I’m inspired by the whole body of Micheal Hansmeyer’s work, but a piece of his that perhaps most outwardly displays the algorithmic nature of his architectural practice is Subdivided Columns. As Hansmeyer describes it, he did not design columns, but rather designed a process that produces a column. His algorithm “subdivides” the surface of a cylinder into smaller and smaller surfaces, applying different division ratios to produce unique forms. The final column is generated by breaking up the digital column into 2700 horizontal “slices”, which are laser cut out of greyboard and assembled.

In Subdivided Columns, Hansmeyer plays with the idea of the undrawable vs the unimaginable. Even though we can imagine these forms, or at least the idea of them, most computer software and traditional drawing techniques are incapable of generating them. With a computer’s help, for the first time in human history, we can actually realize them. It makes you think about how our work is the product of our minds and our tools. Hansmeyer’s work embodies the notion that with new computational tools, we can produce something deeply human – the kind of computational thinking we’ve been pondering for centuries – but at the same time, completely new.

Here’s a video showing the process used to create Subdivided Columns

Project 02 – face generator – srauch

This face generator makes lots of cool folks to chill with! About half of the characteristics of each person — for instance, the shirt size and color, the background, and the skin tone — are completely random, while other components such as the eye color or headwear/hairstyle are randomly selected from a list of options. Writing this code really dusted off the ol’ middle school algebra. Some of said algebra is visible in the positively chicken-scratch notebook hieroglyphs I made while figuring out some of the first few variables. Once I had those established, though, I found I wasn’t writing anything down, instead just relying on the variables I’d already defined to write the next ones–quite the departure from how I worked through last week’s homework.

sketch

var width = 480;
var height = 640;

//background color
var backgroundR = 100;
var backgroundG = 0;
var backgroundB = 0;

//shirt color and size
var shirtR = 200;
var shirtG = 200;
var shirtB = 0;
var shirtWide = 400;
var shirtTall = 100;

//skintone
var skinR = 47;
var skinG = 39;
var skinB = 32;

//neck
var neckTall = 250;
var neckWide = 100;
var neckY = 200;

//head
var headWide = 250;
var headTall = 300;
var headX = width/2;
var headY = 200;

//ears
var earSize = 40;

//eyes
var eyeColor = 1;
var eyeSize = 30;
var eyeDistance = 30;

//nose
var noseLong = 20;
var noseWide = 10;

//mouth
var mouthSelector = 1;

//eyebrows
var eyebrowTall = 30;
var eyebrowWide = 30;
var eyebrowColorSelector = 1;
var eyebrowWeight = 10;

//hair
var hairstyle = 1;

function setup() {
    createCanvas(480, 640);
    background(220);
    text("p5.js vers 0.9.0 test.", 10, 15);
}

function draw() {
    noStroke();
    background(backgroundR, backgroundG, backgroundB);

    // sleeve location variables -- have to be here (not global) so will update with new shirtWide values 
    var shirtCornerStar = ((width-shirtWide)/2)+((shirtWide/4)/2); //x coord of starboard sleeve
    var shirtCornerPort = width-shirtCornerStar; //x coord of port sleeve

    //shirt
    fill(shirtR, shirtG, shirtB);
    //rect(((width-shirtWide)/2), (height-shirtTall), shirtWide, shirtTall); 
    rect(shirtCornerStar, (height-shirtTall), (shirtWide-(shirtWide/4)), shirtTall);

    //sleeves
    fill(shirtR-20, shirtG-20, shirtB-20); //makes sleeves slightly darker than shirt
    triangle(shirtCornerStar, (height-shirtTall), shirtCornerStar, height, (shirtCornerStar-((shirtWide/4)/2)), height); //starboard sleeve
    triangle( shirtCornerPort, (height-shirtTall), shirtCornerPort, height, (shirtCornerPort+((shirtWide/4)/2)), height); //port sleeve

    //neck
    neckWide = shirtWide/3
    neckY = height-neckTall-shirtTall+(shirtTall/6);
    fill(skinR-20, skinG-20, skinB-20);
    rect(width/2-neckWide/2, neckY, neckWide, neckTall);
    ellipse(width/2, neckY+neckTall, neckWide, neckTall/4);

    //head
    headX = width/2
    headY = neckY
    fill(skinR, skinG, skinB);
    ellipse(headX, headY, headWide, headTall);

    //ears
    fill(skinR-10, skinG-10, skinB-10);
    ellipse(headX-(headWide/2), headY, earSize, earSize*1.5); //starboard ear
    ellipse(width-(headX-(headWide/2)), headY, earSize, earSize*1.5); //port ear

    //redraw head to cover ears, theres prob a better way to do this but ears rely on the head variables
    fill(skinR, skinG, skinB);
    ellipse(headX, headY, headWide, headTall);

    //nose (length and width)
    strokeWeight(noseWide);
    stroke(skinR, skinG-20, skinB-20);
    line(headX, headY, headX, headY+noseLong);
    noStroke();

    //eyes (color and distance from center of head)
    if (eyeColor <= 1) {
        fill(54, 43, 17); //brown
    } else if (eyeColor <= 2) {
        fill(52, 95, 45); //green
    } else if (eyeColor <= 2.8) {
        fill(13, 200, 200); //blue
    } else {
        fill(255, 20, 0); //red!
    }
    ellipse((width/2)-eyeDistance, headY, eyeSize);
    ellipse((width/2)+eyeDistance, headY, eyeSize);


    //mouth (arc of different size and stroke color)
    if (mouthSelector <= 1) { //open smile
        fill(61, 32, 31);
        arc(headX, headY+noseLong*2, headWide/3, headTall/4, radians(0), radians(180));
    } else if (mouthSelector <= 2) { //closed smile
        noFill();
        stroke(skinR+20, skinG-20, skinB-20);
        strokeWeight(20);
        arc(headX, headY+noseLong*2, headWide/3, headTall/5, radians(10), radians(170));
        noStroke();
    } else { //bubblegum
        fill(40, 0, 0);
        ellipse(headX+10, headY+(headTall/2)-(headTall/6), 30); //mouth
        fill(238, 168, 234, 70); //pink transparent
        ellipse(headX+10, headY+(headTall/2)-(headTall/6), 175, 175); //bubble1
        ellipse(headX+10, headY+(headTall/2)-(headTall/6), 180, 180); //bubble 2
        fill(255, 240, 240, 90);
        ellipse(headX+40, headY+(headTall/2)-headTall/3, 30, 30); //highlight
    }

    //and finally, hair!
    if (hairstyle <=1) { //bald
        //do nothing
    } else if (hairstyle <=2) { //beanie
    strokeWeight(12);
    strokeCap(ROUND);
        if (hairstyle <= 1.3){
            fill(168, 47, 47); //red hat
            stroke(168-10, 47-10, 47-10);
        } else if (hairstyle <=1.6) {
            fill(200 , 120, 218); //pink hat
            stroke(200-10, 120-10, 218-10);
        } else {
            fill(86, 93, 200); //perriwinkle hat
            stroke(86-10, 93-10, 200-10);
        }
        arc(headX, headY-(headTall/2)+40, headWide+5, headTall-60, radians(180), radians(360));
        rect(headX-(headWide/2)-10, headY-(headTall/2)+40, headWide+20, 60);
    } else { //bowl cut
        if (hairstyle <= 2.3){
            fill(45, 40, 30); //dark brown
            stroke(45, 40, 30);
        } else if (hairstyle <=2.8) {
            fill(130, 96, 57); //light brown
            stroke(130, 96, 57);
        } else if (hairstyle <=2.9 & skinR > 80 && skinG > 80 && skinB >30) {
            fill(222, 129, 25); //red
            stroke(222, 129, 25);
        } else {
            fill(25, 183, 222); //blue
            stroke(25, 183, 222);
        }
        arc(headX, headY-headY/4, headWide+5, headTall-60, radians(180), radians(360));
    }

    //eyebrows
    if (eyebrowColorSelector <=1) {
        stroke(40, 35, 20); //dark brown
    } else if (eyebrowColorSelector <=2) {
        stroke(230, 230, 138); //blonde
    } else {
        stroke(140, 230, 200); //blue
    }

    noFill();
    strokeWeight(eyebrowWeight);
    arc((width/2)-eyeDistance, headY-eyebrowTall, eyebrowWide, 20, radians(200), radians(340));
    arc((width/2)+eyeDistance, headY-eyebrowTall, eyebrowWide, 20, radians(200), radians(340));
    noStroke();

}

function mousePressed() {
    //background color change
    backgroundR = random(0, 255);
    backgroundG = random(0, 255);
    backgroundB = random(0, 255);

    //shirt color and size change
    shirtR = random(0, 255);
    shirtG = random(0, 255);
    shirtB = random(0, 255);
    shirtWide = random((width-(width/3)), (width-20));
    shirtTall = random((height/6), (height/4));

    //neck and skin changes
    skinR = random(60, 200);
    skinG = random(skinR, skinR-10);
    skinB = random(skinR-20, skinR-30);
    neckTall = random(200, 250);

    //head
    headWide = random(neckWide+100, neckWide+150);
    headTall = random(headWide, headWide*1.4);
    earSize = random(50, 60);

    //eyes
    eyeColor = random(0,3); 
    eyeSize = random(20, 40);
    eyeDistance = random(30, headWide/2-30);

    //nose
    noseLong = random(headTall/10, headTall/6);
    noseWide = random(25, 40);

    //mouth
    mouthSelector = random(0, 3);

    //eyebrows
    eyebrowColorSelector = random(0,2.1);
    eyebrowWeight = random(10, 18);
    eyebrowTall = random(20, 40);

    //hair
    hairstyle = random(0,3);
}

Blog 02 – Generative Art – srauch

I’m inspired by the landscape-generating algorithm Minecraft uses to build its maps. Each Minecraft world has a completely unique map, but they are generated piecemeal rather than all in one go–the map is built one 16×16 block “chunk” at a time under the player as they wander. The worlds are built a layer at a time, using a 64-bit random number called a seed that determines the shape, biome, and finally content of each chunk, though the game also relies on “smoothing” functions that ensure biomes blend logically into one another–for example, there won’t be a snowy forest next to a desert. 

The landscape-generating algorithm Minecraft is the soul of the game. It creates in the player a sense of thrill and wonder about exploring a completely unknown landscape spreading out around them – a feeling that’s hard to come by in a highly connected 21st-century world. In a more technical sense, it’s also nifty in that it allows the game itself to be quite small–the whole thing, fresh out of the box (so to speak), takes up less than a gigabyte, making for an easy download.

credit: Minecraft.net

Blog 01 – Technical Art – srauch

I continue to be inspired by the VFX in Stranger Things, which is done by Rodeo FX using (from what I could discern online) Maya for modeling and Arnold Core for rendering. The most recent season, according to VFX supervisor Julien Hery, was the product of about two years of work.

The Stranger Things VFX inspires me for a couple of reasons. For one, the monster design is spectacular; it enhances the storytelling significantly. Secondly, Stranger Things works to bridge the gap between practical and computer-generated effects, and they do a fantastic job of it. They use VFX in such an artful and compelling way to make creatures that are completely fictitious, but move in their environment in a very convincing way, enhancing the immersion and worldbuilding.

You can see one of their completely CG monsters in this scene:

The continued improvement of visual effects such as these will broaden the horizons of future filmmakers and storytellers, allowing them to elegantly depict what before could only be imagined.

Project 01 – Self Portrait – srauch

A portrait of Sam Rauch!

sketch

function setup() {
    createCanvas(600, 600);
    background(220);
    text("p5.js vers 0.9.0 test.", 10, 15);
}

function draw() {
    background(231, 203, 62);

    //temporary guidelines
    //strokeWeight(2);
    //line(300, 0, 300, 600);
    //line(0, 300, 600, 300);

    //shirt
    strokeWeight(0);
    fill(114, 193, 189);
    rect(120, 500, 360, 100);
    triangle(120, 500, 300, 460, 300, 500);
    triangle(300, 500, 300, 460, 480, 500);
    fill(75, 161, 156);
    triangle(120, 500, 120, 600, 60, 600);
    triangle(480, 500, 480, 600, 540, 600);
    ellipse(300, 505, 200, 60);

    //neck
    fill(244, 233, 217); //light skin
    rect(225, 339, 150, 170);
    ellipse(300, 510, 150, 30);

    fill(199, 169, 127); //shadow skin
    ellipse(300, 400, 150, 150);
    rect(225, 339, 150, 67);

    //head
    fill(244, 233, 217); //light skin
    ellipse(300, 285, 260, 320);

    //ears
    ellipse(170, 295, 50, 80);
    ellipse(430, 295, 50, 80);
    triangle(160, 332, 180, 335, 185, 350);
    triangle(440, 332, 420, 335, 415, 350);

    //hair base
    noFill();
    stroke(173, 94, 93); //hair dark
    strokeWeight(20);
    arc(300, 285, 240, 300, 3.39, 6.03);

    fill(173, 94, 93);
    strokeWeight(0);
    arc(300, 210, 220, 130, 3.15, 6.30);

    triangle(192, 250, 200, 200, 260, 200);
    triangle((600-192), 250, (600-200), 200, (600-260), 200);

    //sideburns?
    fill(173, 94, 93) //hair dark
    strokeWeight(0);
    rect(172, 255, 20, 60, 0, 0, 20, 20);
    rect(408, 255, 20, 60, 0, 0, 20, 20);

    //mouth
    fill(61, 32, 31); //mouth pink
    arc(300, 375, 100, 90, 6.30, 3.15);

    stroke(61, 32, 31); //mouth pink
    strokeWeight(10);
    strokeCap(ROUND); //case sensitive: SQUARE and ROUND
    line(255, 375, 345, 375);

    //teeth
    stroke(247, 246, 232); //teeth color
    strokeWeight(10);
    line(262, 382, 338, 382);

    //nose
    stroke(199, 168, 127);
    strokeWeight(18);
    line(305, 300, 305, 345);

    //playing with whites of eyes
    //fill(247, 246, 232);
    //strokeWeight(0);
    //ellipse(245,300, 50, 40);
    //ellipse(355,300, 50, 40);
    //arc(245,300, 50, 40, 3.3, 6.15);
    //arc(355,300, 50, 40, 3.3, 6.15);

    //eye arcs
    stroke(69, 74, 69); //eye color
    strokeWeight(5);
    noFill();
    arc(245,300, 50, 40, 3.3, 6.15);
    arc(355,300, 50, 40, 3.3, 6.15);

    //eye fill
    strokeWeight(0);
    fill(69, 74, 69);
    ellipse(245, 295, 25, 25);
    ellipse(355, 295, 25, 25);

    //eyebrows
    stroke(87, 68, 44); //eyebrow color
    strokeWeight(10);
    line(240, 260, 270, 262); //flat
    line(220, 270, 240, 260); //corner
    line((600-240), 260, (600-270), 262); //flat
    line((600-220), 270, (600-240), 260); //corner


    //angleMode(DEGREES);

    //spikes!
    fill(237, 141, 141); //hair light
    strokeWeight(0);

    triangle(380, 80, 350, 200, 240, 160);
    triangle(310, 70, 380, 200, 270, 200);
    triangle(190, 220, 300, 160, 220, 100);
    triangle(220, 190, 315, 160, 270, 90);
    triangle(200, 230, 230, 180, 190, 160);

    //bangs
    triangle(230, 200, 290, 200, 270, 240);
    triangle(200, 200, 250, 200, 230, 250);
    triangle(270, 200, 350, 200, 340, 250);
    triangle(195, 200, 230, 220, 185, 240);
    triangle(170, 195, 210, 180, 200, 230);
    triangle(220, 200, 270, 200, 280, 170);
    triangle(340, 140, 420, 130, 380, 200);
    triangle(340, 210, 410, 220, 370, 170);
    triangle(330, 210, 380, 240, 375, 210);

    noLoop();
}