mecha-project07-curves

sketch

//maddy cha
//section e
//mecha@andrew.cmu.edu

var nPoints = 100;

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

function draw() {
    //background g value is increased with mouseX
    background(255,constrain(map(mouseX,0,width,0,255),210,240),200);   
    frame();
    //location of curve depends on mouse (but is constrained 60 pixels around center in x and y directions)
    translate(constrain(mouseX,width/2-30,width/2+30),constrain(mouseY,height/2-30,height/2+30));
    hypocycloid();
}

//draws outside black rectangle
function frame(){
    noFill();
    stroke(0);
    rect(0,0,width-1,height-1);
}

function hypocycloid(){
    var x;
    var y;
    var r;
    var a = map(mouseX,0,width,0,150);
    //increases amount of points on hypocycloid
    //makes it so that points are increasing by whole numbers
    var b = nf(map(mouseX,0,width,0,6),2,0);

    push();
    //rotates based on mouseX location
    rotate(mouseX);
    //opacity of shape is dependant on mouseX
    fill(256,256,256,map(mouseX,0,width,0,100));
    beginShape();
    for (var i = 0; i < nPoints; i++) {
        var t = map(i, 0, nPoints, 0, TWO_PI);
        
        x = (a/b)*((b-1)*cos(t)-cos((b-1)*t))
        y = (a/b)*((b-1)*sin(t)+sin((b-1)*t));
        //draws points at x and y values (with some randomness)
        //nPoints dictates how many points are drawn between lines
        vertex(x+random(-2,2), y+random(-2,2));
    }
    endShape(CLOSE);
    pop();
}

For this project, I started with creating a deltoid by implementing the formula into my code. Once I was able to understand how to do this, I wanted to expand my scope by looking at the overarching hypocycloid. I decided that I wanted my mouseX and mouseY interactions to increase the amount of cusps that would appear on my shape. In order to do this, I had to alter my original deltoid formula to take in a greater amount of variables.

Once I figured that out, I implemented more ways in which the user could interact with my code using their mouse. I relied on the constrain() and map() functions in order to make sure the shape stayed in the canvas. While mouseY was used to change the location of my shape, mouseX dictated the amount of cusps, the color of the background color, the size, fill opacity, and the rotation of the hypocycloid. Additionally I experimented with adding randomness so that my project would be more visually entertaining.

mecha-lookingoutwards-07

Touching Air

For this week, I decided to look into the work of Stefanie Posavec, specifically her explorations with wearable data visualizations. Collaborating with information researcher Miriam Quick, Posavec created this piece titled Touching Air in 2014. The two collected data regarding large particulate (PM10) levels. Each necklace they created in this series was meant to visualize a week’s worth of data, with the size and shape of each piece representative of the amount of particulates in the air. The large, spiky piece in the image above represents the fact that there are a dangerous amount of particulates in the air–making the piece harmful to touch.

Posavec wrote that her decision to visualize this data using a necklace had to do with how these specific particulate levels are harmful to one’s heart and lungs. When I imagine data visualizations, my mind immediately thinks of graphs and other two-dimensional ways of visualizing data. Because of how this went against the norm of what I consider to be data visualizations, I felt that it was an interesting piece to dissect. I was inspired with how the communication of the data was representational of the issues that the subject brings about.

mecha-lookingoutwards-06


Coding Architecture

For this week, I stumbled upon the artwork of Linyi Dai, a graduate of Rhode Island School of Design. When I first considered the subject of randomness in computational art, I did not even consider the possibility of using randomness in order to produce practical objects. While this example may not be a perfect example of practicality, it led me to realize that randomness could be used for things such as architectural rendering. While there are a lot of conditions for this specific example of randomness, the location of where the rectangles appear on each of the layers on this piece are. What I found to be particularly inspiring about this piece was Dai’s ability to create spheres that followed a similar format while still displaying a nature of randomness. I liked that the changes between each sphere were subtle yet undeniably there.

mecha-project06-abstract-clock

sketch

//maddy cha
//section e
//mecha@andrew.cmu.edu
//project-06

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

function draw() {
    var h = hour();
    var m = minute();
    var s = second();

    var w = width/10;
    var h2 = height/3
    background(142,185,196);   

    //body
    noStroke();
    fill(256,256,256,120);
    rect(100,80,330,340,40,40,40,40);


    //changes from 24 hour to 12 hour clock
    if(h == 0){
        h = 12;
    } else if(h > 12 & h < 24){
        h-=12;
    } else{
        h = hour();
    }

    //calls function that uses minutes to determine how many eyelashes to draw
    minuteLashes();

    for(var i = 0; i < 12 ; i++){
        //allows for two rows of eyes
        if(i < 6){
            fill(256);
            noStroke();
            arc(w*(i+3),h2,30,15,0,180);
            arc(w*(i+3),h2,30,15,180,360);
            //eye will turn red corresponding to hour
            if(i == h-1){
                fill(255,map(m,0,60,0,120),map(m,0,60,0,120));
            } else 
                fill(142,185,196);

            //blue iris (top row)
            ellipse(w*(i+3),h2,15,15);

            //pupil (top row)
            fill(20);
            ellipse(w*(i+3),h2,10,10);     

        } else{
            fill(256);
            noStroke();
            arc(w*(i-3),h2+30,30,15,0,180);
            arc(w*(i-3),h2+30,30,15,180,360);

            //eye will turn red corresponding to hour
            if(i == h-1){
                fill(255,100,100);
            } else 
            //blue iris (bottom row)
            fill(142,185,196);
            ellipse(w*(i-3),h2+30,15,15);

            //pupil (bottom row)
            fill(20);
            ellipse(w*(i-3),h2+30,10,10);        

        }
    
        //drooping eyelinds
        if(s >= 55 || s <= 5){
            if(i<6){
            fill(100,150,160);
            arc(w*(i+3),h2,30,15,180,360);
        } else{
            fill(100,150,160);
            arc(w*(i-3),h2+30,30,15,180,360);
        }
    }

        //blinks every minute
        if(s == 0){
            fill(100,150,160);
            if(i < 6){
                arc(w*(i+3),h2,30,15,0,180);
                arc(w*(i+3),h2,30,15,180,360);  
            } else{
                arc(w*(i-3),h2+30,30,15,0,180);
                arc(w*(i-3),h2+30,30,15,180,360);            
            }
        }
            
    }
}

function minuteLashes(){
    var s = second();
    //minute tally marks
    for(var j = 0; j <= s; j++){

        //draws five lashes per eye based on seconds
        if(j!=0 & j<=5){
            stroke(100,150,160);
            strokeWeight(2);
            line(128+5*j,145, 128+5*j,160);
        }
        if(j >5 & j<=10){
            line(152+5*j,145, 152+5*j,160);
        }
        if(j >10 & j<=15){
            line(174+5*j,145, 174+5*j,160);
        }
        if(j >15 & j<=20){
            line(198+5*j,145, 198+5*j,160);
        }
        if(j >20 & j<=25){
            line(221+5*j,145, 221+5*j,160);
        }
        if(j >25 & j<=30){
            line(244+5*j,145, 244+5*j,160);
        }
        if(j >30 & j<=35){
            line(128+5*(j-30),175, 128+5*(j-30),190);
        }
        if(j >35 & j<=40){
            line(152+5*(j-30),175, 152+5*(j-30),190);
        }
        if(j >40 & j<=45){
            line(174+5*(j-30),175, 174+5*(j-30),190);
        }
        if(j >45 & j<=50){
            line(198+5*(j-30),175, 198+5*(j-30),190);
        }
        if(j >50 & j<=55){
            line(221+5*(j-30),175, 221+5*(j-30),190);
        }
        if(j >55 & j<=60){
            line(244+5*(j-30),175, 244+5*(j-30),190);
        }
    }
    mouth();
}

function mouth(){
    var m = minute();

    noStroke();
    fill(255,map(m,0,60,0,120),map(m,0,60,0,120));    
    rect(150,220,230,map(m,0,60,20,180),90,90,40,40);
    noStroke();
    fill(255);
}

For this project, I decided to use hours, minutes, and seconds of the current time in order to create a graphic picture. I started by sketching out a monster that I could use to show the passage of time.

While I messed around with a couple different coded designs, I went with using eyes to indicate the hour, mouth size to indicate minutes, and eyelashes to indicate seconds. One of the eyes turns red corresponding to the current hour, and the monster blinks every minute (his eyelids appear 5 seconds before and after he blinks). He gains a new eyelash every second, and the size of his mouth is dependent on the current minute.

mecha-project05-wallpaper

sketch

//maddy cha
//section e
//mecha@andrew.cmu.edu
//project-05

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

function draw() {
    bird();
    noLoop();
}

function bird() {
    background(230,225,215);
    //dictates the x position of all of the elements
    var z = random(-70,20);

    //randomizes angle of grass
    var grassAdd = random(-10,10);
    var grassAdd3 = random(0,20);

    //randomizes whether or not third piece of grass will appear
    var randomGrass = random(0,10);

    //nested for loop that creates grid of chickens
    for(var x = z; x < 880; x+=140){
        for(var y = z; y < 880; y+=140){
        //grass
        noFill();
        strokeWeight(1);
        stroke(130,125,115);
        line(80+x,140+y,80+x-grassAdd,140+y-random(8,14));
        line(85+x,140+y,85+x-grassAdd,140+y-random(10,20));

        //chance that third piece of grass will appear
        if(randomGrass <= 5){
            line(100+x+grassAdd3,140+y,100+x-grassAdd+grassAdd3,140+y-random(8,14));
        }

        //wing shadow
        noStroke();
        fill(215,200,190);
        rect(3+x,52+y,35,30,40,20,0,20);

        //legs
        noFill();
        stroke(255,123,0);
        strokeWeight(2);
        line(40+x,90+y,40+x,110+y);
        line(40+x, 110+y, 37+x, 110+y);
        
        stroke(215,93,0);
        line(30+x, 110+y, 27+x, 110+y);
        line(30+x,90+y,30+x,110+y);

        //body
        noStroke();
        fill(255);
        rect(10+x,25+y,30,70,0,20,0,50);
        rect(20+x,60+y,50,35,0,0,20,20);

        //eye
        fill(130,125,115);
        ellipse(20+x,34+y,5.5,5.5);
        noFill();
        strokeWeight(1);
        stroke(130,125,115);
        ellipse(20+x,34+y,8,8);

        //beak
        noStroke();
        fill(255,123,0);
        triangle(10+x,35+y,-2+x,25+y,10+x,25+y);
    
        //wing shadow
        fill(230,225,215);
        rect(30+x,52+y,35,30,40,20,0,20);

        //wing
        fill(255);
        rect(30+x,50+y,35,30,40,20,0,20);
        }
    }
}

For this project, I decided to start with creating a graphic that I could use to repeat and make an aesthetically pleasing wallpaper with. While I was originally planning to create a function and place it in a for loop in draw, I instead implemented a nested for loop in my “bird” function. After creating my bird, I added different lines of grass that would change angles based on randomized x and y values. Additionally, a randomized variable would dictate whether or not a third piece of grass would show up.

mecha-lookingoutwards-05

ramen scene (buttons determine what elements fall/how they interact)

Creator of the company Terrified Jellyfish, Tj Hughes thought up Nour, an interactive food simulator experimenting with 3D stylistic renditions of food. Advertised as “food art” on kickstarter, the program allows users to interact with scenes of ramen, boba, and popcorn through button mashing (whether on a keyboard or midi board). The user learns about how each button affects the scene through experimentation.

What drew me to this project was the beautiful visuals and the seamless combination of art and code. The way that the scenes appear makes it feel like an animation, yet the ability for users to interact with it the way that they do ties it back to programming. I also liked how the creator’s admitted love of “bright, saturated colors” and “absurdist humor” are reflected in the visual aesthetics and interactivity of the game itself.

Although it has yet to be fully backed and completed, the game is expected to be downloadable through Steam.

boba scene (buttons determine how/what elements move)

mecha-project04-string-art

sketch

//global variables that hold x and y position as well as the amount that is added to both values
//(different x and y variables per function)

var x1 = -100;
var y1 = 0;
var x1Step = 2;
var y1Step = 4;

var x2 = 400;
var y2 = 0;
var x2Step = 2;
var y2Step = 2;

var gradient = 0;
var gradient2 = 256;
var gradient3 = 256;

var x11 = 0;
var x22 = 400;
var y11 = 300;
var y22 = 0;
var x11Step = 0.5;
var y11Step = 1;
var x22Step = 0.5;
var y22Step = 1;

function setup() {
    createCanvas(400,300);
}

function draw() {
    //makes background change color value
    background(gradient3--);
    //calls functions that produce lines
    lines();
    lines2();
    lines34();
}

//lines converging in center
function lines(){
    var x1constrain = constrain(mouseX,-100,0);
    strokeWeight(0.8);
    for(var i=0;i<1000;i+=10){
        stroke(gradient+i);
        line(x1constrain+i, 0, 0, y1-i);

    }
    x1+=x1Step;
    y1+=y1Step;
}

//lines converging in center
function lines2(){
    var y2constrain =constrain(mouseX,-100,0);
    strokeWeight(0.8);
    for(var i=0;i<1000;i+=10){
        stroke(gradient2-i);
        line(x2-i, 300, 400, y2constrain+i);

    }
    x2-=x2Step;
    y2+=y2Step;
}

//slower corner lines
function lines34(){
    //increases i at a faster rate so as to draw less lines
    for(var i=0;i<1000;i+=30){
        stroke(gradient+i*1.2);
        line(x11+i,0,0,y11-i);
        stroke(gradient+i*1.2);
        line(x22-i,300,400,y22+i);
    }
    //changes x11 and y22 values so that it creates a curve
    x11+=x11Step;
    y11-=y11Step;
    x22-=x22Step;
    y22+=y22Step;
}

For this project, I decided that I wanted to play with adding motion into my string art. I started with figuring out the values in order to make the first loop of lines in the top left corner and used my experimentation with that in order to mirror the lines into the bottom right corner.

While I thought that the two looked interesting together, I decided that rather than create two more loops for the other corners, I wanted to create two new series of lines that would start from the same corner but act in a very different way. While playing around with that concept, I came up with the code below.

sketch

//lines1 variables
var x1=0;
var x1Step=0.5;
var y1=300;
var y1Step=1;
var x2=400;
var x2Step=1;
var y2=0;
var y2Step=1;
var gradient=0;

var y3=100;
var y3Step=0.5;
var x3=1000;
var x3Step=1;
var y4=400;
var y4Step=1;
var x4=400;
var x4Step=1;


function setup() {
    createCanvas(400,300);
}

function draw() {
    background(255,200,200);
    lines1();
}

function lines1(){
    if(y1 >0 & y1 < 300){
    for(var i=0;i<1000;i+=20){
        strokeWeight(0.8);
        //gradient black to white lines
        stroke(gradient+i*1.2);
        line(x1+i,0,0,y1-i);
        //teal lines
        stroke(gradient+i*1.2);
        line(x2-i,300,400,y2+i);
    }
}
     for(var i=0;i<1000;i+=60){
        strokeWeight(0.8);
        stroke(0);
        line(0,y3+i,x3-i,0);
        stroke(256);
        line(0,y4-i,x4+i,0);
    }
    x1+=x1Step;
    y1-=y1Step;
    x2-=x2Step;
    y2+=y2Step;
    x3+=x3Step;
    y3-=y3Step;
    x4-=x4Step;
    y4+=y4Step;

}

Although I found that I was able to satisfy the requirements of the project, I decided that I was not satisfied with the inconsistent ways that the lines would move, so I restarted and played around with changing different variables. Through more experimentation, I was able to come up with my final code, which appeared more sophisticated in terms of the spacing of the grid it created as well as the monochrome colors.

mecha-lookingoutwards-04

Patatap was created by designer Jono Brandel in collaboration with Lullatone and published on March 26, 2014. Described as a “portable animation and sound kit”, patatap generates sounds created by the Lullatone team, Shawn and Yoshimi, with corresponding graphics at the push of a key. As both a graphic designer and a computer programmer, Jono wanted to create a program that introduced synesthesia–more specifically visual music–to creators.

What drew me to this project specifically was the way that sound and graphics were combined in such a precise manner. When first introduced to this website a few years ago, I did not even consider the fact that it had to have been coded. With the knowledge that I know now, I have even more respect for the designers and the project itself. I am also inspired by Jono’s ability to purposefully exemplify the concept of synesthesia through Patatap.

mecha-project03-dynamic-drawing

sketch

//alters
//position of eyebrows, eyes, blush, mouth, bird, face
//color of blush, face, bird
//size of blush, face

var colorR = 0;
var colorG = 0;
var colorB = 0;
var topY = 70;
var bottomY = 640-70;
var ellipseSize = 140;
var angle = 0;

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

function draw() {
    background(210-colorR,240-colorG,240);
    noStroke();

    angle+=1;
    //rotating sun moon thing
        push();
        translate(240,300);
        rotate(angle);
        noStroke();
        fill(255);
        ellipse(-40,-250,40,40)
        pop();
    
    fill(210-colorR,240-colorG,240);
    noStroke();
    rect(0,260,600,600);

    //constrain mouseY so ball doesn't go past top and bottom part of canvas
    var yConstrain = constrain(mouseY, topY, bottomY);
    var ellipseSize = constrain(mouseY-400, 140,220);
    var ellipseSize2 = constrain(mouseY+400,100,140);

    //little bird friend
    //beak
    noStroke();
    fill(230+colorR,180+colorG,130+colorB);
    triangle(230,yConstrain-145,190,yConstrain-120,240,yConstrain-110);
    noFill();
    stroke(80);
    line(240,yConstrain-100,240,yConstrain)
    line(230,yConstrain-100,230,yConstrain)
    noStroke();
    fill(255,160+colorR,160+colorR);
    arc(238,yConstrain-110,50,50,30,220,CHORD);
    ellipse(220,yConstrain-130,40,40);
    //wing
    fill(255,140+colorR,140+colorR);
    arc(250,yConstrain-110,40,40,30,220,CHORD);

    //face
    noStroke();
    fill(230+colorR,180+colorG,130+colorB);
    ellipse(240,yConstrain,ellipseSize,ellipseSize2);

    //eyebrows
    noFill();
    strokeWeight(2);
    stroke(80);
    arc(205, yConstrain-10,40,40,30,70,OPEN);
    arc(270, yConstrain-10,40,40,-270,-230,OPEN);
    
    //eyes and mouth
    //eyes open while mouse is in top part of screen
    if(mouseY<250){
        noStroke();
        fill(80);
        ellipse(220,yConstrain+30,6,6);
        ellipse(260,yConstrain+30,6,6);
        
        noFill();
        stroke(80);
        strokeWeight(2);
        arc(240,yConstrain+35,30,30,40,140,OPEN);

        ellipse(220,yConstrain-125,2,2);

        //blush
        noStroke();
        fill(250+colorR,140+colorG,100+colorB)
        ellipse(200, yConstrain+40, ellipseSize/10, 14);
        ellipse(280, yConstrain+40, ellipseSize/10, 14);

    }
    if(mouseY<450 & mouseY >=250){
        noStroke();
        fill(80);
        ellipse(220,yConstrain+30,6,6);
        ellipse(260,yConstrain+30,6,6);

        stroke(80);
        strokeWeight(2);
        fill(255);
        line(230,yConstrain+45,250,yConstrain+45);

        ellipse(220,yConstrain-125,2,2);

        //text box
        fill(255);
        strokeWeight(1.5);
        noStroke();
        rect(47,yConstrain-150,104,40,30,30,0,30);
        triangle(120,yConstrain-140,120,yConstrain-110,160,yConstrain-110);
        noFill();
        stroke(80);
        strokeWeight(1);
        text("please stop",70,yConstrain-126);

        //blush
        noStroke();
        fill(250+colorR,140+colorG,100+colorB)
        ellipse(200, yConstrain+40, ellipseSize/10, 14);
        ellipse(280, yConstrain+40, ellipseSize/10, 14);

    }
    //eyes closed while mouse is in bottom part of screen
    if(mouseY>=450){
        noFill();
        strokeWeight(2);
        stroke(80);
        line(210,yConstrain+30,220,yConstrain+25);
        line(260,yConstrain+25,270,yConstrain+30);

        noFill();
        stroke(80);
        strokeWeight(2);
        arc(240,yConstrain+45,30,30,180,360,OPEN);

        fill(255);
        strokeWeight(1.5);
        noStroke();
        rect(47,yConstrain-150,104,40,30,30,0,30);
        triangle(120,yConstrain-140,120,yConstrain-110,160,yConstrain-110);
        noFill();
        stroke(80);
        strokeWeight(1);
        text("how could you",62,yConstrain-126);

        strokeWeight(2);
        line(213,yConstrain-126,220,yConstrain-124);

        //blush
        noStroke();
        fill(250+colorR,140+colorG,100+colorB)
        ellipse(200, yConstrain+40, ellipseSize/10, 14);
        ellipse(280, yConstrain+40, ellipseSize/10, 14);

    }
    //changes color of face as mouse goes down
    if(mouseY < height/2){
        if(colorR < 20){
        colorR++;
        colorG--;
        colorB-=5;}
    } else{
        if(colorR > -20){
        colorR--;
        colorG++;
        colorB-=5;
    }
}
}

At first, I struggled with the open ended nature of this prompt. I couldn’t figure out how exactly I wanted to implement all of the changing aspects in such a small canvas without making it seem too cluttered. My first idea was utilizing mouseY to create something that looked like it was being stepped on, and ended up with the code above. Although it ended up a lot different than what I had first planned, I decided that rather than limit myself to a specific sort of theme, I would just roll with whatever came to my mind first. I thought that the hardest part of this was definitely calculating the position of all of the elements I used in relation to mouseY.

mecha-lookingoutwards-03

In 2014, the design studio Nervous System created a kinematic dress utilizing generative technology and 3D printing. To do this, the studio first created a program coined Kinematics Cloth App, a web application utilizing javascript with the ability to generate dresses, shirts, and skirts that could be printed in 3D. Through the app, users have the option to customize the pattern of the dress as well as the fit and style.

What first drew me to this project was the combination of computer generated art and fashion. Although it makes sense that algorithms and the like are capable of creating such pieces, it still amazes me to even think of how one would go about taking into consideration all of the combinations of shapes that could go into customization.

Not only this, but the way that the web app is designed allows for users who are inexperienced with CAD modeling. Having the ability to give accessibility to such advanced technology to the everyday person without losing the customizability of the designs seems simple in theory, but takes a lot of strategic design.