LO2-Generative Art

Meander – Robert Hodgin

“Meander is a procedural system for generating historical maps of rivers that never existed”

I find this project especially interesting and inspiring because it is a representation of art that transcends time. Hodgin not only uses animations of rivers on a map, but also 3d representations that depict the effect of these rivers on the surrounding terrain, as well as the overall topography of the area. As an architecture student i find this super unique because it combines animation and art with useful information that can make predictions based on the condition of the earth.

The algorithm of this piece seems to involve the usage of vectors to produce bends that form the curves of the appearing rivers. Hodgin was inspired by the artist Harold Fisk, who first created these maps that visualize time along with engineers in the US Army Coup. in 1944. It’s fascinating that now, with more evolved technology, idealizations of many artists in the past can be produced by later generations.

Meander

Project-02-Variable Face

sketch
function setup() {
    createCanvas(640, 600);
    background(220);
    text("p5.js vers 0.9.0 test.", 10, 15);
}
// Simple beginning template for variable face.
var eyeSize = 20;
var faceWidth = 100;
var faceHeight = 300;
var mouthHeight = 230;
var noseHeight = 190;
 
var rface = 240;
var gface = 188;
var bface = 212;

var rmouth = 48;
var gmouth = 213;
var bmouth = 200;

var rnose = 62;
var gnose = 12;
var bnose = 94;

var reyes = 208;
var geyes = 255;
var beyes = 206;

function setup() {
    createCanvas(300, 300);
}
 
function draw() {
    background(180);


    fill (rface,gface,bface);
    ellipse(width / 2, height / 2, faceWidth,  faceHeight);


    var eyeLX = width / 2 - faceWidth * 0.25;
    var eyeRX = width / 2 + faceWidth * 0.25;
    fill (reyes,geyes,beyes);
    ellipse(eyeLX, height / 2, eyeSize, eyeSize);
    ellipse(eyeRX, height / 2, eyeSize, eyeSize);

    fill(rmouth, gmouth, bmouth);
    arc (width/2, mouthHeight, 30, 10, TWO_PI, PI); //mouth

    fill (rnose, gnose, bnose);
    ellipse (width/2, noseHeight, 20); //nose
}
 
function mousePressed() {
    // when the user clicks, these variables are reassigned
    // to random values within specified ranges. For example,
    // 'faceWidth' gets a random value between 75 and 150.
    faceWidth = random(75, 150);
    faceHeight = random(200, 350);
    eyeSize = random(10, 40);
    mouthHeight = random(210, 240);
    noseHeight = random (180, 200);
    rface = random (200, 290);
    gface = random (170, 200);
    bface = random (200, 240);

}

Computational design of ornaments

Muqarnas is elaborate structural ornamentation that transits between floor plans and dome ceilings. This project done by Michael Hansmeyer involves using an algorithm to replicate and generate new patterns of muqarnas. I am intrigued by the dazzling patterns computers generate using simple logic. Thanks to computational design, what took hundreds of hours to design in the past can be done in minutes. This project also has implications for ornamental design in other areas, including clothing, interior design, etc.

Muqarnas generated by the algorithm

The algorithm first draws two contour lines marking the top and bottom of muqarnas, then subdividing the space in between recursively. To add variation, the software subdivides the space selectively based on the topographic features of each tile. Finally, contour lines are drawn between tiles of different tiers to add vertical dimension. The author shows his artistic sensibilities by subdividing the geometry so that each tile is too small to recognize. As a result, the muqarnas look like a continuous surface with concaves and convex features, which is different from traditional muqarnas. It is not just a replication of the past but a new design approach that utilizes the machine’s mighty computing power.

Variable Face

I want to create a simple cartoon face that has many expressions. Therefore, I add many variables including the mouth, hair, eyebrow, and so on. The outcome looks good.

Variable Face

// Setting variables for coding facial actions
var eyeSizeX = 20;
var eyeSizeY = 20;
var faceWidth = 100;
var faceHeight = 150;
var mouthExpression = 1;
var noseExpression = 1;
var hairExpression = 1;
var hairSize = 0.4;
var mouthSize = 0.1;
var r = 225
var g = 175
var b = 125
var rot = 0; 
var eyeOffAry = [-1, -0.5, 0, 0.5, 1];
var eyeOffs = 0;

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

function draw() {
    background(180);
    
    //draw face
    fill(r, g, b);
    strokeWeight(0);
    ellipse(width / 2, height / 2, faceWidth,  faceHeight);
    
    //draw hair
    //hair
    if (hairExpression <= 1) {
    fill(r-100, g-100, b-100);
    arc(width / 2, height / 2, faceWidth,  faceHeight, faceWidth*hairSize-160, -faceWidth*hairSize-20, CHORD);
    } 
    //beard
    else if (hairExpression >= 1 & hairExpression <= 2) {
    stroke(r-100, g-100, b-100);
    strokeWeight(faceWidth/5);
    arc(width / 2, height / 2, faceWidth, faceHeight, faceWidth*hairSize+40, 140-faceWidth*hairSize);
    }
    //hair line
    else if (hairExpression >= 2 & hairExpression <= 3) {
    stroke(r-100, g-100, b-100);
    strokeWeight(faceWidth/5);
    arc(width / 2, height / 2, faceWidth, faceHeight, -180+faceWidth*hairSize, -faceWidth*hairSize);
    }
    //long hair
    else if (hairExpression >= 3 & hairExpression <= 4) {
    //draw long hair behind face
    rectMode(CORNER);
    fill(r-100, g-100, b-100);
    stroke(r-100, g-100, b-100);
    strokeWeight(faceWidth/6);
    rect(width/2-faceWidth/2, height/2, faceWidth, faceHeight);
    //draw face forward
    fill(r, g, b); 
    strokeWeight(0);
    ellipse(width / 2, height / 2, faceWidth,  faceHeight);
    //draw hair forward
    fill(r-100, g-100, b-100);
    arc(width / 2, height / 2, faceWidth,  faceHeight, faceWidth*hairSize-160, -faceWidth*hairSize-20, CHORD);
    noFill();
    stroke(r-100, g-100, b-100);
    strokeWeight(faceWidth/5);
    arc(width / 2, height / 2, faceWidth, faceHeight, -180, 0);
    }


    //draw eyes
    stroke(0);
    strokeWeight(0);
    var eyeLX = width / 2 - faceWidth * 0.15;
    var eyeRX = width / 2 + faceWidth * 0.15;
    fill(255);
    ellipse(eyeLX, height / 2, eyeSizeX, eyeSizeY);
    ellipse(eyeRX, height / 2, eyeSizeX, eyeSizeY);
    fill(0);
    ellipse(eyeLX + eyeOffs*(eyeSizeX / 4), height / 2, eyeSizeX / 2, eyeSizeY / 2);
    ellipse(eyeRX + eyeOffs*(eyeSizeX / 4), height / 2, eyeSizeX / 2, eyeSizeY / 2);

    //draw noses
    fill(r-100,g-100,b-100);
    if (noseExpression <= 1) {
    ellipse(width/2, height/2 + faceHeight*0.05, faceWidth/20, faceHeight/20);
    } else if(noseExpression >= 1 & noseExpression <=2) {
    rectMode(CENTER);
    rect (width/2, height/2 + faceHeight*0.08, faceWidth/20, 1.3*faceHeight/20);
    } else {
    triangle(width/2, height/2 + faceHeight*0.05, width/2-faceWidth/20, height/2 + faceHeight*0.1, width/2+faceWidth/20, height/2 + faceHeight*0.1)
    }
    
    //draw eyebrows
    var ebrowLX1 = width / 2 - faceWidth * 0.2;
    var ebrowLY1 = height / 2 - faceHeight * 0.15;
    var ebrowLX2 = width / 2 - faceWidth * 0.35;
    var ebrowLY2 = height / 2 - faceHeight * 0.15;
    var ebrowRX1 = width / 2 + faceWidth * 0.2;
    var ebrowRY1 = height / 2 - faceHeight * 0.15;
    var ebrowRX2 = width / 2 + faceWidth * 0.35;
    var ebrowRY2 = height / 2 - faceHeight * 0.15;
    noFill();
    stroke(0);
    strokeWeight(5);
    
    translate((ebrowLX1+ebrowLX1)/2, (ebrowLY1+ebrowLY2)/2);
    rotate(rot);
    line(10, 0, -10, 0);
    rotate(-rot);
    translate(-(ebrowLX1+ebrowLX1)/2, -(ebrowLY1+ebrowLY2)/2);

    translate((ebrowRX1+ebrowRX1)/2, (ebrowRY1+ebrowRY2)/2);
    rotate(-rot);
    line(10, 0, -10, 0);
    rotate(rot);
    translate(-(ebrowRX1+ebrowRX1)/2, -(ebrowRY1+ebrowRY2)/2);

    //draw mouth
    var mouthLX = width / 2 - faceWidth * 0.25;
    var mouthLY = height / 2 + faceHeight * 0.25;
    var mouthRX = width / 2 + faceWidth * 0.25;
    var mouthRY = height / 2 + faceHeight * 0.25;
    noFill();
    strokeWeight(0);
    if (mouthExpression <= 1) {
    //open happy mouth 
    fill(255);
    beginShape();
    curveVertex(mouthLX, mouthLY);
    curveVertex(mouthLX, mouthLY);
    curveVertex(0.5*(mouthLX+mouthRX)-faceWidth*0.1, mouthLY+faceHeight*0.1);
    curveVertex(0.5*(mouthLX+mouthRX)+faceWidth*0.1, mouthLY+faceHeight*0.1);
    curveVertex(mouthRX, mouthRY);
    curveVertex(0.5*(mouthLX+mouthRX)+faceWidth*0.1, mouthLY+faceHeight*mouthSize/2);
    curveVertex(0.5*(mouthLX+mouthRX)-faceWidth*0.1, mouthLY+faceHeight*mouthSize/2);
    curveVertex(mouthLX, mouthLY);
    curveVertex(mouthLX, mouthLY);
    endShape(); 
    } else if (mouthExpression >= 1 & mouthExpression <= 2) {
    //open sad mouth 
    fill(255);
    beginShape();
    curveVertex(mouthLX, mouthLY);
    curveVertex(mouthLX, mouthLY);
    curveVertex(0.5*(mouthLX+mouthRX)-faceWidth*0.1, mouthLY-faceHeight*0.1);
    curveVertex(0.5*(mouthLX+mouthRX)+faceWidth*0.1, mouthLY-faceHeight*0.1);
    curveVertex(mouthRX, mouthRY);
    curveVertex(0.5*(mouthLX+mouthRX)+faceWidth*0.1, mouthLY-faceHeight*mouthSize/2);
    curveVertex(0.5*(mouthLX+mouthRX)-faceWidth*0.1, mouthLY-faceHeight*mouthSize/2);
    curveVertex(mouthLX, mouthLY);
    curveVertex(mouthLX, mouthLY);
    endShape();
    } else if (mouthExpression >= 2 & mouthExpression <= 3){
    //closed mouth
    strokeWeight(5);
    beginShape();
    curveVertex(mouthLX, mouthLY);
    curveVertex(mouthLX, mouthLY);
    curveVertex(0.5*(mouthLX+mouthRX)-faceWidth*0.1, mouthRY-faceHeight*mouthSize);
    curveVertex(0.5*(mouthLX+mouthRX)+faceWidth*0.1, mouthLY-faceHeight*mouthSize);
    curveVertex(mouthRX, mouthRY);
    curveVertex(mouthRX, mouthRY);
    endShape();
    } else if (mouthExpression >= 3 & mouthExpression <= 4){
    //no expression
    strokeWeight(5);
    beginShape();
    curveVertex(mouthLX, mouthLY);
    curveVertex(mouthLX, mouthLY);
    curveVertex(mouthRX, mouthRY);
    curveVertex(mouthRX, mouthRY);
    endShape();
    }
}   

//Randomize the value of variables when the user clicks to generate a new random face
function mousePressed() {
    faceWidth = random(100, 200);
    faceHeight = random(150, 250);
    eyeSizeX = random(20, 30);
    eyeSizeY = random(10, 30);
    mouthExpression = random(0, 4);
    noseExpression = random(0, 3);
    hairExpression = random(0, 5);//give some chance between 4-5 for no hair
    mouthSize = random(-0.1, 0.1);
    hairSize = random(0.1, 0.2);
    eyeOffs = random(eyeOffAry);
    r = random(100, 255);
    g = random(100, 255);
    b = random(100, 255);
    rot = random(-45, 45);
}

Looking Outwards 02: Generative Art

Project: Purform – The White Box, Audiovisual Performance, 2010

“This cycle metaphorically transposes, into sounds and images, concepts from systems theory related to black, white and grey boxes.”

I admire the aesthetics and fluidity of this project. The combination of the wide range of sounds and dynamic abstract visuals and their harmony of working together allows the audience to be fully absorbed into the piece. I am especially inspired by how the visual and audio components work together and are dependent on each other to make this piece whole. This piece is almost inviting; its fluidity and dynamicism pulls and mesmerizes the audience in and be in synch with the audio and visuals. I suppose the project was made by a looping code that was taught to react to sound vibrations and audio stimuli, and translate it into a random visual or shape. The artists’ (Alain Thibault for music, Yan Breuleux for visuals, and Jean-Sebastien Rousseau and Peter Dines for the program) sensibilities all come together to create one aesthetically and fundamentally cohesive and effective piece.

link to YouTube video

Project: Purform – The White Box, Audiovisual Performance, 2010

01-Project-face

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

function draw() {
 fill(75,36,36,[255]); //hair
    ellipse(200,200,230,400);
 fill(212,179,135,[255]);
    ellipse(200,150,180,250); //face
fill(219,58,107,[100]);       
    ellipse((width/2),(height/2+50),70,30); //lips
fill(0)
strokeWeight(3);
    line((width/2-40),(height/2+50),(width/2+40),(height/2+50));
fill(255); //eye whites
    ellipse((width/2-30),(height/2-40),30,15);
    ellipse((width/2+30),(height/2-40),30,15);
fill(75,32,32,[255]);
    ellipse((width/2-30),(height/2-40),10,10);
    ellipse((width/2+30),(height/2-40),10,10);
    arc((width/2-30),(height/2-60),30,10,PI,radians(360)); //eyebrow right
    arc((width/2+30),(height/2-60),30,10,PI,radians(360)); //eyebrow left
fill(164,135,106,[255]); //nose
strokeWeight(1);
    triangle((width/2-15),(height/2+10),(width/2+15),(height/2+10),(width/2),(height/2-30));
fill(223,193,163,[255]);
strokeWeight(1);
    rect((width/2-9),(height/2-30),18,35);
fill(0);
    ellipse((width/2-5),(height/2+5),8,5);
    ellipse((width/2+5),(height/2+5),8,5);
fill(255,204,204,[255]);
    circle((width/2+40),(height/2),30);
    circle((width/2-40),(height/2),30);
noLoop
}

I found creating the proportions most challenging and getting different features in their correct positions.

project1-self portrait

sketch

    function setup() {
    createCanvas(1920,1080)
}


function draw() {
    background(0);
    fill(20);
    ellipse(600,400,500,300)
    ellipse(1320,400,500,300)
    fill(40)
    ellipse(600,400,400,290)
    ellipse(1320,400,400,290)
    fill(70)
    ellipse(600,400,300,280)
    ellipse(1320,400,300,280)
    fill(110)
    ellipse(600,400,250,270)
    ellipse(1320,400,250,270)
    fill(140)
    ellipse(600,400,150,260)
    ellipse(1320,400,150,260)
    fill(240)
    ellipse(600,400,90,260)
    ellipse(1320,400,90,260)

    fill(30)
    ellipse(960,690,50,100)
    fill(60)
    ellipse(960,800,200,50) 

    
    var y = 260
    var dir = 1
    var speed = 50 
    function draw () {
        fill (0)
        ellipse(600, y, 30,30)
        ellipse(1320, y, 30,30)
        y += dir * speed
        if (y<200) {
            dir= -dir
        }
        if (y>600) {
            dir= -dir
        }
    }
    
}

    






most challenging is calculate the position

Project 1: My Self Portrait

sketch
//name: Hari Vardhan Sampath
//classSection: E

function setup() {
    createCanvas(500, 500);
    background(0);
}

function draw() {
    
    fill(212, 38, 40);
    ellipse(250, 150, 160, 200);
    fill(150, 38, 40);
    ellipse(250, 160, 300, 100); //hat

    fill(251, 209, 1);
    ellipse(250, 250, 150, 200); //faceOutline

    strokeWeight(7);
    ellipse(220, 225, 50, 50);
    ellipse(280, 225, 50, 50);
    line(260, 220, 240, 220); //glasses
    
    strokeWeight(10);
    point(220, 220);
    strokeWeight(10);
    point(280, 220); //eyes
    
    strokeWeight(5);
    fill(255, 255, 255);
    arc(250, 300, 75, 30, 220, 330, CHORD)  //mouth

    strokeWeight(5);
    arc(250, 260, 5, 15, 200, 330) //nose

    noLoop();
}

project 1: my self-portrait

efleisch project
/*Eliana Fleischer
    efleisch
    Section E
*/

function setup() {
    createCanvas(500, 500);
    background(240, 146, 243);
    //used a RGB color chart to find the color code for a purple bakcground
 
}

function draw() {
    //these lines were a way to add more elements to my assignemnt and also experiment using the "color" command in the code
    // i put all the starting points as the same so it would make a light refraction-esque shape
    strokeWeight(10)
    stroke("red")
    line(width/2,height/3,500,height/3)
    stroke("orange")
    line(width/2,height/3,500,height/3+10)
    stroke("yellow")
    line(width/2,height/3,500,height/3+20)
    stroke("green")
    line(width/2,height/3,500,height/3+30)
    stroke("blue")
    line(width/2,height/3,500,height/3+40)
    stroke("purple")
    line(width/2,height/3,500,height/3+50)
   

    strokeWeight(1)
    stroke(0)
    //this is the fill I am using for my skin tone. I used the same RGB generator for it as with the purple background
    fill(164,127,73)
    
    // i used the starting point of width/2 and height/3 and based all of my measurments off of that scale
    ellipse(width/3 -25, height/3, 20, 30) // these are the ellipses for my ears. i put it first so it would be drawn behind the head
    ellipse(width/3 + 75, height/3, 20, 30)
    ellipse(width/3 +25, height/3, 100, 125) // head
    circle(width/3 -25, height/2 +80, 25) // these are the hands 
    circle(width/3 +75, height/2 +80, 25)

    fill(255)// this is the white fill for my eyes

    ellipse(width/3, height/3, 24,32)
    ellipse(width/3 + 50, height/3, 24, 32)

    fill(62,32,9) // this is the brown for the center of my eyes 

    circle(width/3, height/3, 16) //center of eyes
    circle(width/3 + 50, height/3, 16)

    fill(0)

    triangle(width/3 + 25, height/3 + 25, width/3 +13, height/3 + 37, width/3 + 37, height/3 + 37) //mouth

    fill(255)
    triangle(width/3 + 25, height/3 + 25, width/3 + 20, height/3 + 32, width/3 + 30, height/3 + 32) //teeth

    strokeWeight(3) // i wanted my hair to be drawn bolder so i increased the stroke weight

    fill(0)
/* these points I used to plan out my quadrilaterals but I dont need them for the final product
    point(width/3 + 25, height/3 - 65)
    point(width/3 - 15, height/3 - 55)
    point(width/3 , height/3 - 50)
    point(width/3 - 25 , height/3 - 10)

*/ 

    quad(width/3 + 25, height/3 - 65, width/3 - 15, height/3 - 55, width/3 - 25 , height/3 , width/3 , height/3 - 50)// hair
    quad(width/3 + 25, height/3 - 65, width/3 + 40, height/3 - 55, width/3 + 75 , height/3 , width/3 +75 , height/3 - 50)


    strokeWeight(7) // i decided to use points instead of small circles to utilize a different element 
    point(width/3, height/3 ) // pupils 
    point(width/3 +50, height/3 )

    strokeWeight(1) // decreased stroke weight again for drawing the body
    rect(width/3 -25, height/2 -20, 100, 100) // body
    rect(width/3 -40, height/2 +5, 15, 75) // arms
    rect(width/3 +75, height/2 +5, 15, 75)
    fill(0, 102, 0) // green for pants
    rect(width/3 - 25, height/2 +80, 45, 100) //pants
    rect(width/3 +30, height/2 +80, 45, 100)


}

I think the most challenging part of my project was centering all of my objects relative to each other.

project 1: self-portrait

m’s project 1
/*m. tayao
    atayao
    lab section E
*/

function setup() {
    createCanvas(500, 500);
    background(0);
}

function draw() {
// BACKGROUND CHANGE
if (mouseX > width/2) {
    background(145, 176, 255);    // light blue bg
    fill(208, 230, 112);    // "O"
    rect(width/2 - 50, height/2 - 200, 35, 55);
    rect(width/2 - 40, height/2 - 190, 25, 45);
    fill(145, 176, 255);
    rect(width/2 - 40, height/2 - 190, 15, 35);
    fill(208, 230, 112);    // "H"
    rect(width/2 - 5, height/2 - 200, 10, 55);
    rect(width/2 + 25, height/2 - 200, 10, 55);
    rect(width/2, height/2 - 175, 30, 10);
    rect(width/2 + 45, height/2 - 200, 10, 40);    // "!"
    rect(width/2 + 45, height/2 - 155, 10, 10);
} else {
    background(208, 230, 112);
    }
// SELF-PORTRAIT
noStroke();
fill(64, 48, 27);    // hair
ellipse(width/2 - 55, height/2 - 60, 75);
ellipse(width/2 + 25, height/2 - 50, 135);
rect(width/2 - 92.5, height/2 - 60, 184.75, 200);
fill(214, 161, 96);    // head
ellipse(width/2, height/2 + 15, 150, 165);
fill(89, 55, 12);    // eyebrows
ellipse(width/2 - 25, height/2 + 7, 25, 10);
ellipse(width/2 + 25, height/2 + 7, 25, 10);
fill(242, 236, 228);    // whites of eyes
ellipse(width/2 - 30, height/2 + 35, 45, 30);
ellipse(width/2 + 30, height/2 + 35, 45, 30);
fill(125, 81, 0);    // irises
ellipse(width/2 - 30, height/2 + 35, 20);
ellipse(width/2 + 30, height/2 + 35, 20);
fill(64, 44, 15);    // pupils
circle(width/2 - 30, height/2 + 35, 10);
circle(width/2 + 30, height/2 + 35, 10);
fill(181, 129, 65);    // nose
ellipse(width/2 - 5, height/2 + 70, 7);
ellipse(width/2 + 5, height/2 + 70, 7);
fill(237, 115, 90);    // cheeks
ellipse(width/2 - 45, height/2 + 65, 40, 20);
ellipse(width/2 + 45, height/2 + 65, 40, 20);
fill(191, 69, 131);    // mouth
ellipse(width/2, height/2 + 85, 20, 10);
fill(242, 236, 228);    // teef
ellipse(width/2, height/2 + 82, 13, 5);
}