Final Project

hcFinal
var picfiles = ["S0UUF6k.png", "QRebAPt.png", "kPzEtew.png", "GDfUrs9.png", 
"RdaK8Db.png", "rJua0RK.png", "OFcSHV3.png", "MOsS3A0.png", "gqBXY2d.png",
"O6M0opw.png", "dMPlHtH.png", "KQPXYro.png", "0k3Synd.png", "lXtNJ7L.png",
"046RWzZ.png", "gybarRF.png"];
var soundfiles = ["a.mp3", "b.mp3", "c.mp3", "d.mp3", "e.mp3", "f.mp3","g.mp3",
"h.mp3", "i.mp3", "j.mp3", "k.mp3", "l.mp3", "m.mp3", "n.mp3", "o.mp3", "p.mp3"]; //Will add more sound files later
var pics = [];
var sounds = [];
var channelobj = [];
var oldindex = -1;
var letters = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"];
var colors = [];
var titles = ["Australia fire", "BLM protest", "Chadwick Bosewman death", "Death of Chadwick Boseman", "Explosion in Beirut",
"Florida man saves his dog from an alligator", "Gas explosion in Nigeria", "Harvey Weinstein convicted",
"Impeachment trial of Trump", "Joe Biden wins", "Kobe Bryant death", "Locust swarm", "Murder hornets in US",
"NASA's Mars 2020", "Olympics postponed", "Presidential election"]
var relkey=-1;

function preload(){
    //sound files
    for (var i = 0; i < soundfiles.length; i++){
       sounds[i] = createAudio(concat ("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/", soundfiles[i])); //stop() doesn't work with loadSound
        //image files
       pics[i] = loadImage(concat ("https://i.imgur.com/", picfiles[i]));
    }
}

function makeChannel(letter, letterColor){ //Using object to combine letters and their color
    ch = {l: letter, lc: letterColor
         }
    return ch;
}

function setup(){
    createCanvas(500, 500);
    rectMode(CENTER);
    imageMode(CENTER);
    //Giving all letters the same gray color in the beginning
    for (var i = 0; i < letters.length; i++){
        channelobj[i] = makeChannel(letters[i], color(222, 217, 209));
    }
}

function draw(){
    background(240, 255, 254);
    TV();
    drawTitle(relkey);
    drawText(relkey);
}

function drawText(nSelect){
    if (nSelect > -1 & nSelect < letters.length){ //Making selected letter to turn black
        channelobj[nSelect].lc = color(0);
    }
    for (var i = 0; i < channelobj.length; i++){ //Giving characteristics and placement to the letters
        textFont('Baskerville')
        textAlign(CENTER);
        fill(channelobj[i].lc);
        textSize(25);
        text(channelobj[i].l, 20 * i + 100, 450);
    }
    if (nSelect > -1 & nSelect < letters.length){ //Making the letters to turn back to gray
        channelobj[nSelect].lc = color(222, 217, 209);
    }
}

function drawTitle(nSelect){
    noStroke();
    fill(240, 255, 254);
    rect(250, 60, 500, 120); //drawing rect to cover previous titles
    if (nSelect > -1 & nSelect < titles.length){
        textFont('Baskerville')
        textAlign(CENTER);
        fill(0);
        textSize(25);
        text(titles[nSelect], 250, 90);
    }
}

function keyPressed(){
    loop();
    relkey = keyCode - 65; //65 = 'a' keycode, found on p5js.org
    if (relkey > channelobj.length - 1 || relkey < 0){ //Checking the pressed key is in between a~p
        return; //returning any key that is not a~p
    }

    for(var i = 0; i < sounds.length; i++){ //Stopping the audio from previous channel (isPlaying found on p5js.org)
          sounds[i].stop(0);
    }
    sounds[relkey].play(); //Calling the correct audio
    started = true;
}

function TV(){
    //Drawing TV
    stroke(200);
    fill(168, 237, 170);
    rect(250, 270, 370, 270, 35);
    fill(209, 196, 186);
    circle(390, 200, 30);
    circle(390, 250, 30);
    for (var i = 300; i < 360; i += 10){
        rect(390, i, 20, 5);
    }
    fill(100);
       if (relkey > - 1 & relkey < channelobj.length ) {
     image(pics[relkey], 220, 270); //Calling the correct image
    } else {
    rect(220, 270, 260, 220);
    loading();
    for(var i = 0; i < sounds.length; i++){ //Stopping the audio from previous channel
          sounds[i].stop(0);
        }
    }
}

function loading(){ //drawing loading screen
    fill(255);
    push();
    translate(220, 270);
    for (var i = 0; i < 6; i++){
        push();
        rotate(radians(frameCount + 60 * i));
        ellipse(30, 0, 20, 10);
        pop();
    }
    pop();
}

For this project, I wanted to create a television that shows the events that happened in 2020. I was inspired to work on this project since so many people talked about how they will never speak of 2020 in the future. I thought it would be fun to create a program that sums up this year and show it to people in the future to bring their memories back. 

I tried to find a somewhat cute way to show the events since a lot of them are disturbing news. It felt like 2020 was a disastrous year and it was hard to pin down just one main event to show. So I decided to find a way to show all the “key” events of 2020. 

You can watch the channels by pressing the keyboard from “a” to “p.” If you press any keyboard that is not one of those alphabets, the television will stop playing.

Project 11: Generative Landscape

hc
var buildings = [];
var mountains = [];
var trees = [];
var noiseParam = 0;
var noiseStep = 0.01;
var people = [];
var img;

function preload(){
    //calling the superman image
    img = loadImage("https://i.imgur.com/21p2JQR.png");
}

function setup() {
    createCanvas(480, 480); 
    imageMode(CENTER);
    // create an initial collection of buildings
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        buildings[i] = makeBuilding(rx);
    }
    // mountains
    for (var i = 0; i <= width/4; i++) {
        var value = map(noise(noiseParam), 0, 1, height * 0.2, height * 0.9);
        mountains.push(value);
        noiseParam += noiseStep;
    }
}


function draw() {
    background(204, 241, 255); 
    //drawing clouds
    cloud(50, 70);
    push();
    scale(0.7);
    cloud(480, 150);
    pop();
    drawMountains(); //drawing the mountains
    displayStatusString();
    displayHorizon();
    //drawing the buildings
    updateAndDisplayBuildings();
    removeBuildingsThatHaveSlippedOutOfView();
    addNewBuildingsWithSomeRandomProbability();
    image(img, 250, 150, img.width * 0.2, img.height * 0.2); //superman
    //drawing the trees
    updateAndDisplayTrees(); 
    removeTreesThatHaveSlippedOutOfView();
    addNewTreesWithSomeRandomProbability(); 
    //drawing the people
    updateAndDisplayPeople();
    removePeopleThatHaveSlippedOutOfView();
    addNewPeopleWithSomeRandomProbability(); 
}

function cloud(x, y){
    //drawing the cloud
    push();
    translate(x, y);
    noStroke();
    fill(255, 237, 209, 95);
    ellipse(0, 10, 70, 50);
    ellipse(25, 0, 90, 60);
    ellipse(50, 10, 80, 45);
    pop();
}

//Buildings
function updateAndDisplayBuildings(){
    // Update the building's positions, and display them.
    for (var i = 0; i < buildings.length; i++){
        buildings[i].move();
        buildings[i].display();
    }
}

function removeBuildingsThatHaveSlippedOutOfView(){
    //removing the buildings
    var buildingsToKeep = [];
    for (var i = 0; i < buildings.length; i++){
        if (buildings[i].x + buildings[i].breadth > 0) {
            buildingsToKeep.push(buildings[i]);
        }
    }
    buildings = buildingsToKeep; // remember the surviving buildings
}


function addNewBuildingsWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newBuildingLikelihood = 0.015;
    if (random(0,1) < newBuildingLikelihood) {
        buildings.push(makeBuilding(width));
    }
}


// method to update position of building every frame
function buildingMove() {
    this.x += this.speed;
}
    

// draw the building and some windows
function buildingDisplay() {
    var floorHeight = 20;
    var bHeight = this.nFloors * floorHeight; 
    fill(59, 107, 130); 
    stroke(100); 
    push();
    translate(this.x, height - 40);
    rect(0, -bHeight, this.breadth, bHeight);
    stroke(220); 
    fill(207, 226, 232);
    if (bHeight > 55){
        for (var i = 0; i < this.nFloors; i++) {
            rect(5, -15 - (i * floorHeight), this.breadth - 40, 10);
            rect(35, -15 - (i * floorHeight), this.breadth - 40, 10);
        }
    }else{
        fill(255, 246, 230);
        rect(0, -bHeight, this.breadth, bHeight);
        noStroke();
        fill(240, 182, 74);
        triangle(-10,-bHeight,this.breadth/2,-bHeight-30,this.breadth+10,-bHeight);
        fill(150, 100, 45);
        rect(20, 0, this.breadth - 40, -20);
    }
    pop();
}


function makeBuilding(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: 60,
                speed: -3.5,
                nFloors: round(random(2,8)),
                move: buildingMove,
                display: buildingDisplay}
    return bldg;
}

function drawMountains(){
    mountains.shift();
    var value = map(noise(noiseParam), 0, 1, height * 0.2, height * 0.9);
    mountains.push(value);
    noiseParam += noiseStep;
    stroke(135, 173, 141);
    fill(135, 173, 141);
    beginShape(); 
    vertex(0, height);
    for (var i = 0; i < width/4; i++) {
        vertex(i*5, mountains[i]);
        vertex((i+1)*5, mountains[i+1]);
    }
    vertex(width, height);
    endShape();
}

//drawing trees
function updateAndDisplayTrees(){
    for (var i = 0; i < trees.length; i++){
        trees[i].move();
        trees[i].display();
    }
}

function removeTreesThatHaveSlippedOutOfView(){
    var treesToKeep = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x + trees[i].breadth > 0) {
            treesToKeep.push(trees[i]);
        }
    }
    trees = treesToKeep;
}

function addNewTreesWithSomeRandomProbability() {
    var newTreeLikelihood = 0.025; 
    if (random(0,1) < newTreeLikelihood) {
        trees.push(makeTree(width));
    }
}

function treeMove() {
    this.x += this.speed;
}

function makeTree(birthLocationX) {
    var trees = {x: birthLocationX,
                breadth: 20,
                speed: -3.5,
                treeHeight: round(random(50,100)),
                move: treeMove,
                display: treeDisplay}
    return trees;
}


function treeDisplay() {
    push();
    translate(this.x, height - 30);
    noStroke(); 
    fill(107, 83, 71);
    rect(-5, 0, 10, 15); //tree trunk
    fill(66, 161, 61); 
    //leaves
    triangle(-this.breadth+10, -30, 0, -this.treeHeight, this.breadth-10, -30);
    triangle(-this.breadth+5, 0, 0, -this.treeHeight*0.7, this.breadth-5, 0);
    pop();
}

//Drawing people
function updateAndDisplayPeople(){
    for (var i = 0; i < people.length; i++){
        people[i].move();
        people[i].display();
    }
}

function removePeopleThatHaveSlippedOutOfView(){
    var peopleToKeep = [];
    for (var i = 0; i < people.length; i++){
        if (people[i].x + people[i].breadth > 0) {
            peopleToKeep.push(people[i]);
        }
    }
    people = peopleToKeep;
}

function addNewPeopleWithSomeRandomProbability() {
    var newPeopleLikelihood = 0.005; 
    if (random(0,1) < newPeopleLikelihood) {
        people.push(makePeople(width));
    }
}


function peopleMove() {
    this.x += this.speed;
}

function peopleDisplay() {
    push();
    translate(this.x, height - 25);
    noStroke(); 
    fill(0);
    ellipse(0, -20, 40, 50); //head
    rect(-35, 0, 70, 50, 80); //body
    push();
    rotate(radians(-7));
    ellipse(25, -15, 15, 110); //arm
    pop();
    pop();
}

function makePeople(birthLocationX) {
    var ppl = {x: birthLocationX,
                breadth: round(random(5, 10)),
                speed: -3.5,
                pHeight: round(random(20,25)),
                move: peopleMove,
                display: peopleDisplay}
    return ppl;
}

function displayHorizon(){
    fill(53, 97, 44);
    rect (0,height-50, width, height-50); 
}


function displayStatusString(){
    noStroke(); 
    fill(0); 
}

Looking Outwards 11: A Focus on Women Practitioners

Emily Gobeille is a designer who specializes in merging technology and design to create an immersive design experience. She spent her years studying many disciplines, including web, prints, motion graphics, games, and installations. She also is one of the founders of Designer I/O, which specializes in the design and development of interactive installations. The company’s clients and partners usually include children museums.

I decided to look at one of her Designer I/O projects called Mimic. It is an “interactive installation that allows visitors to engage in a dialogue with a robot arm through gesture.” The robot can track the people’s movements and also has the ability to react to individuals actions accordingly. The robot can break down its impressions into three feelings: trust, curiosity, and interest, which will affect the robot’s responses. Depending on the individual’s movement and emotions, Mimic will react to many people simultaneously, changing its behavior. I personally find this interactive robot interesting for its skill to acknowledge the viewer’s reactions. 

Project 10: Sonic Story

AnimationHCDownload
//hayoonc
//Hayoon Choi
//Section C

var crash;
var aaah;
var birdSound;
var car;
var oops;
var bg;
var car1;
var cary = -120; var carPlus = 0.2;
var car2;
var car2x = 70; var car2dx = 30;
var person1;
var person1x = 350; var person1y = 305;
var p1x = 0; var p1dx = 30; var p1y = 0; var p1dy = 30; var pr = 0;
var person2;
var p2x = 200; var p2dx = 30; var p2y = 50;
var p2dy = 10; var p2s = 1; var p2ds = 0.02;
var bird;
var birdx = 600; var birddx = -15;
var clouddx = 5; var cloudx = 600;
var count = 0;

function preload(){
    //Sounds
    wind = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/wind-1.wav");
	crash = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/crash.wav");
    aaah = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/aaah.wav");
    birdSound = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/bird-1.wav");
    car = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/car-1.wav");
    oops = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/oops.wav");
    //Images
    bg = loadImage("https://i.imgur.com/l8Qc6Md.png?1");
    car1 = loadImage("https://i.imgur.com/5mLAaw5.png?1");
    car2 = loadImage("https://i.imgur.com/bxJJmCI.png?1");
    person1 = loadImage("https://i.imgur.com/LjpJvmr.png?1");
    person2 = loadImage("https://i.imgur.com/FyITsh6.png?1");
    bird = loadImage("https://i.imgur.com/pQXMNIy.png?1");
}

function setup() {
    createCanvas(600, 400);
    useSound();
    imageMode(CENTER);
    frameRate(10);
}

function soundSetup(){
	crash.setVolume(0.5);
    wind.setVolume(0.6);
    car.setVolume(1.4);
    aaah.setVolume(0.6);
}

function draw() {
    background(136, 203, 237); //sky color
    count ++;
    //Animation
    if (count > 0 & count < 80){
        //drawing the image as the background for the first scene
        image(bg, 300, 200, width, height);
    }
    if (count > 0 & count < 45){
        //making cloud move
        cloud(cloudx, 100);
        cloudx = cloudx - clouddx;
        if (cloudx == 400){
            clouddx = 0;
        }
    }
    if (count >= 45 & count < 80){
        //car entering
        cloud(400, 100);
        carScale(300, 200);
    }
    if (count >= 80 & count < 90){
        //car moving in the second scene
        carMove(600, 430);
        image(person1, person1x, person1y, width * 0.8, height * 0.8);
    }
    if (count >= 90 & count < 115){
        //person gets hit
        image(car2, 350, 430, width, height);
        personHit(person1x, person1y);
    }
    if (count >= 115 & count < 170){
        //person gets thrown into the air
        personFly(300, 200);
    }
    if (count >= 170){
        //showing the car again
        image(bg, 300, 200, width, height);
        cloud(400, 100);
        push();
        scale(1.5);
        image(car1, 200, 200, width, height);
        pop();
    }
    if (count > 190 & count <= 240){
        //bird flying
        image(bird, birdx, 0, width * 0.6, height * 0.6);
        birdx += birddx;
    }
    //Sound
    if (count == 1){
        wind.play();
    }
    if (count == 45){
        car.play();
    }
    if (count == 90){
        car.stop();
        crash.play();
    }
    if (count == 110){
        aaah.play();
    }
    if (count == 180){
        oops.play();
    }
    if (count == 190){
        birdSound.play();
    }
}

function cloud(x, y){
    //drawing cloud
    push();
    translate(x, y);
    noStroke();
    fill(255);
    ellipse(0, 0, 60, 40);
    ellipse(40, 0, 70, 50);
    pop();
}

function carScale(x, y){
    //car moving in the first scene
    push();
    translate(x, y);
    scale(carPlus);
    image(car1, 0, cary, width, height);
    pop();
    carPlus += 0.1;
    cary += 9;
}

function carMove(x, y){
    //car moving in the second scene
    push();
    translate(x, y);
    image(car2, car2x, 0, width, height);
    pop();
    car2x -= car2dx;
    if (car2x <= -250){
        car2dx = 0;
    }
}

function personHit(x, y){
    //making the person get hit
    push();
    translate(x, y);
    rotate(radians(pr));
    image(person1, p1x, p1y, width * 0.8, height * 0.8);
    pop();
    p1x -= p1dx;
    p1y -= p1dy;
    pr -= 1;
}

function personFly(x, y){
    //making the person fly
    push();
    translate(x, y);
    rotate(radians(pr));
    scale(p2s);
    image(person2, p2x, p2y, width * 0.8, height * 0.8);
    pop();
    p2x -= p2dx;
    p2y -= p2dy;
    pr -= 15;
    p2s -= p2ds;
    if (p2s <= 0){
        p2ds = 0;
    }
}

For this project, I wanted to include a car. Because I couldn’t find any pictures I that go well with the story, I drew them instead.

Looking Outwards 10: Computer Music

House Party was created by Neil Mendoza for a personal project. It is a musical installation with all of its materials, from furniture to computers, scavenged from trash. Even Arduino Zero, which controls the actuators in the installation, was found in the trash as well. How this works is that each screen is connected to a computer running software written in openFrameworks and the MIDI composition data was sent to Arduino and an OF control program. Then the control program sent the data to other computers over ethernet as OSC. As a result, the control program read the data and triggered the screens and Arduino. When I first saw this project, I was surprised that it didn’t use any greenscreen effect and all the materials were physically present and working. It was even more shocking that all the materials were previously trash. I admire that Neil used his unique artistic sense to create a musical installation that performs in its “natural” habitat.

Project 09: Computational Portrait

HCP
//Hayoon Choi
//hayoonc
//Section C

let img;
var click = 0; //initial click status

function preload() {
    img = loadImage('https://i.imgur.com/5Ka0n6z.jpg?1');
}

function setup() {
    createCanvas(330, 440);
    imageMode(CENTER);
    noStroke();
    background(255);
    img.loadPixels();
}

function draw() {
    //pointilizing the picture
    let pointillize = map(mouseX, 0, width, 3, 7);
    let x = floor(random(img.width));
    let y = floor(random(img.height));
    let pix = img.get(x, y);
    fill(pix);
    if (click == 0){ //drawing pumpkin initially
        pumpkin(x, y, pointillize, pointillize);
    } else if (click == 1){ //drawing ghost after one click
        ghost(x, y, pointillize, pointillize);
    } else { //drawing bat after two clicks
        bat(x, y, pointillize, pointillize);
    }
}

function pumpkin(x, y){
    //drawing the pumpkin
    push();
    translate(x, y);
    rect(5, -10, 2, 6, 70);
    ellipse(12, 0, 5, 9);
    ellipse(0, 0, 5, 9)
    ellipse(3, 0, 5, 11);
    ellipse(9, 0, 5, 11);
    ellipse(6, 0, 5, 12);
    pop();
}
function ghost(x, y){
    //drawing the ghost
    push();
    translate(x, y);
    ellipse(0, 0, 9, 10);
    ellipse(-5, 3, 5, 2);
    ellipse(5, 3, 5, 2);
    beginShape();
    curveVertex(-4.5, 0);
    curveVertex(-4.5, 0);
    curveVertex(-3, 4);
    curveVertex(-1, 6);
    curveVertex(2, 9);
    curveVertex(6, 11);
    curveVertex(5, 8);
    curveVertex(4, 4);
    curveVertex(4.5, 0);
    curveVertex(4.5, 0);
    endShape();
    pop();
}
function bat(x, y){
    //drawing the bat
    push();
    translate(x, y);
    ellipse(0, 0, 7, 10);
    wing(); //calling the right wing
    push()
    scale(-1, 1); //flipping the wing to draw the left wing
    wing();
    pop();
    triangle(2, -3, 1.9, -6, 0, -4.6);
    triangle(-2, -3, -1.9, -6, 0, -4.6);
    pop();
}

function wing(){
    //drawing the wing
    beginShape();
    curveVertex(3, -2);
    curveVertex(3, -2);
    curveVertex(6, -2);
    curveVertex(11, -3);
    curveVertex(13, 0);
    curveVertex(11, 0);
    curveVertex(10, 0.3);
    curveVertex(10, 2);
    curveVertex(8, 1);
    curveVertex(6.7, 0.7);
    curveVertex(6, 2);
    curveVertex(5, 1);
    curveVertex(4.3, 0.7);
    curveVertex(3.6, 0.9);
    curveVertex(3, 2);
    curveVertex(3, 2);
    endShape();
}

function mousePressed() {
    //making the shapes to change after mouse click
    if (click == 2) { 
        click = 0;
    } else {
        click += 1;
    }
    if (mouseButton === RIGHT) { //right click restarts the process
        background(255);
    }
}

Since it’s Halloween, I decided to make all shapes Halloween related. The shapes change when the mouse clicks on the canvas and it restarts the process if the mouse right clicks.

Drawn with just pumpkins
Drawn with just ghosts
Drawn with just bats

Looking Outwards 09: on Looking Outwards

For this week, I looked at 101’s week 9 LO about computer graphics. He/she introduced me to the project Melting memories by Refik Anadol, which was displayed in Pilevneli Gallery from February 7 through March 17, 2018. In the post, he/she mentioned how it was interesting to see a project that intersects physical and digital reality, art, and neuroscience. I agree with that since, besides from its outstanding graphics, the fact that it showcased materiality of remembering captured my attention. I thought Anadol’s way of displaying advanced technology and the study of human memory was creative. The method of gathering data and implying it to the installation was also unique. For this project, participants were asked to focus on specific long-term memories during the recording process. Then the researchers looked at certain nodes with limited frequency rates and used them to drive noise parameters within the real time simulation. 

Melting Memories

Peer link: https://courses.ideate.cmu.edu/15-104/f2020/2020/10/03/looking-outwards-05-3d-computer-graphics-5/

Looking Outwards 08: The Creative Practice of an Individual

Stephanie Dinkins is a transmedia artist who earned her MFA from Maryland Institute College of Art and is currently working as a professor at Stony Brook University. She started off as a photographer and did not have much experience in coding, however she was interested in the digital world and documentation. Her journey began with the project Bina48, where she had conversations with the robot to explore the possibilities of emotional interaction with a person and an autonomous robot. Then she moved on to her ongoing project, Not The Only One, which attempts to create a multi generational memoir of a black American family told from the perspective of an artificial intelligence. While presenting it was noticeable that she humanizes the projects that she has worked on and has formed a deep connection with them. I’m personally interested in AI, which is why I chose to watch her lecture. However, I was more engaged by her goal, which is to bring diverse perspectives into the AI world. She believes that providing more inclusivity, community engagement, and social equity will significantly broaden the future possibilities of AI. In addition, I also admire her because of her fine arts background and her bravery of diving into the digital coding world. 

Project 07: Composition with Curves

Curvehc
var nPoints = 600;

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

}

function draw(){
    background(0);
    //calling functions
    hypotrochoid();
    epicycloid();
}

function hypotrochoid(){
    //drawing hypotrochoid
    //https://mathworld.wolfram.com/Hypotrochoid.html
    push();
    noFill();
    stroke(57, 139, 173)
    translate(width / 2, height / 2);
    var x = constrain(mouseX, 0, width);
    var y = constrain(mouseY, 0, height);
    var a = map(x, 0, width, 70, 150);
    var b = map(y, 0, height, 0.5, 4);
    var h = constrain(a/2, 100, 200);
    beginShape();
    for (var i = 0; i < nPoints; i++) {
        var t = map(i, 0, nPoints, 0, TWO_PI);
        x = (a - b) * cos(t) + h * cos(((a - b) / b) * t);
        y = (a - b) * sin(t) - h * sin(((a - b) / b) * t );
        vertex(x, y);
    }
    endShape();
    pop();
}

function epicycloid(){
    //drawing epicycloid
    //https://mathworld.wolfram.com/Epicycloid.html
    push();
    translate(width / 2, height / 2)
    var x = constrain(mouseX, 0, width);
    var y; 
    var a = map(x, 0, width, 10, 20);
    var b = a / 30;
    var h = constrain(mouseY / 9, 0, 0.7 * height);
    var ph = mouseX / 25;
    fill(202, 223, 232, 70);
    stroke(90 + 98 * sin(millis() / 500), 174, 200); //making the color change smoothly
    beginShape();
    for (var i = 0; i < nPoints; i++) {
        var t = map(i, 0, nPoints, 0, TWO_PI);
        x = (a + b) * cos(t) - h * cos(ph + t * (a + b) / b);
        y = (a + b) * sin(t) - h * sin(ph + t * (a + b) / b);
        vertex(x, y);
    }
    endShape(CLOSE);
    pop();
}

At first, I wasn’t really sure how I was supposed to do the project since it looked complex. I also didn’t know what type of shapes I should create either. However, using the mathematical formula turned out to be not as overwhelming as I thought it would be since they created the shapes for me. I tried doing this project by exploring different types of curves and ended up choosing hypotrochoid and epicycloid. I began by drawing the hypotrochoid first by plugging in different numbers. Once I got that in place, I thought it looked empty in the middle so I then added an epicycloid curve. Although it was challenging to figure out which variable controls what, it was satisfying to see the end result. 

Screenshots of two different states

Looking Outwards 07: Information Visualization

We feel fine” project was created by Jonathan Harris in 2009 for a book co-authored with Seth Kamvar. The graphs show in-depth exploration of human emotions. They’re developed from a database of more than twelve million individual sentences collected over three years from personal blogs on the Internet and show the world’s emotional landscape of ups and downs. I personally admire how he was able to create a statistical graph of the world’s emotional struggles, such as mood swings. I thought that choosing this particular theme was interesting to begin with. I believe that gathering information on emotional state and putting it into graphs are more challenging than getting statistical and measurable information, such as rainfall rate, and turning that into graphs. His artistic ability shined through his graph by using different color schemes and styles to convey all the different emotions. His graphs clearly conveyed the complexity of emotions as well.

One of the “We feel fine” graphs