Danny Cho – Final Project – Shooting Stars

sketch

var renderer;
var starSize = 10;
var stars = [];
var launchSpeed = 40;
var starDuration = 1000;
var starLimit = 10;
var starGrowth = .5;
var starMoveFade = 20;
var persX = 30;
var persY = 30;
var timerMultiplier = 0.2;

var particles = [];
var particleSize = 5;
var particleSpeed = 2;
var limitZ = -7500;
var starWiggle = 4;


var bgStars = [];
var bgStarNumber = 100;

function setup() {
    renderer = createCanvas(windowWidth, windowHeight, WEBGL);
    for (var i = 0; i < 100; i++) {
        bgStars.push(makeBackgroundStars());
        bgStars[i].x = random(-15000, 16000);
    }
    frameRate = 60;
}

function draw() {
    background(0);
    fill(255);
    translate(-width / 2, -height / 2, 0);
    noCursor();
    ellipse(mouseX, mouseY, 25);
    //drawing background stars
    if (bgStars.length < bgStarNumber) {
        bgStars.push(makeBackgroundStars());
    }
    for (var i = 0; i < bgStars.length; i++) {
        bgStars[i].draw();
        bgStars[i].move();
        if (bgStars[i].x < -15000) {
            bgStars.splice(i,1);
        }
    }

    //drawing particles
    if (mouseIsPressed) {
        particles.push(makeParticle());
        for (var i = 0; i < particles.length; i++) {
            particles[i].draw();
            particles[i].move();
            particles[i].remove();
            if (particles[i].opq == 0){
                particles.splice(i,1);
            }
        }
    }
    //drawing stars
    for (var i = 0; i < stars.length; i++) {
        stars[i].draw();
        stars[i].count();
        stars[i].move();
        if (stars[i].timer > starDuration) {
            stars.shift();
        }  
        if (stars[i].x < -15000) {
            stars.splice(i,1);
        }
    }
    //removeStars
    if (stars.length > starLimit) {
        stars.shift();
    }
}

//when the mouse is pressed, it starts creating a star
function mousePressed() {
    stars.push(makeStar());
}

//as soon as the stars are done being created, they are not the newest
function mouseReleased() {
    for (var j = 0; j < stars.length; j++) {
        stars[j].newest = false;
    }
    particles = [];
}

function makeStar() {
    var star = {x: mouseX, y: mouseY, z: 0,
                size: starSize, newest: true,
                perspectiveX: width/2 - mouseX,
                perspectiveY: height/2 - mouseY,
                // evolve: evolveStar, 
                count: countTimeStar, timer: 0,
                flashX: mouseX, flashY: mouseY, flashZ: -1000,
                draw: drawStar, move: moveStar, sizeDown: 20}
    return star;
}

//drawing the star
//controls the growth of the star
function drawStar() {
    // translate(this.x, this.y, this.z);
    push();
    translate(this.x, this.y, this.z);
    strokeWeight(0);
    stroke(200);
    //radiance shown by multiple circle
    for (var i = 0; i < 3; i++) {
        fill(255, 255, 255, 40);
        sphere(this.size * (1 + (i / 2)), 15, 15);
    }
    pop();
    if (mouseIsPressed & this.newest == true) {
        this.size += starGrowth;
    }
    if (mouseReleased) {
        strokeWeight(0);
        push();
        translate(this.flashX, this.flashY, 0);
        fill(255, 255, 255, 100 - 5 * (this.timer))
        sphere(this.size * ((this.timer) ^ 2 / 10));
        // sphere((this.size * ((this.timer)/10))/2 * 10);
        pop();
    }
}

//controls the movement of the star
function moveStar() {
    //if it has been released, 
    if (this.newest == false) {
        if (this.z <= limitZ) {
            this.y += starWiggle * sin(millis()/300);
           
            this.x -= starMoveFade;
                while (this.sizeDown > 1) {
        this.size = this.size * .99;
        this.sizeDown -= 1;
        print("hi")
    }
        }
        else if (this.z > limitZ) {
            this.z -= launchSpeed * this.timer * .25;
            this.x -= this.perspectiveX / persX * (this.timer * timerMultiplier);
            this.y -= this.perspectiveY / persY * (this.timer * timerMultiplier);
        }
        else {this.y -= launchSpeed * (this.timer * .05);    
        }
    }
}

function countTimeStar() { //works!
    if (frameCount % 2 == 0 & this.newest == false) {
        this.timer++;
    }
}

//creating particles that will gather towards the touch point
function makeParticle() {
    var particle = {OriginX: mouseX, OriginY: mouseY, OriginZ: 0,
                    awayX: mouseX - random(-500, 500),
                    awayY: mouseY - random(-500, 500),
                    awayZ: 0 + random(-200, 200), opq: 20,
                    move: moveParticle, count: countTimeParticle,
                    draw: drawParticle, remove: removeParticle,
                    timer: 0}
    return particle;
}

function drawParticle() {
    
    push();
    translate(this.awayX, this.awayY, this.awayZ);
    fill(255, 255, 255, this.opq);
    sphere(particleSize);
    sphere(particleSize / 2);
    pop();
}

function removeParticle() {
    if (dist(this.OriginX, this.OriginY, this.OriginZ,
        this.awayX, this.awayY, this.awayZ) <= 50) {
        this.opq = 0;
    }
}

function moveParticle() {
    var distX = this.OriginX - this.awayX;
    var distY = this.OriginY - this.awayY;
    var distZ = this.OriginZ - this.awayZ;
    this.awayX += distX * .03;
    this.awayY += distY * .03;
    this.awayZ += distZ * .03;
    this.opq += 50 / dist(this.OriginX, this.OriginY, this.OriginZ,
                            this.awayX, this.awayY, this.awayZ);
}

function countTimeParticle() {
    if (frameCount % 2 == 0 & this.newest == false) {
        this.timer++;
    }
}

function makeBackgroundStars() {
    var bgStar = {x: 14000, y: random(-5000, 5000), z: limitZ,
                    move: moveBackgroundStars, draw: drawBackgroundStars,
                    size: random(20, 60), fluctuate: random(400, 800)}
    return bgStar;
}

function moveBackgroundStars() {
    this.x -= starMoveFade;
    this.y += 2 * sin(millis() / this.fluctuate);
}

function drawBackgroundStars() {
    push();
    translate(this.x, this.y, this.z);
    noStroke();
    sphere(this.size);
    fill(255, 255, 255, 30 * (sin(millis() / this.fluctuate) / 2));
    sphere(2 * this.size);
    pop();
}

I created an interactive star generator as a simulation for the design project, “Tesla’s Sunlit Night”. The concept is that people entering this brand pop-up shop will be able to interactive the inner walls the way this visualization allows the audience to. The only major difference in the interaction would be the clicks translated as touches.

It is meant to emphasize through experience what Tesla’s solar energy products can do. The reason this pop up is called, “Sunlit Night” is because the experience of creating stars in the dark ceiling , representing the night sky will be powered by the solar energy.

To interact, just click anywhere on the screen. The longer you hold, it will increase in size. I wanted to push further in the growth of star and how each differ in their appearance, but it was computationally too expensive, and could not be realized.

Danny Cho – LookingOutwards 12

I looked at two people’s projects, Hannah Cai (2018 Fall) and Supawat Vitoorapakorn (2017 Fall). Hannah created an experience where you can select stars and connect them with different shapes, while Supawat created an environment to test out the process of evolution.

Above is Supawat’s evolution simulation

Above is Hannah’s interactive constellation

What I find very interesting in these two people’s projects is that they took completely different routes about what they want to convey. Hannah created a visually pleasing interaction while Supawat created a highly data-based visualization of constantly morphing information.

I wonder if I can take the middle ground of balance between these two. 

Danny Cho – Final Project Proposal

I am currently making a space for an experience for people to feel wonder and playfulness by creating stars shooting them into the night sky. Below is the sketch. The touch screen part will be substituted with the clicking motion and I want to create additive features that are activated in various conditions in relation to distance between different stars and their locations.

Danny Cho – Generative Landscape

For this project, I was inspired by some of the previous works done in the past 15-104 classes. Especially the ones that were done regarding the concepts of the shooting stars and lamps inspired me. I tried to replicate the frame of the lamps with the detail feature of the sphere function as well as showing the glow by creating multiple translucent sphere in and out of them.

It takes some time for the lamps to start appearing unless you drag around the screen to look for them.

landscape

//Danny Cho
//Project 11
//changjuc@andrew.cmu.ed
//section A
var lampNumber = 20;
var lampXlimit;
var lampZlimit;
var lampYlimit;
var lamps = []; //containing objects
var lampScale = 60; //scale of the lamp exterior
var renderer;



function setup() {
	renderer = createCanvas(480, 480, WEBGL);
	for (var i = 0; i < lampNumber; i++) {
        lampXlimit = random(-100, 600);
        lampXlimit = random(-1000, 1000);
        lampZlimit = random(-50, 1000);
        lamps[i] = makeLamp(lampXlimit, lampYlimit, lampZlimit);
    }
    frameRate(10);

}

function draw() {
	background(28, 37, 65);
	noStroke();
	
	// for (var i = 0; i < lampNumber; i++) {
	// 	push();
	// 	 print("line37")
	// 	translate(lampX[i], lampY[i], lampZ[i]);

	// }
	// pop();
	for (var u = 0; u < lamps.length; u++) {
		lamps[u].draw();
	}

	var keepLamps = []; 
	//would delete the lamps that go beyond a certain height
		for (var j = 0; j < lamps.length; j++) {
			if (lamps[j].y > 500) {
				keepLamps.push(lamps[j]);
			}
		}

	orbitControl();
	fill(255);

	

}

function makeLamp(lx, ly, lz) {
	print("lamp make")
	var lamp = {x: lx, y: ly, z: lz, draw: lampDraw}
	return lamp;
}

function lampDraw() {
	print("lampdraw")
	push();
	print("line59")
	//location of the lamp
	translate(this.x, this.y, this.z);
	fill(218, 45, 28, 200);
	stroke(0);
	//the exterior of the lamp
	sphere(lampScale, 10, 4);
	noStroke();
	//inner lighting of the lamp
	for (var i = 0; i < 5; i++) {
		fill(255, 220, 115, 20 - 4 * i)
		sphere(9 * i + 10);
	}
	//outer glow of the lamp
	for (var i = 0; i < 6; i++) {
		fill(255, 220, 115, 4.5)
		sphere((i * i) + 60);
	}
	//lamp's movement
	this.y -= 45;
	pop();

	//making new lamps
	var newLamp = 0.008; //chances of new lamp being created
	if (random(0, 1) < newLamp) {
		lampXlimit = random(-2000, 6000);
		lampZlimit = random(-5000, 0);
		lamps.push(makeLamp(lampXlimit, (-lampZlimit) / 4, lampZlimit));
	}
	
}

Danny Cho – LookingOutwards 11

For this week’s looking outwards to give attention to female artists in the field of creative coding, I would like to focus on Sharon Daniel. Sharon Daniel is a professor in the Film and Digital Media department and serves as chair for the Digital Arts and New Media MFA program at the University of California, Santa Cruz. Her works are focused on empowering and giving voice to those who don’t receive as much attention and are often mistreated, and become the victims of injustice in our society.

a screenshot of “blood sugar”

My favorite work of hers is called, “Blood Sugar”. It is an archive of interviews with numerous conversations with different types of addicts. The conversations include why and how they became addicts. The visualization shows the form of sound wave as well as different key sentences that reacts to the movement of the mouse.

What interests me is that the visualization is not necessarily a crucial part of the story and it could have been explained in many other ways, but because it creates a certain atmosphere, while emphasizing the “voice” of the interviewee, it adds to the experience of listen. Especially how one can rotate the sound wave in the 3D space provides metaphorically different perspectives.

This is the link to her project.

Danny Cho – LookingOutwards 10

The Weather Thingy is an instrument that takes into account the weather to play various sounds in harmony. I found the serenity produced by this project fascinating. Different sensors bring the numerical input to be translated into the algorithm and produce sound. The ambience of the sound and the concept of weather go along very well together.

This project makes me wonder the very extreme cases and different possible variables. For instance, when it is hailing, what will happen? Or when the climate is very arid and hot? I think this project has a lot of potential and room to explore.

Weather Thingy – ECAL/Adrien Kaeser

Danny Cho – SonicSketch Project 10


sketch

I made an interactive sound grid where the position of your mouse determines which of the soundtracks are being played the loudest. The ellipses also change colors and scales accordingly. There is unbalance due to innate volume difference in the sound files. The sound files are all 120bpm to match the beat, but due to the volume imbalance, it’s hard to be aware of individual sounds.

//Danny Cho
//changjuc@andrew.cmu.edu
//Section A
//Project 10

var px = [];
var py = [];
var div = 10;
var noiseOn = false;
var myLeftTop;
var myRightTop;
var myLeftBot;
var myRightBot;

function preload() {
    myLeftTop = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/LeftTop-1.wav");
    myRightTop = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/RightTop.wav");
    myLeftBot = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/LeftBot.wav");
    myRightBot = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/RightBot.wav");
    // call loadImage() and loadSound() for all media files here
}


function soundSetup() { // setup for audio generation
    // setting initial volume
    myLeftTop.setVolume(0.1); 
    myLeftBot.setVolume(0.1); 
    myRightTop.setVolume(0.1); 
    myRightBot.setVolume(0.1); 
}


function setup() {
    createCanvas(400, 400); //create canvas
    for (var i = 0; i < div; i++) {
        px.push(i * (height / div)); //create array for creating grid
        py.push(i * (height / div));
    }
    useSound();
}

function mousePressed() { //play when mouse is pressed
    myLeftTop.play(); 
    myLeftBot.play(); 
    myRightTop.play(); 
    myRightBot.play();
}

function draw() {
    background(0);
    stroke(255);
    strokeWeight(0.5);
    //creates the grid
    for (var i = 0; i < px.length; i++) {
        line(px[i], 0, px[i], height);
        line(0, py[i], width, py[i]);
        }
    //draws circles on the grid
    for (var i = 0; i < px.length - 1; i++) {
        for(var j = 0; j < px.length - 1; j++) {
            fill(100, 255/(i), 255/j);
            //circles resond to the mouse position
            if (dist(mouseX, mouseY, px[i+1], py[j+1]) < 20) {
                ellipse(px[i+1], py[j+1], 50, 50);
            }
            else {
                strokeWeight(0);
                ellipse(px[i+1], py[j+1],
                        1300/dist(mouseX, mouseY, px[i+1], py[j+1]),
                        1300/dist(mouseX, mouseY, px[i+1], py[j+1]));
            }
            
        }
        
    }
    //the volume of each soundtrack depends on the distance of the mouse to the corners
    myLeftTop.setVolume((dist(mouseX, mouseY, 0, 0))^2/2500); 
    myLeftBot.setVolume((dist(mouseX, mouseY, 0, height))^2/2500); 
    myRightTop.setVolume((dist(mouseX, mouseY, width, 0))^2/2500); 
    myRightBot.setVolume((dist(mouseX, mouseY, width, height))^2/2500);
    

}

Danny Cho – LookingOutwards 9

For this week’s LookingOutwards, I was inspired by Refik Anadol’s work, Melting Memories, previously reviewed by Kristine Kim, my classmate. Initially, the display that replicates the characteristics of solid and liquid caught my attention, assuming that it is actually a material, not a 2D display. However, it turned out that it was a visualization on a screen.

This made me curious to see how can real physical materials could become ephemeral. It certainly is magical to imagine a tangible form constantly morphing or growing into something else. I also was intrigued by New Balance’s 3D printed midsole, seeing how generative design is affecting a 3D form that will later become tangible and be used in actual products.

This project was reviewed by another classmate Ilona Altman. With Melting Memories project, this led me wondering and eager to see a physical form shifting in realtime as a reaction to generative design algorithm.

Danny Cho – Project 9


Sketch

I made a self portrait generator that recognizes and connects bright red spots in an image and emphasizes / connects them. I also tried to imitate the characteristic of water color by playing with the transparency of ellipses being drawn.

This is the original image

This is what has been generated by the algorithm

//Danny Cho
//Project 9
//changjuc@andrew.cmu.edu
//section A

var underlyingImage;
var pixColor;
var squareColor;

//arrays for red spots' coordinates
var redSpotsX = [];
var redSpotsY = [];

//preloads image
function preload() {
    var myImageURL = "https://i.imgur.com/5PlTu4V.jpg";
    underlyingImage = loadImage(myImageURL);
}

//sets up the canvas
function setup() {
    createCanvas(750, 1334);
    background(0);
    underlyingImage.loadPixels();
    frameRate(1000);
}

function draw() {
    //random pixels chosen
    var px = random(width);
    var py = random(height);
    //limiting the randomness to be integers within the canvas boundary
    var ix = constrain(floor(px), 0, width-1);
    var iy = constrain(floor(py), 0, height-1);
    //color at the location
    var theColorAtLocationXY = underlyingImage.get(ix, iy);
    pixColor = color(theColorAtLocationXY);

    //if red value is the highest number out of RGB palette,
    //and is higher than 230, the part becomes pure red
    //and saves the coordinates of them for the lines to be drawn
    if (Math.max(red(pixColor), green(pixColor), blue(pixColor)) == red(pixColor)
        & red(pixColor) > 230) {
        redSpotsX.push(ix);
        redSpotsY.push(iy);
        
        pixColor = color(255, 0, 0);
    }
    //connects the red spots with lines
    for (var i = 0; i < redSpotsX.length - 1; i++) {
            stroke(200, 0, 0);
            strokeWeight(.1);
            line(redSpotsX[i], redSpotsY[i],
                 redSpotsX[i + 1], redSpotsY[i + 1]);
        }

    noStroke();
    // changes the transparency of the ellipses
    pixColor.setAlpha(100);
    fill(pixColor);
    ellipse(px, py, 15, 15);

}

Danny Cho – LookingOutwards 08

Mike Tucker is an interaction designer who works in the realm of virtual spaces and generative design and mixed reality. He has worked for BBC’s visual effect department and is currently working at Magic Leap, creating future of spatial computing.

His work in collaboration with Sigur Ros, a musician makes me wonder the capability of generative design. The images that are provided for the audience as explanation inspires me to take a step into it. Especially, a quote said by the musician blew my mind, “What if you can have a whole world as your album jacket.” I am curious what the next step would be, and how much in sync different sensory inputs will become as the time passes.

He displays his work in two different backgrounds: in the context of actual usage/installation, and by itself as in the black/white background. This strategy allows the audience be able to take a step back as well as forth, by providing macro and micro perspective about his work.

http://mike-tucker.com/15/
http://mike-tucker.com/15/Tonandi-Loop.mov

I am amazed thinking about how much knowledge about this field and other adjacent ones Mike would have. Regarding space, perspective and music. I want to be a designer where I have a broad understand of the world around me and be able to manipulate my knowledge to create a new reality.