Justin Yook- Final Project

stageMaster

// Justin Yook
// jyook@andrew.cmu.edu
// Section C
// Final Project: Stage Master

var dancerArr = []; // Array of dancer objects 
var siz = 20; // Diameter of dancers (fixed)
var cFrame = 0; // Current frame = current count (index)
var tFrames = 8; // Total number of frames = eight count
var c; //Current canvas

function setup() {
    c = createCanvas(480, 360);
}

function draw() {
    background(255);
    // Create Grid 
    // Horizontal lines
    for (var i = 0; i < height; i+=30) {
        stroke(200);
        strokeWeight(1);
        line(0, i, width, i);
    }
    // Vertical lines
    for (var i = 0; i < width; i+=30) {
        stroke(200);
        strokeWeight(1);
        line(i, 0, i, height);
    }

    // Create bottom rectangle
    fill(65, 105, 225);
    rect(0, 300, width, height);

    // Create count circles 
    for (var i = 0; i < 8; i++) {  
        fill(255);
        ellipse(i * 50 + 66, 330, 2 * siz, 2 * siz);

        fill(0);
        textSize(14);
        text(i + 1, i * 50 + 62, 335);
    }

    // Create upper rectangle
    fill(65, 105, 225);
    rect(0, 0, width, height - 300);

    // Check and display dancer objects
    for (var i = 0; i < dancerArr.length; i++) {
        dancerArr[i].draw();
    }

    // Display title
    fill(255);
    textSize(20);
    text("STAGE MASTER", width / 3, height / 8);

    // Indicate which eight count you are currently on with green ellipse
    if (cFrame == 0) {
        fill(0, 255, 0);
        ellipse(66, 330, 40, 40);

        fill(0);
        textSize(14);
        text("1", 62, 335);
    }

    if (cFrame == 1) {
        fill(0, 255, 0);
        ellipse(116, 330, 40, 40);

        fill(0);
        textSize(14);
        text("2", 112, 335);
    }

    if (cFrame == 2) {
        fill(0, 255, 0);
        ellipse(166, 330, 40, 40);

        fill(0);
        textSize(14);
        text("3", 162, 335);
    }

    if (cFrame == 3) {
        fill(0, 255, 0);
        ellipse(216, 330, 40, 40);

        fill(0);
        textSize(14);
        text("4", 212, 335);
    }

    if (cFrame == 4) {
        fill(0, 255, 0);
        ellipse(266, 330, 40, 40);

        fill(0);
        textSize(14);
        text("5", 262, 335);
    }

    if (cFrame == 5) {
        fill(0, 255, 0);
        ellipse(316, 330, 40, 40);

        fill(0);
        textSize(14);
        text("6", 312, 335);
    }

    if (cFrame == 6) {
        fill(0, 255, 0);
        ellipse(366, 330, 40, 40);

        fill(0);
        textSize(14);
        text("7", 362, 335);
    }

    if (cFrame == 7) {
        fill(0, 255, 0);
        ellipse(416, 330, 40, 40);

        fill(0);
        textSize(14);
        text("8", 412, 335);
    }
}

function keyPressed() {
    // Add new dancer at (mouseX, mouseY) when pressing spacebar
    if (key == ' ') { 
        dancerArr.push(makeDancer(mouseX, mouseY, siz));
    }

    // Move to next eight count when pressing 'd'
    if (key == 'd') {
        cFrame += 1;
        cFrame = cFrame % tFrames;
        for (var i = 0; i < dancerArr.length; i++) {
            if (dancerArr[i].posArr.length < cFrame) {
                //x
                dancerArr[i].posArr[cFrame][0] = dancerArr[i].posArr[cFrame - 1][0];

                //y
                dancerArr[i].posArr[cFrame][1] = dancerArr[i].posArr[cFrame - 1][1];
            }
        }
    }

    // Move to previous eight count when pressing 'a'
    if (key == 'a') {
        cFrame -= 1;
        if (cFrame < 0) {
            cFrame += 8;
        }
    }

    // Download screenshot of current formation
    if (key == "s") {
        saveCanvas(c, 'formation', 'jpg');
    }
}

// Click and drag dancer object
function mousePressed() {
    for (var i = 0; i < dancerArr.length; i++) {
        if (dist(mouseX, mouseY, dancerArr[i].posArr[cFrame][0], dancerArr[i].posArr[cFrame][1]) <= (dancerArr[i].ps / 2)) {
            dancerArr[i].drag = true;
        }
    }
}

function mouseDragged() {
    for (var i = 0; i < dancerArr.length; i++) {
        if (dancerArr[i].drag == true) {
            for (var j = cFrame; j < tFrames; j++) {
                dancerArr[i].posArr[j][0] = mouseX; 
                dancerArr[i].posArr[j][1] = mouseY; 
            }
        }
    }
}

function mouseReleased() {
    for (var i = 0; i < dancerArr.length; i++) {
        dancerArr[i].drag = false;
    }
}

//----------------------------------------------------------------------
// DANCER OBJECT
function makeDancer(x, y, s) { 
    var dancer = {"px": x, "py": y, "ps": s, "drag": false};
    var posArr = [];
    for (var i = 0; i < tFrames; i++) {
        posArr.push([x, y]);
    }
    dancer.posArr = posArr;
    dancer.draw = dancerDisplay;
    return dancer;
}

function dancerDisplay() {
    fill(0);
    var cpos = this.posArr[cFrame];
    ellipse(cpos[0], cpos[1], this.ps, this.ps);
}

Instructions:

‘space’ key: Add a new dancer at (mouseX, mouseY)

‘d’ key: Move to the next count

‘a’ key: Move to the previous count

’s’ key: Save a screenshot of the current formation

Mouse: Click, hold, and drag inside dancer to move the dancer

First add a dancer on the canvas, at your mouse position; click and drag the dancer to move them around. If you are satisfied with the placement of your dancers, then move to the next count by pressing ‘d’. If you want to change any previous formations, press ‘a’ to move to the previous count. You can also save a screenshot of the current formation by pressing ’s’.

Statement:

“Stage Master” is a tool for choreographers and dancers to visualize dance formations. I really enjoyed creating this project, because it is something that can help me make formations easily, and in an organized manner. The most challenging part of the project was developing how dancer objects were updated for each count because I had to understand nested arrays and objects very well. The current version of the program only works for a single set of eight counts, but in the future, I would want to add a feature that allows the user to navigate through sets of eight counts. In addition, it would be better if I were to include a feature where the user can play and pause music. Overall, the visuals are not that great, and the amount of code is not a lot, but I believe that the function of the program is useful.

Justin Yook – Project Proposal

General idea of project

In the world of dance, concepts and formations are very important because they heavily influence how detailed choreography looks and feels as a whole. But, this part of the choreography process can be difficult because there are many factors involved. My final project is called Stage Master, a tool that choreographers can use to make various formations and staging ideas in an organized manner. Specifically, users will first drag and drop an audio file into the program. Then, the program will break down the audio into sets of eight counts after computing the BPM or tempo. Next, users can add as many dancers on the canvas by clicking the mouse, and move each dancer around by dragging them with the mouse. Every formation will be linked to a corresponding frame of counts within a set of eight counts. The convenient feature is that users can play the music while they arrange dancers. After finishing all the staging ideas, the program has the ability to export all screenshots of the formations in a compiled pdf file.

Justin Yook – Looking Outwards 12

Osu gameplay
Example from Playbook.dance

The two projects that are relevant to my project are Osu by Dean Herbert, and Playbook.dance by Greg Lee. Osu is a rhythm game, where players press on the keyboard or click the mouse to the song they are listening to in the game. I admire the game because it has grown to be one of the biggest of its genre, and it has never lost any player engagement; the idea of interacting with music is interesting. Playbook.dance is an application for the iPhone, that allows choreographers to arrange dancers, represented by circles, to create concepts for staging and formations. I like this application because it is easy to use, and pretty flexible. The only negative side of it is that it is becoming outdated, because the author does not update it anymore.

Sources:

https://osu.ppy.sh/home

https://itunes.apple.com/us/app/playbook-dance/id572038933?mt=8

Justin Yook – Project 11

freeTurtle

// Justin Yook
// jyook@andrew.cmu.edu
// Section C
// Project 11

var blueTurtle;
var rCol = [];
var rFor;

function setup() {
    createCanvas(360, 240);
    background(0);

    for (var i = 0; i < 50; i++) {
    	rCol[i] = color(random(0, 255), random(0, 255), random(0, 255));
    }

   	blueTurtle = makeTurtle(0, height / 2);
    blueTurtle.setWeight(3);
    blueTurtle.setColor(color(255, 255, 255));

	frameRate(60);
}

function draw() {
	// CREATE THE ZIG ZAG PATTERN
	blueTurtle.forward(1);

	if (blueTurtle.x >= 45 & blueTurtle.x < 90) {
		blueTurtle.face(300);
		blueTurtle.forward(1);
	}

	if (blueTurtle.x >= 90 & blueTurtle.x < 135) {
		blueTurtle.face(70);
		blueTurtle.forward(1);
	}

	if (blueTurtle.x >= 135 & blueTurtle.x < 180) {
		blueTurtle.face(-70);
		blueTurtle.forward(1);
	}

	if (blueTurtle.x >= 180 & blueTurtle.x < 225) {
		blueTurtle.face(70);
		blueTurtle.forward(1);
	}

	if (blueTurtle.x >= 225 & blueTurtle.x < 270) {
		blueTurtle.face(-70);
		blueTurtle.forward(1);
	}

	if (blueTurtle.x >= 270 & blueTurtle.x < 315) {
		blueTurtle.face(-300);
		blueTurtle.forward(1);
	}

	if (blueTurtle.x >= 315 & blueTurtle.x < width) {
		blueTurtle.face(0);
		blueTurtle.forward(1);
	}

	if (blueTurtle.x >= width) {
		blueTurtle.x = 0;
		blueTurtle.y = random(0, 240);
		blueTurtle.setColor(random(rCol));
	}
}

// Implement Turtle 
function turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}
function turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;
var newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){
this.forward(-p);}function turtlePenDown(){this.penIsDown=true;}
function turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){
if(this.penIsDown){stroke(this.color);strokeWeight(this.weight);
line(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){
return sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){
var absAngle=degrees(atan2(y-this.y,x-this.x));
var angle=((absAngle-this.angle)+360)%360.0;return angle;}
function turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle< 180){
this.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}
function turtleSetWeight(w){this.weight=w;}function turtleFace(angle){
this.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,
angle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,
right:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,
penUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,
turnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,
setColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};
return turtle;}

I was inspired by how heartbeats and sound were represented on monitors, and created a zig-zag pattern similar to them. To add something interesting, I made an array with length 50, where each element is a random color. In addition, the y-coordinate of each pattern drawn after the first is random.

One variation of random colors and y-coordinates

Justin Yook – Looking Outwards 11

Design of Application

Prélude in ACGT by Pierry Jaquillard is a project that converts personal DNA data into into sounds. Jaquillard used his own DNA sequence to convert it into music. I admire this project because it combines biology and music together, two topics that can seem unrelated. It is a new way of expressing something through music, and it can open doors to creative and innovative ideas. Jacquillard used a midi Library for JavaScript to generate the midi signals in the main computer. Then he sent those signals to Ableton Live to play the sounds from webapps on iPads and iPhones. Even other musical elements such as tempo can be controlled on the application. There is no mention of a specific algorithm used with JavaScript. The creator’s artistic sensibilities show in his simple and intuitive design of the app.

Source: https://www.creativeapplications.net/js/prelude-in-acgt-sonification-of-personal-dna-data/

Justin Yook – Project 10

genland

// Justin Yook
// jyook@andrew.cmu.edu
// Section C
// Project 10

var milk = [];
var milkCol;

function setup() {
    createCanvas(480, 200);
    milkCol = [color(255, 0, 0), color(255, 255, 0), color(0, 0, 255), color(0, 255, 0)];

    for (var i = 0; i < 10; i++) {
        var rx = random(width); // random x location within width
        milk[i] = makeMilk(rx);
    }

    frameRate(60);
}

function draw() {
    background(200, 233, 243);

    displayFloor();

    updateAndDisplayMilk();
    removeMilk();
    addMilkRandom();
}

function displayFloor(){
    stroke(152, 196, 209);
    strokeWeight(3);
    line(0, height - 30, width, height - 30);
}

function makeMilk(spawnX) {
    var mlk = {x: spawnX,
               space: 50,
               speed: -1.0,
               move: milkMove,
               col: random(milkCol),
               display: milkDisplay}
    return mlk;
}

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

function milkDisplay() {
    fill(255);
    stroke(0);
    strokeWeight(1);
    rect(this.x, height - 90, 40, 70);

    fill(this.col);
    rect(this.x, height - 90, 40, 10);

    fill(this.col);
    rect(this.x, height - 30, 40, 10);

    fill(255);
    quad(this.x, height - 90, this.x + 5, height - 100, this.x + 35, height - 100, this.x + 40, height - 90);

    fill(255);
    rect(this.x + 5, height - 105, 30, 5);
}

function addMilkRandom() {
    var newMilkProb = .007;
    if (random(0, 1) < newMilkProb) {
        milk.push(makeMilk(width));
    }
}

function removeMilk() {
    var milkeep = [];
    for (var i = 0; i < milk.length; i++) {
        if (milk[i].x + milk[i].space > 0) {
            milkeep.push(milk[i]);
        }
    }
    milk = milkeep;
}

function updateAndDisplayMilk() {
    for (var i = 0; i < milk.length; i++) {
        milk[i].move();
        milk[i].display();
    }
}

I chose to do a generative landscape of the inside of a refrigerator. The object I defined is the milk quart. Each milk quart has a color that is randomly picked from an array of pre-selected colors. I was inspired when I went to buy some groceries, and I saw that different types of milk had different colors on their packaging. If I were to add to this project, I would include different heights for each milk quart, and other food products (objects) such as eggs, and yogurt. The concept for this project was the hardest to think of by far,  because I could not find inspiration for a long time during the week.

Initial sketches

Justin Yook – Looking Outwards 10

 

Minicade display

Chloe Varelidi’s Minicade project uses a simple approach to teach people how to make mini games. I think that Minicade is not only an education tool but also serves as an inspiration that can convince other people to branch out further from the web-app and create their own video games. Varelidi’s career started out when she pursued a Master in Fine Art at Parson’s Design and Technology Program. After acquiring the degree, she worked for various video game developer studios as creative director, and senior game designer. Later, she set up her own company called Humans Who Play, a business that encourages doing good with play. Minicade was developed when she was a member of LittleBits.

Sources:

http://www.minica.de/

http://varelidi.com/

Justin Yook – Looking Outwards 09

3D Print of Obama’s Speech

I decided to discuss rjpark’s Looking Outwards 03, about Gilles Azzaro’s 3D printed sculptures based on sound. This project is interesting to me because it is a way for people to visualize audio in physical form. According to the blog post, the artist uses audio samples of events or speeches that he values. I agree that the 3D sculptures serve as a beautiful representation of historical events, whether it may be global or local; memories or past events are very important because they have the power to define individuals or groups of people. In the future, it would be great if the artist used a much bigger 3D printer to make bigger versions of the audio. They can be like landmarks that help bring people together.

Source: https://3dprint.com/124989/3d-printed-sound-fablabs/

Artist: http://www.gillesazzaro.com/

Justin Yook – Project 09

customPix

// Justin Yook
// jyook@andrew.cmu.edu
// Section C
// Project 09

var underlyingImg;

function preload() {
    var imgURL = "https://i.imgur.com/25HDnhA.jpg";
    underlyingImg = loadImage(imgURL);
}
function setup() {
    createCanvas(270, 480);
    background(255);
    underlyingImg.loadPixels();
    frameRate(60);
}

function draw() {
    var x = random(width);
    var y = random(height);
    var px = constrain(floor(x), 0, width-1);
    var py = constrain(floor(y), 0, height-1);
    var theColorAtLocationXY = underlyingImg.get(px, py);

    noStroke();
    fill(theColorAtLocationXY);
    rect(x, y, 20, 10);
}

For the portrait, I used my friend’s face. I kept playing around with the style of points being drawn, but I decided on a long rectangle because it reminded me of actual old paintings; in addition, the slight obscurity of his face made it look less boring. I also set the frame-rate to be higher so it paints the portrait faster.

Finished portrait
Original photo

Justin Yook – Looking Outwards 08

Chris Sugrue is a digital artist who is known to create interactive displays, audiovisual performances, and algorithmic animations. She has a Masters of Fine Arts in Design and Technology from Parsons School of Design, and now is based in Paris, France; she currently is a teacher at Parsons Paris.  Sugrue’s work mostly involves experimenting with technology by coming up with fascinating ways to explore artificial life, optical illusions, and eye-tracking. I admire her art because each piece she made has a different story within it. Story is important in any art piece because it gives the art a new level of depth and interpretation. My favorite project is Delicate Boundaries, an interactive simulation where cell-like creatures on a screen can crawl onto the person touching the screen; the small creatures move around a person’s body to another in interesting ways. The visual for this project is very simple, so that it is relaxing to the eyes. However, the project’s message and interactivity makes all the difference because it is a way for something so simple looking to have so much complexity. I learned from this that what is more important than visuals is the message that is conveyed, and that my projects should try to incorporate more interactivity.

Source: http://csugrue.com/delicateboundaries/