Project-11-Landscape

I take references from this animation/rendering competition and made this robot pushing a sphere in an alien planet:

I have trees generation in the background

boulders in front

and hills in the back

/*
 * Andrew J Wang
 * ajw2@andrew.cmu.edu
 * Section A
 *
 * This Program is walking
 */

//sets of links

//location of feets of the walking person
var pointXG = 0;
var pointYG = 0;

//steps (frame) locations of the feets
var stepsX = [0,1,2,3,4,5,6,7,8,9,10,10,10,10,10,10,9,8,7,6,5,4,3,2,1,0];
var stepsY = [0,0.5,1,1.5,2,2.5,3,3.5,4,4.5,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0];

//counters for multiple frames (feet + mountains)
var counter = 0;

//location of the person on the drawing
var locationX = 120;
var locationY = 200;

//arrays for trees for clusters of boulders 
var trees = [];
var clusters = [];

//set a array for land heights (FROM PREVIOUS ASSIGNMENT)
var landHeight = [];
var landHeight2 = [];

//create noice parameter and steps
var noiseParam = 0;
var noiseParam2 = 0;
var noiseStep = 0.005;
var noiseStep2 = 0.01;

function setup() {
    createCanvas(480,300);
    // create an initial collection of trees
    for (var i = 0; i < 5; i++){
        var rx = random(width);
        trees[i] = makeTrees(rx);
    }

    // create an initial collection of boulders
    for (var i = 0; i < 10; i++)
    {
        var rx2 = random(width);
        clusters[i] = makeClusters(rx2);
    }

    //hill #1
    for (var k=0; k<=480; k++)
    {   
        //get noise through noise param
        var n = noise(noiseParam);
        //remapping based on height
        var value = map(n,0,1,0,height/4)+130;
        //add to array
        landHeight.push(value);
        //plus steps
        noiseParam += noiseStep;
    }

    //hill #2
    for (var k=0; k<=480; k++)
    {   
        //get noise through noise param
        var n2 = noise(noiseParam2);
        //remapping based on height
        var value2 = map(n2,0,1,0,height/3)+80;
        //add to array
        landHeight2.push(value2);
        //plus steps
        noiseParam2 += noiseStep2;
    }

}


function draw() {
    background(100);

    //MOON
    push();
    noStroke();
    fill(255,255,220);
    ellipse(380,0,250,250);
    pop();

    //draw first sets of hill
    push();
    noStroke();
    fill(240);
    beginShape();
    //fist vertex
    vertex(0,(locationY+70+60)*0.8-80);
    //for loop to grab all the vertex
    for (var k=0; k<=480; k++)
    {   
    vertex(k,landHeight2[k]);
    }
    //last vertex
    vertex(width,(locationY+70+60)*0.8-80);
    endShape(CLOSE);
    //adding another point by shifting
    var n2=noise(noiseParam2);
    var value2 = map(n2,0,1,0,height/3)+80;
    noiseParam2 += 0.01/20;
    //slowing the speed of refreshing by using a counter
    if (counter%40==0)
    {
        landHeight2.shift();
        landHeight2.push(value2);
    }
    pop();

    //draw second sets of hill
    push();
    noStroke();
    fill(220);
    beginShape();
    //fist vertex
    vertex(0,(locationY+70+60)*0.8-80);
    //for loop to grab all the vertex
    for (var k=0; k<=480; k++)
    {   
    vertex(k,landHeight[k]);
    }
    //last vertex
    vertex(width,(locationY+70+60)*0.8-80);
    endShape(CLOSE);
    //adding another point by shifting
    var n=noise(noiseParam);
    var value = map(n,0,1,0,height/4)+130;
    noiseParam += 0.005/5;
    //slowing the speed of refreshing by using a counter
    if (counter%10==0)
    {
        landHeight.shift();
        landHeight.push(value);
    }
    pop();

    //ground plane
    push();
    noStroke();
    fill(200);
    rect(0,(locationY+70+60)*0.8-80,width, height-((locationY+70+60)*0.8-80));
    pop();

    //set trees and clusters by refreshing the removed objects and clusters
    updateDisplay();
    removeTrees();
    addTrees();
    removeClusters();
    addClusters();

    //walking person
    strokeWeight(3);
    push();

    //scaling it
    scale(0.6);
    translate(0,150);
    walking(locationX,locationY);
    walking2(locationX,locationY);
    body(locationX,locationY);

    //butt
    push();
    strokeWeight(2);
    ellipse(locationX,locationY,15,15);
    pop();
    pop();

    //display clusters in the end
    updateDisplay2();

}


//refreashing trees and display them
function updateDisplay(){
    for (var i = 0; i < trees.length; i++){
        trees[i].move();
        trees[i].display();
    }
}

//refreshing boulders and display them
function updateDisplay2(){
    for (var i = 0; i < clusters.length; i++){
        clusters[i].move();
        clusters[i].display();
    }
}

//removing trees if it is too far away from the screen
function removeTrees(){
    var treesToKeep = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x + trees[i].breadth > 0) {
            treesToKeep.push(trees[i]);
        }
    }
}

//removing boulders if it is too far away from the screen
function removeClusters(){
    var clustersToKeep = [];
    for (var i = 0; i < clusters.length; i++){
        if (clusters[i].x + clusters[i].breadth > 0) {
            clustersToKeep.push(clusters[i]);
        }
    }
}

//add trees 100 units away from border
function addTrees() {
    var Likelihood = 0.01; 
    if (random(0,1) < Likelihood) {
        trees.push(makeTrees(width+100));
    }
}

//add boulders 500 units away from border
function addClusters() {
    var Likelihood = 0.01; 
    if (random(0,1) < Likelihood) {
        clusters.push(makeClusters(width+500));
    }
}

//set trees values and function
function makeTrees(birthLocationX) {
    var tree = {x: birthLocationX,
                breadth: 100,
                speed: -0.4,
                y: 160+round(random(20)),
                treeHeight: round(random(40,50)),
                size: round(random(30,50)),
                move: objectMove,
                display: treeDisplay}
    return tree;
}

//set boulders values and functions
function makeClusters(birthLocationX) {
    var tree = {x: birthLocationX,
                breadth: 100,
                speed: -2.0,
                treeHeight: round(random(40,50)),
                size: round(random(200,350)),
                move: object2Move,
                display: clusterDisplay}
    return tree;
}

//move objects 
function objectMove() {
    this.x += this.speed;
}

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

//draw trees
function treeDisplay() {
    line(this.x, this.y , this.x, this.y+this.treeHeight);

    push();
    translate(this.x,this.y);
    rectMode(CENTER);
    noFill();
    strokeWeight(1);

    push();
    rotate(-counter/180*Math.PI);
    rect(0,0,this.size,this.size);
    pop();

    push();
    rotate(counter/180*Math.PI);
    rect(0,0,this.size-10,this.size-10);
    pop();


    pop();
}

//draw bolders
function clusterDisplay() {
    push();
    fill(0);
    ellipse(this.x,height+30,this.size,this.size/2);
    strokeWeight(1.5);
    noFill();
    ellipse(this.x,height+30,this.size+20,this.size/2+10);
    pop();
}

//leg #1
function walking(xL,yL)
{   
    //counter/10 get frame number
    var counterK = Math.floor(counter/10)%(stepsX.length);

    //Feet locations
    pointXG = xL-70+stepsX[counterK]*6;
    pointYG = yL+70-stepsY[counterK]*4;

    //Pathegorean theorm to get the knee and legs
    var dis = Math.sqrt((xL-pointXG)*(xL-pointXG)+(yL-pointYG)*(yL-pointYG));
    var num = (10000)-(dis*dis);
    var sid = sqrt(num);
    var midX = xL-(xL-pointXG)/2;
    var midY = yL-(yL-pointYG)/2;
    var tan = atan2(pointXG-xL,pointYG-yL);
    ellipse ((pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2, 5,5);
    line(xL,yL,(pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2);
    line(pointXG,pointYG,(pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2);

    //feet bending
    if (stepsY[counterK]==0)
    {
        line(pointXG,pointYG,pointXG+20,pointYG);
    }
    else
    {
        var tanF = atan2(Math.sqrt(400-stepsY[counterK]*2),stepsY[counterK]*4);
        line(pointXG,pointYG,pointXG+20*sin(tanF),pointYG+20*cos(tanF));
    }

    counter++;
}

//repeat for the second leg
function walking2(xL,yL)
{   
    var counterK = (Math.floor(counter/10)+stepsX.length/2)%(stepsX.length);
    pointXG = xL-70+stepsX[counterK]*6;
    pointYG = yL+70-stepsY[counterK]*4;
    var dis = Math.sqrt((xL-pointXG)*(xL-pointXG)+(yL-pointYG)*(yL-pointYG));
    var num = (10000)-(dis*dis);
    var sid = sqrt(num);
    var midX = xL-(xL-pointXG)/2;
    var midY = yL-(yL-pointYG)/2;
    var tan = atan2(pointXG-xL,pointYG-yL);
    ellipse ((pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2, 5,5);
    line(xL,yL,(pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2);
    line(pointXG,pointYG,(pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2);
    if (stepsY[counterK]==0)
    {
        line(pointXG,pointYG,pointXG+20,pointYG);
    }
    else
    {
        var tanF = atan2(Math.sqrt(400-stepsY[counterK]*2),stepsY[counterK]*4);
        line(pointXG,pointYG,pointXG+20*sin(tanF),pointYG+20*cos(tanF));
    }

    counter++;

}

//body parts and other stuff
function body(xL,yL)
{
    var counterK = (Math.floor(counter/10)+stepsX.length/2)%(stepsX.length);
    var counterK2 = (Math.floor(counter/10)+10)%(stepsX.length);
    var counterK3 = (Math.floor(counter/10)+25)%(stepsX.length);
    push();
    strokeWeight(2);
    fill("grey")
    //shoulder 1
    ellipse(xL+35+stepsY[counterK2],yL-45-stepsX[counterK2],30,30);

    //hand
    ellipse(xL+35+60,yL-45-stepsX[counterK]+10,10,10);
    pop();

    //arms
    line(xL+35+stepsY[counterK],yL-45-stepsX[counterK],xL+35+30,yL-45-stepsX[counterK]+20);
    line(xL+35+30,yL-45-stepsX[counterK]+20,xL+35+60,yL-45-stepsX[counterK]+10);

    //body
    line(xL,yL,xL+35+stepsY[counterK],yL-45-stepsX[counterK]);

    push();
    fill("black");
    ellipse(xL+35+30,yL-45-stepsX[counterK]+20,5,5);
    pop();

    //Round thingy
    push();
    noFill();
    strokeWeight(2);
    ellipse(xL+35+175,yL-45,230,230);
    fill(255);
    ellipse(xL+35+175,yL-45,220,220);

    stroke(255);

    pop();


    //shoulder 2
    push();
    noStroke();
    ellipse(xL+35+stepsY[counterK2],yL-45-stepsX[counterK2],15,15);
    pop();

    //head
    push();
    strokeWeight(1);
    noFill();
    translate(xL+55+stepsY[counterK3],yL-85-stepsX[counterK3]);
    rectMode(CENTER);
    rotate(-counter/180*Math.PI);
    rect(0,0,40,40);
    rect(0,0,30,30);
    pop();

    push();
    strokeWeight(1);
    noFill();
    translate(xL+65+stepsY[counterK2]*2,yL-95-stepsX[counterK2]);
    rectMode(CENTER);
    rotate(counter/180*Math.PI);
    rect(0,0,25,25);
    rect(0,0,30,30);
    pop();

    push();
    strokeWeight(1);
    noFill();
    translate(xL+45+stepsY[counterK]*2,yL-75-stepsX[counterK]);
    rectMode(CENTER);
    rotate(counter/180*Math.PI);
    rect(0,0,25,25);
    rect(0,0,15,15);
    pop();

}





Looking Outwards – 11

Link: https://www.plagiarismtoday.com/2021/03/16/nfts-and-copyright/

By reading this article, I understand how NFTs really work. So, according to this article owning an NFT doesn’t necessarily mean someone actually owns the copyright of this art piece. However, it isn’t completely useless, as NFTs can also be considered as an internet-signed copy of the work. Because of the fact that the NFTs function as a signed copy of the original art piece, they can help the producers financially. On the other hand, some people who didn’t create those works can also tokenize those works can really damage the career of the artists who actually created those works. In other words, NFT platforms not only provide an easier way to allow society to donate and help digital artists but also create an opportunity for those who are even involved in any art creation process to drain money from those creators. However, in a few years, courts will eventually be involved in such cases to protect those artists eventually. 

CITATION:

Bailey, J. (2021, March 16). NFTs and copyright. Plagiarism Today. Retrieved November 19, 2022, from https://www.plagiarismtoday.com/2021/03/16/nfts-and-copyright/ 

Project 10 – SANIC

Sanic make “dash” noises every now and then

Eggman has “intro” and “escape” lines

Rings make sounds when grabbed by sanic

Knuckle makes sounds in the end

/*
 * Andrew J Wang
 * ajw2@andrew.cmu.edu
 * Section A
 *
 * This Program is Sanic
 */

//rotation variables for limb movements for sanic and the coins
var rot = 0;
//controls whether the limbs are moving forwards or backwards
var forward = true;
//sanic locations
var x=0;
//eggman image
var egg;
//eggman Ylocation
var eggY = -150;
//uganda knuckle's Ylocation
var ugandaY = 450;

//Green Hill Zone notes (BACKGROUND MUSIC)
var pitch = [72,69,72,71,72,71,67, 0, 69,76,74,72,71,72,71,67, 0, 72,69,72,71,72,71,67, 0, 69,69,65,69,67,69,67,60, 0];
var duration = [3,9,3,9,3,9,12, 15, 3,3,9,3,9,3,9,12, 15, 3,9,3,9,3,9,12, 15, 3,3,9,3,9,3,9,12, 15];

//counter for durations
var counter = 0;
//which note on the pitch list to play
var note = 0;

//rings' existance
var coin = [true,true,true,true,true];

//sound variables
var eggmanIntro;
var ringSound;
var dawae;
var spinDash;
var eggmanDefeat

//https://courses.ideate.cmu.edu/15-104/f2022/wp-content/uploads/2022/11/name-eggman.wav
//https://courses.ideate.cmu.edu/15-104/f2022/wp-content/uploads/2022/11/Sonic_Ring_Sound_Effect.wav
//https://courses.ideate.cmu.edu/15-104/f2022/wp-content/uploads/2022/11/do-you-know-the-way.wav
//https://courses.ideate.cmu.edu/15-104/f2022/wp-content/uploads/2022/11/Spin.wav
//https://courses.ideate.cmu.edu/15-104/f2022/wp-content/uploads/2022/11/no.wav


//loading the images and sounds
function preload() {
    egg = loadImage("https://i.imgur.com/Wy46mQF.png");
    uganda = loadImage ("https://i.imgur.com/HRB5kdy.png");
    eggmanIntro = loadSound("https://courses.ideate.cmu.edu/15-104/f2022/wp-content/uploads/2022/11/name-eggman.wav");
    ringSound = loadSound("https://courses.ideate.cmu.edu/15-104/f2022/wp-content/uploads/2022/11/Sonic_Ring_Sound_Effect.wav");
    dawae = loadSound("https://courses.ideate.cmu.edu/15-104/f2022/wp-content/uploads/2022/11/do-you-know-the-way.wav");
    spinDash = loadSound("https://courses.ideate.cmu.edu/15-104/f2022/wp-content/uploads/2022/11/Spin.wav");
    eggmanDefeat = loadSound ('https://courses.ideate.cmu.edu/15-104/f2022/wp-content/uploads/2022/11/no.wav');
}

//setups Don't think I need to elaborate
function setup() {
    createCanvas(600,300);
    useSound();
    frameRate(20);
}

function soundSetup() { 
    osc = new p5.Oscillator();
    osc.amp(0.25);
    eggmanIntro.setVolume(1.0);
    ringSound.setVolume(0.5);
    dawae.setVolume(0.5);
    spinDash.setVolume(0.5);
    eggmanDefeat.setVolume(1.0);
    osc.setType('square');
    osc.start();
}



function draw() {

    background(255);
    //rotation till 1 then change directions
    if (rot>=1 || rot <=-1)
    {
        forward = !forward;
    }
    if (forward)
    {
        rot+=0.1;
    }
    else
    {
        rot-=0.1;
    }

    //move sanic by 1 per frame
    x+=1;

    //check whether sanic ran pass through those rings or not
    for (var k=0; k<5; k++)
    {
        if (x>(100+k*100))
        {
            coin[k] = false;
        }
    }

    //if sanic is on the ring play ring sound
    if (x%100==0 & x<600 && x>0)
    {
        ringSound.play();
    }

    //sanic spins every now and then if he's on the screen
    if (x%100==50 & x<=600 && x>=0)
    {
        spinDash.play();
    }

    //rings
    ring(100,170,rot,coin[0]);
    ring(200,170,rot,coin[1]);
    ring(300,170,rot,coin[2]);
    ring(400,170,rot,coin[3]);
    ring(500,170,rot,coin[4]);

    //eggman shows up
    if (eggY<50)
    {eggY+=2;}

    //eggman "escapes"
    if (x>300 & eggY<1000)
    {
        eggY = 50 + (x-300) * (x-300);
    }

    //eggman intro right before he stops
    if (eggY==48)
    {
        eggmanIntro.play();
    }

    //eggman says no moment after he's defeated
    if (eggY==54)
    {
        eggmanDefeat.play();
    }
    //eggman image
    eggman(300,eggY);

    //sanic
    sanicLimbs(x,100,rot);
    sanic(x,100);

    //uganda knuckle shows up
    if (x>700 & ugandaY > 200)
    {
        ugandaY -=2;
    }

    //"DO YOU KNOW DA WAE" before stoping
    if (ugandaY==202)
    {
        dawae.play();
    }

    //kunckle
    knuckle(300,ugandaY);


    //if pitch is 0 stop playing
    if (pitch[note] == 0)
    {
        osc.stop();
    }

    //if pitch before is 0 but this note isn't restart
    else if (pitch[note-1] == 0 & pitch[note] != 0)
    {
        osc.start();
    }

    //play notes
    osc.freq(midiToFreq(pitch[note]));

    //duration counter ++
    if (counter < duration[note] & note < pitch.length)
    {
        counter++
    }
    //if reach max duration change note and reset
    else if (counter >= duration[note] && note < pitch.length)
    {   
        counter = 0;
        note++;
    }
    //if reach the end restart from the beginning to loop
    else
    {
        note=0;
    }

}

//drawing sanic
function sanic(xL,yL)
{   
    push();
    translate(xL,yL);
    noStroke();
    stroke(0);
    fill("blue");
    curve(-10,100,-7,-10,-50,-30,-50,50);
    curve(-10,100,-7,10,-50,10,-50,50);
    curve(-10,100,-7,30,-65,20,-50,100);
    curve(-10,100,-7,40,-50,30,-50,50);
    curve(-10,100,-7,90,-75,70,-50,200);
    strokeWeight(1);
    ellipse(0,25,10,20);
    ellipse(0,0,50,45);
    ellipse(0,70,70,75);
    fill(255,255,170);
    ellipse(0,70,40,45);
    ellipse(3,15,25,10);
    fill(255);
    ellipse(10,0,15,13);
    ellipse(-8,0,15,10);
    fill(0);
    ellipse(12,0,3,3);
    ellipse(-6,0,3,3);
    ellipse(0,8,4,4);
    stroke(5);
    curve(-7,5,-7,15,16,15,16,5);
    pop();
}

//drawing sanic's llimbs 
function sanicLimbs (xL,yL,r)
{
    push();
    translate(xL,yL);

        push();
        translate(15,50);
        rotate(r);
        fill("blue");

        beginShape();
        vertex(0, 0);
        bezierVertex(0,0,30,-50,60,0);
        bezierVertex(60,0,30,-25,0,0);
        endShape();

        fill(255);
        ellipse(60,0,20,20);
        pop();


        push();
        translate(-15,60);
        rotate(r);
        fill("blue");

        beginShape();
        vertex(0, 0);
        bezierVertex(0,0,-30,-55,-60,0);
        bezierVertex(-60,0,-30,-15,0,0);
        endShape();

        fill(255);
        ellipse(-60,0,30,25);
        pop();

        push();
        translate(0,100);
        rotate(r);
        fill("blue");

        beginShape();
        vertex(0, 0);
        bezierVertex(0,0,-60,0,-60,60);
        bezierVertex(-60,60,-60,40,0,0);
        endShape();

        fill("red");
        ellipse(-70,60,40,20);
        pop();

        push();
        translate(20,100);
        rotate(r);
        fill("blue");

        beginShape();
        vertex(0, 0);
        bezierVertex(0,0,0,40,60,60);
        bezierVertex(60,60,0,80,0,0);
        endShape();

        fill("red");
        ellipse(70,60,40,20);
        pop();


    pop();
}

//ring spins through scalling
function ring (xR,yR,sc,sh)
{
    if (sh==true)
    {
    push();
    translate(xR,yR);
    scale(sc,1.0);
    fill("gold");
    ellipse(0,0,50,50);
    fill(255);
    ellipse(0,0,30,30);
    pop();
    }

}

function eggman (xE,yE)
{
    image(egg,xE,yE,150,150);
}

function knuckle (xU, yU)
{
    push();
    imageMode(CENTER);
    image(uganda,xU, yU, 250,250);
    pop();
}

Project 09 : Computational Portrait

The Image is based on how Octopus uses their camouflage:

So Basically I created a bunch of particles that ages and disappear eventually:

when those particles first appear they growth rapidly then they slowly shrink and fade away

Base Image:

Base Image

/*
 * Andrew J Wang
 * ajw2@andrew.cmu.edu
 * Section A
 *
 * This Program is Face
 */

//face image for preload the data
let faceImage;
//array of global particles
var particles = [];

//preload image
function preload(){
    faceImage = loadImage("https://i.imgur.com/i3WmsKd.jpeg");
}


function particleStep() {
    //age of the particles 
    this.age++;

    //shrine slowly after 45 age
    if (this.age % 2 == 0 & this.age >= 45)
        {
            this.sz = this.sz * 0.98;
        }
    //grow rapidly before 45 age
    else if (this.age % 2 == 0 & this.age < 45)
        {
            this.sz = this.sz * 1.1;
        }

}
 
 
function particleDraw() {
    push();
    //grab color based on the location on the image
    var kolor = faceImage.get(this.x*2, 220+this.y*2);
    fill(kolor);
    noStroke();
    rectMode(CENTER);
    //create rectangle based on location size and color
    rect(this.x, this.y, this.sz, this.sz);
    pop();
}
 

//create color particles
function makeParticle(px, py, size) {
    p = {x: px, y: py,
         age: 0,
         sz: size,
         stepFunction: particleStep,
         drawFunction: particleDraw
        }
    return p;
}
 
 
function setup() {
    createCanvas(480,480);
    frameRate(120);
}


function draw() {
    background(220);
    stroke(0);

//create 30 particles per fram just to fill the whole image with particles
    for (var n=0; n<30; n++)
    {
        //create particles at random location on the canvas, origin size = 1
        var p = makeParticle(random(480), random(480),1);
        particles.push(p);
    }

    //new particles to refresh
    newParticles = [];
        for (var i = 0; i < particles.length; i++){ // for each particle
        var k = particles[i];
        //draw and refresh particles
        k.stepFunction();
        k.drawFunction();
        if (k.age < 250) {
            //if younger than 250 keep them if not they are gone
        newParticles.push(k);
        }
    }
        // particles refreshed by the new particles
        particles = newParticles;

}

Looking Outwards -09 : A Focus on Women and Non-binary Practitioners in Computational Art

I really admire Camille Utterback’s project Text Rain not because of the complexity of the program itself, but when the project is produced. First, I need to introduce who Camille is. She is an American Interactive Installation artist who graduated from William College and gained her master’s degree from the Interactive Telecommunications Program at New York University’s Tisch School of the Arts. Why I prefer her Text Rain installation is because her work is groundbreaking or one of the first of such type (Interactive Installation). Her work might not look impressive at our time, since her program is basically about capturing the silhouette of pedestrians and making random letters float on them. However, because of this “simple” (compared to nowadays interactive projects) installation, which was created during 1999, more and more interactive public installations that we might see on streets were created, making Camille Utterback a pioneer of such computational forms of art.

Text Rain – by Camille Utterback and Romy Achituv:

Link: http://camilleutterback.com/projects/text-rain/

Looking Outwards – 08

This week I watched the lecture of Jennifer Daniel, who is an American designer, editor, and illustrator, and she also leads the Emoji Subcommittee for the Unicode Consortium, while working for The New York Times and The New Yorker. What people might not know is that Jennifer initiated the gender-inclusive representation movement for the emoji creation group around the globe that shares the same sets of Unicodes for emojis. Among the new gender-inclusive emojis that she created, Mrs. Claus, Woman in Tuxedo, and Man in Veil are the most famous ones. I admire the movement because I think as we develop, we should make all aspects of our modern technology more inclusive for more and more people, to further facilitate our advances. To do this, she believes that we need more and more emojis that can better represent individuals, thus she and her team developed several emoji-related apps such as Emoji Kitchen. While introducing those emoji-related apps during her lecture, she started with the very core and basic definition and evolutions of emoji, then explained every issue of the emojis that we are using and why we should improve them, eventually demonstrating how her works can solve those problems. I enjoy watching her lecture because of how direct her approach to the topic is and how simple she made her works look to non-programmers.

Eyeo 2017 – Jennifer Daniel from Eyeo Festival on Vimeo.

Emoji Kitchen Examples:

Emoji Kitchen

Jennifer Daniel’s Website/Blogs: https://httpcolonforwardslashforwardslashwwwdotjenniferdanieldotcom.com/category/blog/

Project 7 – Curves

It slowly draws a butterfly if u move your mouse from left to right!

/*
 * Andrew J Wang
 * ajw2@andrew.cmu.edu
 * Section A
 *
 * This Program is ButterFly and Flower Curves
 */



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

function draw() {
    background(220);
//create constrain for the rest of the codes' mouse X and Y
    var conY = constrain(mouseY,0,height);
    var conX = constrain(mouseX,0,width);
//create two array sets for Flower's X and Y
    var pointX2 = [];
    var pointY2 = [];
//remapping A and B with mouse X and Y
//A => inner circle, B => outer circle 
    var a = map(conY,0,width,50,150);
    var b = map(conX,0,width,5,15);
    var h = 20;
//using for loop to get points
    for (var k=0; k<=2000; k+=1)
    {   
        //2 PI but 2000 points
        var t=k/1000*Math.PI;
        //epitrochoid formulas for X and Y
        var xP2= width/2+((a+b)*Math.cos(t)-h*cos(((a+b)/b)*t));
        var yP2= height/2+((a+b)*Math.sin(t)-h*sin(((a+b)/b)*t));
        //push values to lists
        pointX2.push(xP2);
        pointY2.push(yP2);
    }
//connect vertexes and close them
    push();
    noFill();
    //stroke
    stroke(0);
    strokeWeight(5);
    beginShape();
    for (var k=0; k<=2000; k+=1)
    {   
        vertex(pointX2[k],pointY2[k]);
    }
    endShape(CLOSE);
    pop();
//connect vertexes and close them
    push();
    //no stroke only fill
    fill(255,200,200);
    strokeWeight(0);
    beginShape();
    for (var k=0; k<=2000; k+=1)
    {   
        vertex(pointX2[k],pointY2[k]);
    }
    endShape(CLOSE);
    pop();
//same logics but this time it is the butterfly curves
    var pointX = [];
    var pointY = [];
    for (var k=0; k<=2400; k+=1)
    {   
        //Mouse Y dictate how big the butterfly will be
        var xP= width/2-map(conY,0,width,0,100)*Math.sin(k/100*Math.PI)*((Math.exp(Math.cos(k/100*Math.PI))) - (2*Math.cos(4*(k/100*Math.PI))) - (Math.pow(Math.sin((k/100*Math.PI)/12), 5)));
        var yP= height/2-map(conY,0,width,0,100)*Math.cos(k/100*Math.PI)*((Math.exp(Math.cos(k/100*Math.PI))) - (2*Math.cos(4*(k/100*Math.PI))) - (Math.pow(Math.sin((k/100*Math.PI)/12), 5)));
        pointX.push(xP);
        pointY.push(yP);
    }

//this time I use smaller circles to represent the curves
    fill (90,map(conY,0,width,0,255),100);
    stroke (90,map(conY,0,width,0,255),100);
    //mouse X dictates how many circles
    for (var k=0; k<=conX*4; k+=1)

    {
        circle (pointX[k],pointY[k],3);
    }
    }




Looking Outwards – 07

I really admire how Chris Harrison did his color flower, and the way he made his algorithm to create these sets of patterns is amazing and visually satisfying to look at. Although he didn’t specify how he made his algorithm, I can still guess a few of the steps that he took to make this work of art. First he made a set of point data within a boundary of a circle, and assigned values of those points based on the distance of them towards the center of the circle. Then, he used the points and the center of the circle to create vectors from the points and go away from the center of the circle. Eventually, based on hue value stored on each circle, they grab the name of the named color and list them on the vector using the color with the corresponding hue value, making this image a colored and worded art piece. Also, I love that he’s able to use the same algorithm to generate images not just circular but other shapes, such as spirals and others. 

Link: https://www.chrisharrison.net/index.php/Visualizations/ColorFlower

Looking Outwards 06: Randomness

I really like June Lee’s Cubic Tower, and I found randomness in their design. The reason why I admire their work on using randomness in computational design (this time is Grasshopper), while the randomness is still controllable. For example, they use boundaries and populate geometry to get computed random points inside the extruded square base using seeds, then they are able to create smaller cubes with only 3 different sizes using the Octree functions, which creates cubes by determining how dense the points are in the area, to be the components of the tower. Even after creating the randomness (that is inside a boundary), they are still able to add details afterward by using functions that turn the mess into individual components. Even after creating the cluster of computer generated randomness, they are still able to split the randomness randomly to add different materials towards the final product. I was really amazed by their ability to fully control the randomness even after already initializing the random points. 

Link:

https://www.youtube.com/watch?v=ETWWx88iXec

Cubic Tower by June Lee

Project 06 – Abstract Clock

Explanation for this abstract clock:

  1. The sun/moon is the HOUR HAND
  2. The duck is the MINUTE HAND
  3. The clouds’ circle is the SECOND HAND
Clock diagram

/*
 * Andrew J Wang
 * ajw2@andrew.cmu.edu
 * Section A
 * Project-05
 *
 * This program draws clock
 */

//set randam numbers for the wavy lines of reflection of the sun
var rando = 0;
//set sin values for waving reed
var drR=0;

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

function draw() {
//get dates for hours, minutes, seconds,and miliseconds
var dt = new Date();
//get location for ducks (MINUTES)
var dx=480-dt.getMinutes()*8-dt.getSeconds()*8/60;
//get location for the sun (HOURS)
var dy=(18-dt.getHours()-dt.getMinutes()*1/60-dt.getSeconds()*1/3600)*300/12;

//background
background(80,50,180);

//create reflection of the sun
if (dy>-125 & dy<425)
{
    sunReflection (dy);
    push();
    //hiding the additional parts above sea level
    fill (80,50,180);
    rect(100,200,280,100);
    pop();
}

//show moon between 6PM to 6AM
if (dy<62)
{
    moon (300+dy,125);
}

else if (dy>238)
{
    moon ((dy-300),125);
}

//create moutains and their reflections
moutain(-50,300,150,100);
moutainReflection(-50,300,150,75);

moutain(50,300,110,50);
moutainReflection(50,300,110,37.5);

moutain(350,300,250,50);
moutainReflection(350,300,250,37.5);

//gradiant sky and sea
gradiantScreen (0,300);
gradiantScreenReverse (300,600);

//draw horizon
stroke(255);
strokeWeight(1);
line (0,300,width,300);

//set sun between 6AM to 6PM
if (dy>-125 & dy<425)
{
    sun(dy,125);
}

//creating lands
land2(-100,480,500,50);
land(-200,480,400,75);

//creating clouds (SECONDS)
clouds();

//creating ducks
duck(dx,350);
duck(dx+480,350);
duck(dx-480,350);

//creating reeds
reed2();
reed();

}

//gradiant sky
function gradiantScreen (y1,y2)
{       
    //for loop changing alpha values for small rectangles
    for (var k=0; k<(y2-y1); k++)
    {   
        noStroke();
        fill (255,220,220,150/(y2-y1)*k);
        rect (0,y1+k,width,1);
    }
}

//gradiant sea but the same as gradiant sky but in reverse
function gradiantScreenReverse (y1,y2)
{
    for (var k=0; k<(y2-y1); k++)
    {   
        noStroke();
        fill (255,220,220,180/(y2-y1)*k);
        rect (0,y2-k,width,1);
    }
}

//creating sun
function sun (y,r)
{       
    fill(255,255,180);
    //outline of the sun
    strokeWeight(5);
    stroke(255,255,230,50);
    var angle = acos((300-y)/(r/2));
    //make arc if parts of the sun is below horizon
    if (300-y<=r/2)
    {
        arc (width/2,y,r,r,-(Math.PI/2-angle)+Math.PI ,2*Math.PI + (Math.PI/2-angle),OPEN);
    }
    //dont make arc if it is not
    else
    {
        circle(width/2,y,r);
    }
}
//creating moon same as sun but having a different arc/circle for the missing piece
function moon (y,r)
{
    fill(255,255,180);
    strokeWeight(0);
    stroke(255,255,230,50);
    var anglem1 = acos((300-y)/(r/2));
    var anglem2 = acos((300-y+20/Math.sqrt(2))/(r/2-20));
    if (Math.abs(300-y)<r/2)
    {
        arc (width/2,y,r,r,-(Math.PI/2-anglem1)+Math.PI ,2*Math.PI + (Math.PI/2-anglem1),OPEN);
        //the missing piece
        if (300-y+20/Math.sqrt(2)<=(r/2-20))
        {   
            push();
            fill(80,50,180);
            arc (width/2+20/Math.sqrt(2),y-20/Math.sqrt(2),r-40,r-40,-(Math.PI/2-anglem2)+Math.PI ,2*Math.PI + (Math.PI/2-anglem2),OPEN);
            pop();
        }
        else
        {
            push();
            fill(80,50,180);
            circle(width/2+20/Math.sqrt(2),y-20/Math.sqrt(2),r-40);
            pop();
        }
    }
    else
    {
        circle(width/2,y,r);
        push();
        fill(80,50,180);
        //the missing piece
        circle(width/2+20/Math.sqrt(2),y-20/Math.sqrt(2),r-40);
        pop();
    }

}

//mountain reflection using bezier
function moutainReflection(mx,y,w,h)
{   
    fill(0,0,255);
    strokeWeight(0);
    bezier(mx,y,mx,y+h,mx+w,y+h*2,mx+w,y);
}

//mountaini using benzier
function moutain(mx,y,w,h)
{   
    fill(0,0,255);
    stroke(255,255,230,50);
    strokeWeight(2);
    bezier(mx,y,mx,y-h,mx+w,y-h*2,mx+w,y);
}

//making clouds
function clouds()
{
    fill(255,255,255,75);
    //getting seconds and milliseconds
    var dt = new Date();
    var x=dt.getSeconds()*8+dt.getMilliseconds()*0.008;;
    var y=480;
    push()
    translate (0,30);
    //original moving clouds
    rect(-50+x,120,200,30,15);
    rect(-70+x,155,150,20,10);
    rect(-100+x,100,150,16,8);
    //clones to make the animation look smooth
    rect(-50+x+y,120,200,30,15);
    rect(-70+x+y,155,150,20,10);
    rect(-100+x+y,100,150,16,8);

    rect(-50+x-y,120,200,30,15);
    rect(-70+x-y,155,150,20,10);
    rect(-100+x-y,100,150,16,8);
    //original moving clouds
    rect(200+x,20,250,30,15);
    rect(350+x,50,150,20,10);
    //clones to make the animation look smooth
    rect(200+x-2*y,20,250,30,15);
    rect(350+x-2*y,50,150,20,10);

    rect(200+x-y,20,250,30,15);
    rect(350+x-y,50,150,20,10);

    //seconds indicator circles
    fill(255);
    circle(0+x,120,20);
    circle(0+x-y,120,20);
    circle(0+x+y,120,20);

    pop();
}

//create reflection of the sun using noice function to make it expand
function sunReflection (y)
{   
    rando+=0.01;
    push()
    fill (255,255,255,180);
    strokeWeight(0);
    stroke (255,255,255,180);
    rectMode(CENTER);
    rect(width/2,300+(300-y)/2,noise(rando)*50+125,4,2);
    rect(width/2,300+(300-y)/2+8,noise(rando*2)*50+75,4,2);
    rect(width/2,300+(300-y)/2-8,noise(rando-1)*50+75,4,2);
    rect(width/2,300+(300-y)/2+16,noise(rando-0.5)*50+40,4,2);
    rect(width/2,300+(300-y)/2-16,noise(rando+0.5)*50+40,4,2);
    pop()
}
//land darker
function land(mx,y,w,h)
{
    fill(30,30,130);
    noStroke();
    bezier(mx,y,mx,y-h*2,mx+w,y-h,mx+w,y);
}
//land lighter
function land2(mx,y,w,h)
{
    fill(75,75,190);
    noStroke();
    bezier(mx,y,mx,y-h*2,mx+w,y-h,mx+w,y);
}
//duck
function duck(x,y)
{   


    fill(30,30,130,180);
    triangle (x-5,y,x-10,y+5,x-5,y+5);
    triangle (x+5,y+5,x+5,y+10,x+35,y+10);
    arc (x,y,10,10,Math.PI,2*Math.PI);
    rect (x-5,y,10,10);
    arc (x+15,y+10,40,25,0,PI,OPEN);
}
//reed
function reed()
{   
    //moving based on sin function
    var dr = Math.sin(Math.PI*drR);
    drR+=0.002;
    push();
    translate(100,500);
    rotate(dr/20);

    fill(180,120,30);
    rect(-0,-200,10,80,5);
    rect(3,-120,4,120);

    fill(190,130,60);
    rect(-40,-190,10,80,5);
    rect(-37,-110,4,120);

    fill(210,110,80);
    rect(-20,-160,10,80,5);
    rect(-17,-80,4,120);
    pop();

}
//second types of reed (blue)
function reed2()
{   
    
    var dr = Math.sin(Math.PI*drR);
    drR+=0.002;
    push();
    translate(50,500);
    rotate(-dr/20);

    fill(50,60,100);
    rect(-0,-200,10,80,5);
    rect(3,-120,4,120);

    fill(30,70,100);
    rect(-40,-190,10,80,5);
    rect(-37,-110,4,120);
    pop();
}