Joseph Zhang – Final Project -12

sketch

// Joseph Zhang
// 15-104 Final Project
// Section E

var rectangles = [];
var gutter = 30;
var totalRows = 15;
var totalCols = 15;
var centerCol = totalCols / 2;
var centerRow = totalRows / 2;
var rectH = 70;

function setup() {
    createCanvas(450, 450, WEBGL);
    // PUT RECTANGLES INTO ARRAY
    for( x = 0; x < totalRows; x++) {
        for ( y = 0; y < totalCols; y++) {
            rectangles.push(createCube(x * gutter, y * gutter, x, y));
        }
    }
}

var bgColor;
var bg = 0;

function draw() {

    rotateY(map(mouseX, 0, height, -.15, .15));
    rotateX(map(mouseY, 0, height, .15, -.15));
    translate(map(mouseX / 10 , 0, width / 10, -10, 10), map(mouseY / 10 , 0, height / 10, -10, 10), 0);

    //INTERACTIVE CONTROLS - UP AND DOWN
    if( keyIsPressed &  keyCode === LEFT_ARROW) {
        if( rectH > -200) {
            rectH -= 3;
            print(rectH);
        }
    }

    else if( keyIsPressed &  keyCode === RIGHT_ARROW) {
        if( rectH < 100) {
            rectH += 3;
            print(rectH);
        }
    }

    // COLOR BACKGROUND
    if(bgColor) {
        if ( bg > 0) {
            bg -= 20;
        }
    }

    else{
        if( bg < 255) {
            bg += 20;
        }
    }
    background(bg);

    rectMode(CENTER);  
    rotateX(radians(40));
    translate( - width / 2, - height / 2 + 15, 0);

    // REPEATEDLY DRAW EVERY PRISM IN DRAW
    for( i = 0; i < rectangles.length; i++) {
        rectangles[i].drawRect();
        rectangles[i].raiseRect();
    }
}

// CUBE OBJECT
function createCube(row, col, r, c) {
    var rectObj = {
        w: 19,
        xPos: row,
        yPos: col,
        offset: dist(r, c, centerCol, centerRow),
        currentHeight: this.offset,
        // UPDATES THE HEIGHT OF RECTANGLE
        drawRect: function() {
            if (this.currentHeight > 0) {
                fill(map(this.currentHeight, 10, 70, 0, 255));
            }
            else{
                fill(map(this.currentHeight, 10, 70, 0, -255));
            }

            push();
            translate(this.xPos, this.yPos , this.currentHeight);
            box(this.w, this.w, this.currentHeight);
            pop();
        },
        // CHANGES THE HEIGHT THROUGH MAPPING CANVAS
        raiseRect: function() {
            this.currentHeight = map( sin(this.offset), -1, 1, 10, rectH);
            this.offset += .1;
        }  
    }
    return rectObj;
}

// IF ENTER KEY IS PRESSED, CHANGE BACKGROUND
function keyPressed() {
        if( keyCode === ENTER) {
            bgColor = !bgColor;
        }
}

INTERACTIVE CONTROLS (click on canvas first):

LEFT ARROW: Decrease wave amplitude

RIGHT ARROW: Decrease wave amplitude

ENTER: Change background color

***IF LAGGING, VISIT https://editor.p5js.org/jxsephz/sketches/9Dqxil-1P

————————

For this project, I wanted to experiment with manipulating forms in three dimensional space. As someone who loves mathematical patterns, I explored ways that I could utilize the oscillation of a Sine wave.

Joseph Zhang — Project 12 — 3D Sine Wave

For my final project, I want to create a manipulatable 3D sine way form. This wave reacts to the mouse position as well as possible keys on the keyboard. I plan for the sine wave to be made of a individual particles, whether it be letters, circles, or cubes.

I’ve always wanted to do something including the third dimension and after seeing that p5.js can utilize webGL, I became really fascinated with possible ways I can do that. Changing variables include color, height of wave, and possibly orientation. Ideally, mouse position will control the location of where the max height of the wave will be. Keyboard functions may dictate the height of the wave, or if I can figure it out, the actual orientation.

My goal for this is to be able create 3D space using 2 dimensional elements. Obviously, 3D in P5 isn’t something that I’ve explored yet. However, it is something I’m eager to explore and learn about.

Joseph Zhang — Looking Outwards — 12

Hyperobjects – Erwin Hoogewood- 2019
Chihiro Sakoda – 2019

For my final project, I wanted to look into two computational artists Erwin Hoogerwood and Chihiro Sakoda. Above are two javascript projects that utilize various forms in geometry and nature to create beautifully animated forms. In both projects, there’s a sense of orchestrated randomness that’s really intriguing to observe. The one above by Hoogerwood is definitely much more systematic and geometric while the one below by Sakoda uses random participles to create something that seems more free flowing.

I would love to see how these artists might be able to make their respective art projects interactive. That would be really fascinating to interact with because it gives us as the user a new sense of agency. I think without this form of interactivity, these beautiful projects remain as cool animations with not as much depth as there could be.

Joseph Zhang – Project 11 – Generative Landscape

sketch

// Joseph Zhang
// Section E
// haozhez@andrew.cmue.edu
// Project-11: Generative Wallpaper

var snowballs = [];
var moons = [];
function setup() {
    createCanvas(480,300);
    // display initial Snowballs
    for( i = 0; i < 3; i++){
        var snowBallsInitialX = random(width);
        snowballs[i] = drawSnowballs(snowBallsInitialX);
    }

    var moonInitialX = random(0, width / 3);
    moons[0] = drawMoon(moonInitialX);
}

function draw() {
    background(28,28,45);

    //moon
    updateAndDisplayMoon();
    addMoon();

    //makeTerrain
    makeTerrain();

    updateAndDisplaySnowballs();
    addSnowballs();
}

// all the details of the moon
function addMoon() {
    var prob = .07;
    if(moons[moons.length-1].xPosMoon < -30){
        moons.push(drawMoon(width));
    }
}

//render moon on screen
function updateAndDisplayMoon() {
    for( i = 0; i < moons.length; i++){
        moons[i].displayMoon();
        moons[i].moveMoon();
    }
}

function drawMoon(xPosM) {
    var moon = {
        xPosMoon: xPosM,
        yPosMoon: random(30, 60),
        moonSize: random(30, 50),
        moonSpeed: -.2,
        //color
        r: 255,
        g: random(180, 255),
        b: random(100, 255),
        //moveMoon
        moveMoon: function(){
            this.xPosMoon += this.moonSpeed;
        },
        //displayMoon
        displayMoon: function() {
            noStroke();
            fill(this.r, this.g, this.b);
            ellipse(this.xPosMoon, this.yPosMoon, this.moonSize, this.moonSize);
            fill(28,28,45);
            ellipse(this.xPosMoon - 20, this.yPosMoon, this.moonSize, this.moonSize);     
        },
    }
    return moon;
}

// draw terrain
var terrainSpeed = 0.00019;
var terrainDetail = 0.008;
function makeTerrain() {
    // noFill();
    fill(30, 40, 50);
    beginShape();
    for( x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t), 0 , 1, 0, height);
        vertex(x, y);
    }
    vertex(width, height);
    vertex(0, height);
    endShape();
}

// add snowBalls
function addSnowballs() {
    var prob = .07;
    if( random(1) < prob) {
        snowballs.push(drawSnowballs(width));
    }
}

// RENDER onto canvas
function updateAndDisplaySnowballs() {
    for ( i = 0; i < snowballs.length; i++) {
        snowballs[i].displaySnowBalls(); //displayCircle();
        snowballs[i].moveSnowBalls(); //moveCircle();
    }
}

// create the actual Snowballs
function drawSnowballs(xPosB) {
    var sb = {
        xPosSnowBalls: xPosB,
        yPosSnowBalls: random(height), // randomize yPossnowBalls of snowBallss
        radius: random(5,15),
        snowBallsSpeed: random(.5,1),
        // move snowBalls
        moveSnowBalls: function() {
            this.xPosSnowBalls -= this.snowBallsSpeed;
            this.yPosSnowBalls += this.snowBallsSpeed * random(.2, .4);
            },
        // display SnowBalls
        displaySnowBalls: function() {
            fill('white');
            ellipse(this.xPosSnowBalls,this.yPosSnowBalls, this.radius, this.radius);
        },

    }
    return sb;
}




As winter approaches, I wanted to create a landscape that reflected the brisk temperature. In this code, there are two arrays, on that randomly generates snowballs and one that generates a new moon form every time it runs across the screen. Objects were created for both the moon and for the snowballs, where parameters such as color, size, and position were dynamically varied.

Below are sketches of my idea, I wanted to create a sense of time of day, sense of direction, and sense of environment. Much of this was done through the use of color which is made of entirely of cool tones and white.

Joseph Zhang – Looking Outwards – 11

For this Looking Outward, I really wanted to look at Amanda Ghassaei design work, specifically her 2017 Origami Simulator. A little about Amanda, she is a graduate of Pomona College and MIT’s media lab. Currently, she is working as a research engineer at Adobe’s Creative Intelligence Lab. With a background in physics and eventually design, she is applying her expertise in the fields of computational design, digital fabrication, and simulation methods

Origami Simulator is a WebGL app that mimics how a certain origami pattern creases and folds. What’s really interesting about this simulator is that contrary to the normal process of making one fold at a time, the simulator attempts to fold creases all at once.


Crease patterns are uploaded into the app as a SVG or FOLD format; from there, the app uses color and opacity to visualize the direction and fold angles of each crease.


The Origami Simulator app also connects to virtual reality and a user is able to interact with the digital forms through that as well.

Overall, I just really appreciate the way Amanda has brought both structure and delight to the seemingly ordinary concept of folding origami.

Joseph Zhang – Project 10 – Sonic Sketch

sketch

// Joseph
// Section E
// Project 10 - Sonic 

var px, py;
var diam = 30;
var distance = 20;
var count = 0;

//load sounds
function preload() {
    up = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/up.wav');
    right = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/right.wav');
    left = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/left.wav');
    down = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/down.wav');
    warningSound = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/warning.wav');
}

function setup() {
    // you can change the next 2 lines:
    createCanvas(400, 400);
    px = width/2;
    py = height/2;
    dx = 0;
    dy = 0;
    useSound();
}

// for some reason wont work if not included
function soundSetup() {
}

function draw() {
    background(200, 220, 250);

    //red background - DANGER
    if(px < 50 || px > 350 || py < 50 || py > 350){
        background('red');
        fill('black');
        text("COME BACK!", width / 2 - 40, height / 2);
    }
    //blue background - SAFE
    else {
        background(200, 220, 250);
        fill('black');
        text("DON'T CROSS THE LINE ;)", width / 2, 30);
    }

    //creating movable circle, square boundary, and directions

    if(count === 0){
        text('UP / DOWN / LEFT / RIGHT ARROWS TO MOVE', 67, height - 20);
    }

    rectMode(CENTER);
    noFill();
    rect(width/2, height/2, 300, 300);


    //change color if inside/outside of boundary box
    if(px > 350 || px < 50 || py > 350 || py < 50){
        fill('blue');
    } else {
        fill('yellow');
    }

    //draw ellipse
    ellipse(px, py, diam, diam);

    //when the ball moves off the screen
    if(px < 0){
        px = height - diam/2;
    } if(px > width){
        px = 0;
    }
}

function keyPressed() {
    //press left key
    if (keyCode === LEFT_ARROW) {
        px -= distance;
        if(px < 50 || px > 350 || py < 50 || py > 350){
            warningSound.play();
        }
        else{
            left.play();
            warningSound.stop();
        }
        count++;
    }
    //press right key
    else if (keyCode === RIGHT_ARROW) {
        px += distance;
        if(px < 50 || px > 350 || py < 50 || py > 350){
            warningSound.play();
        }
        else{
            right.play();
            warningSound.stop();
        }
        count++;
    }
    //press up key
    else if (keyCode === UP_ARROW) {
        py -= distance;
        if(px < 50 || px > 350 || py < 50 || py > 350){
            warningSound.play();
        }
        else{
            up.play();
            warningSound.stop();
        }
        count++;
    }
    //press down key
    else if (keyCode === DOWN_ARROW) {
        py += distance;
        if(px < 50 || px > 350 || py < 50 || py > 350){
            warningSound.play();
        }
        else{
            down.play();
            warningSound.stop();
        }
        count++;
    }
}

In this project, I used the metaphor of the ball as me as a young adult. There are boundaries that we’re given and often times we’re tempted to cross them. We’re often warned, but we’re not stopped. Ultimately, it’s up to us.

Joseph Zhang – Looking Outwards – 10

Installation view of 'Sonic Arcade: Shaping Space with Sound'

Sonic Arcade: Shaping Space with Design is a multi-component exhibition featuring interactive installations that experiment with the computations of Sound Design. The exhibition showcases several solo / collaborative works that, in one way or another, helps the audience feel more integrated into the spatial environment. The work utilizes electronic circuits, signals, radio waves, and resonant bodies to create these immersive experiences.

Foo/Skou
Installation view of 'Sonic Arcade: Shaping Space with Sound'

Though all these pieces are drastically different from each other, each utilize sound as a substance as the primary medium in each installation. In the exhibition above, Studio PSK uses body-activated MIDI sensors to detect when sounds should be triggered / altered. With these sensors installed throughout all the structures, the entire exhibition becomes a musical instrument itself, ultimately allowing viewers to both watch and participate in the art.

Joseph Zhang – Project 09 – Computational Portait

sketch

 // Joseph Zhang
 // Haozhez@andrew.cmu.edu
 // Section E
 // Project 09: Portrait

 var underlyingImage;
 var words = ['joseph', 'designer', 'student', 'cmu', 'loves 104']
 function preload() {
     var myImageURL = "https://i.imgur.com/LTgLTOy.jpg";
     underlyingImage = loadImage(myImageURL);
 }
 
 function setup() {
     createCanvas(500, 500);
     background(0);
     underlyingImage.loadPixels();
     frameRate(100);
 }
 
 function draw() {
    var px = random(width);
    var py = random(height);
    var ix = constrain(floor(px), 0, width-1);
    var iy = constrain(floor(py), 0, height-1);
    var theColorAtLocationXY = underlyingImage.get(ix, iy);

    noStroke();
    fill(theColorAtLocationXY);
    //randomizes text size
    textSize(random(6));
    text(random(words), px, py);
    
    //draws text at mouseX and mouseY
    var theColorAtTheMouse = underlyingImage.get(mouseX, mouseY);
    fill(theColorAtTheMouse);
    text(random(words), mouseX, mouseY);
 }

This is a self-portrait created using words that describe who I am as an individual. Labels hold so much power in our culture whether we like it or not, so why not define yourself?

Few Minutes
Many many minutes

Joseph Zhang – Looking Outwards – 09

http://refikanadol.com/works/melting-memories/

For this week, I looked at Jenny Lee’s Looking Outward-07 article focused on Refik Anadol and his project Melting Memories. Refik is a computational media artist who blurs the lines between computation and installation-based digital art.

https://courses.ideate.cmu.edu/15-104/f2019/category/looking-outwards-07/

Like Jenni, I am also completely fascinated by Refik’s algorithmic methods and uses of brain data. It’s always really incredible to see the thought process behind certain projects and this was one of them. I was also in love with the way Refik decided to actually render the information in visual graphics. The forms are so elegant and natural, but so clearly computational.

Below are screenshots of data used in the project. Seeing the backend of Refik’s practices is really inspiring to analyze.

Joseph Zhang – Looking Outwards – 08

Website: https://nicolation.net/

This week, I wanted to look at Eyeo 2019 speaker Nicole Aptekar. Nicole Aptekar is a computational designer who utilizes three-dimensional rendering techniques and transfers them to physical mediums through lazor cutting techniques. For many of her works, Nicole develops custom software to generate these design. One of my favorite series is Metaflux, which is shown below. The compositions below consist of layers of paper stacked on top of each other to develop these beautiful forms that take advantage of light and shadows. As you can see, Nicole is really focused on geometric form and geared towards understanding how these forms and work in harmony with each other.

https://nicolation.net/category/metaflux

Project from Metaflux Series
Project from Metaflux Series

In her talk, Nicole talks a lot about how her work revolves around finding that middle ground where the physical and digital mediums meet. She tells her story through visually and verbally showcasing her work and how it relates to her as a designer and human. In her presentation, she also breaks the fourth wall and really talks to the audience as a friend. Her use of both digital and physical technologies to create novel art embodies her mission of pushing fabrication techniques and conventions.