Final Project

peachsketchfinal
//Sarah Kwok Section B
//sarahkwo


var walkImage = []; //holds sprite walk cycle  
var People = []; //holds randomly sprouting museum-goers
var yloc = 300; //y location of walking figure
var z = 600; //month image x coordinate
var months = []; //holds images for each of the months
var imageWidth = 300; 
var imageHeight = 175;
var r = 0; //x location of rope
var imageLoc = 100; //image y coordinate
var monthfiles = []; //loads month images
var monthindex = 0; // keeps track of which month function is at
var monthnames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]
//emotions matching the events
var emotions = ["R.I.P.", ":(", "!!!", ":0", "bzzz", "BLM", "take off!","prayers","R.I.P.","lol","SAVED", ":)"]
//news headlines matching events 
var commentary = ["Basketball icon Kobe Bryant passes away in tragic accident", 
"Wildfires ravage forests and wildlife around the world",
"Coronavirus is declared a global pandemic", 
"The Pentagon releases never seen before UFO footage",
"Killer Hornets found in Seattle!",
"Black Lives Matter protests sweep the nation",
"SpaceX launches first commercial flight",
"Warehouse explosion devastates Beirut",
"Supreme Court Justice Ruth Bader Ginsburg passes away",
"President Cheeto gets COVID-19",
"Joe Biden wins the 2020 Presidential Election",
"Several promising vaccines emerge. The future seems bright."]

function preload(){

rope = loadImage("https://i.imgur.com/Opiv3O8.png")
frame = loadImage("https://i.imgur.com/ZNqHge9.png")
thoughtbubble = loadImage("https://i.imgur.com/BLov0ZV.png")
	
    //walk cycle sprite images
    var filenames = [];
    filenames[0] = "http://i.imgur.com/svA3cqA.png";
    filenames[1] = "http://i.imgur.com/jV3FsVQ.png";
    filenames[2] = "http://i.imgur.com/IgQDmRK.png";
    filenames[3] = "http://i.imgur.com/kmVGuo9.png";
    filenames[4] = "http://i.imgur.com/jcMNeGq.png";
    filenames[5] = "http://i.imgur.com/ttJGwkt.png";
    filenames[6] = "http://i.imgur.com/9tL5TRr.png";
    filenames[7] = "http://i.imgur.com/IYn7mIB.png";

    for (var i = 0; i < filenames.length; i++) {
        walkImage[i] = loadImage(filenames[i]);
    }

    //images for each month
    monthfiles[0] = "https://i.imgur.com/IzzQZ2Z.jpg"
    monthfiles[1] = "https://i.imgur.com/RY8heXd.jpg"
    monthfiles[2] = "https://i.imgur.com/6HM3WnG.jpg"
    monthfiles[3] = "https://i.imgur.com/oBki9og.png"
    monthfiles[4] = "https://i.imgur.com/asttHaY.jpg"
    monthfiles[5] = "https://i.imgur.com/z1d6yIB.jpg"
    monthfiles[6] = "https://i.imgur.com/Acilo1q.jpg"
    monthfiles[7] = "https://i.imgur.com/E1mWLZS.jpg"
    monthfiles[8] = "https://i.imgur.com/UkKfRWx.jpg"
    monthfiles[9] = "https://i.imgur.com/14WgN8Z.jpg"
    monthfiles[10] = "https://i.imgur.com/EWo1aiy.jpg"
    monthfiles[11] = "https://i.imgur.com/vW73ESI.jpg"

for (var j = 0; j < monthfiles.length; j++){
	months[j] = loadImage(monthfiles[j]);
}

}

//sprite character walks in place w/ scrolling background 
function stepCharacter (){

    if (this.imageNumber < 7){
    	this.imageNumber ++
    }
    else {
    	this.imageNumber = 0
    }
}

function drawCharacter (){
	image(walkImage[this.imageNumber], this.x, this.y);
}

function makeCharacter(px, py, pdx, pdy) {
    p = {x: px, y: py,
         imageNumber: 0,
         stepFunction: stepCharacter,
         drawFunction: drawCharacter
        }
        return p;
}

var characters = [];

function setup() {

    createCanvas(600, 500);
    frameRate(25)
    textAlign(CENTER)
    textSize(18);
    textStyle(BOLDITALIC);
    textFont('Georgia');
       var p = makeCharacter(100, yloc,5,1) 
       characters.push(p);

    for (var i = 0; i < 5; i++){
        var rx = random(width);
        var ry = random(height/5*3, height);
        People[i] = makePeople(rx, ry);
    }
}


function draw() {

background(122, 24, 49)
fill(61, 29, 7)
    rect(0,height/4*3, width, height);
fill(0)
//update and draws sprite character

//when the image disappears off the left side of canvas, the x location is reset for next image
//after December scrolls past, cycle loops, and program never ends
if (z <  -imageWidth) {
	z = width
	if (monthindex == months.length-1){
		monthindex = 0
	}
	else {monthindex ++}
}

z -= 5


//cycles through array of month images 
	image(frame, z-20, imageLoc -20, imageWidth+40, imageHeight+40)
	image(months[monthindex], z, imageLoc, imageWidth, imageHeight) 
    fill(222, 197, 109)
    stroke(222, 197, 109)
    rect(z-125, imageLoc+imageHeight -25, 110, 35)
    fill(0)
	text(monthnames[monthindex],z - 70, imageLoc+imageHeight)
    noStroke()

//rope scrolls, and, when rope image leaves canvas, redraws on other side 
if (r < -600){
    r = -5
    }

r -= 5

image(rope, r,height/4*3-65)

//update sprite walks
push();
    p.stepFunction();
    p.drawFunction();
pop();

//people (other people at the museum) randomly spawn
    updatePeople();
    removePeople();
    addNewPeople(); 

//if mouse is pressed, corresponding headline appears at top of screen and sprite character reacts
    if (mouseIsPressed){

        image(thoughtbubble, 150, yloc - 55, 90,80)
        text(emotions[monthindex], 195, yloc-25)
        fill(255)
        text(commentary[monthindex], width/2,50)
        noFill()
    }

}

//people move at same rate as background scrolls, making it seem as though they are standing
function updatePeople(){
    for (var i = 0; i < People.length; i++){
        People[i].move();
        People[i].display();
    }
}

function removePeople(){
    var PeopleToKeep = [];
    for (var i = 0; i < People.length; i++){
        if (People[i].x + People[i].breadth > -50) {
            PeopleToKeep.push(People[i]);
        }
    }
    People = PeopleToKeep; 
}

function addNewPeople() {
    var newPeopleLikelihood = 0.05; 
    if (random(0,1) < newPeopleLikelihood) {
        People.push(makePeople(width, random(height/5*3, height)));
    }
}

function PeopleMove() {
    this.x += this.speed;
}
  
//randomly translate canvas and call object at these locations to draw people
//the other people are random indexes called from sprite walkimage array   
function PeopleDisplay() { 
    push();
    translate(this.x, this.y);
   image(walkImage[this.randomImage], this.breadth, this.nsize)
    pop();
}


function makePeople(birthLocationX, birthLocationY) {
    var People = {x: birthLocationX,
                breadth: 50,
                y:birthLocationY,
                speed: -5.0,
                nsize: round(random(20,40)),
                randomImage: floor(random(8)),
                move: PeopleMove,
                display: PeopleDisplay}
    return People;
}

My program is an animation with some user interactivity. It depicts a character walking through a museum that is representative of the year 2020. Each month is marked by an image of a major event that took place that month. While the character walks, if the viewer presses the mouse, a text description corresponding to each event appears as well as a thought bubble and reaction from the walking figure. On a coding level, I was inspired by the scrolling landscapes, and thought I could apply it in a more layered and complex way. Going through the indices of the array (to change the months) while also timing the scrolling (and corresponding further with the ropes) was much more difficult than I had expected! On a conceptual level, I was inspired to create the Museum of 2020 after my sister was shocked remembering that the murder hornets emerged this year, rather than a longer time ago. It has been a long year marred by unprecedented events, and I thought it would be interesting to revisit these moments that defined the world. If I had more time, I would have wanted to try introducing a more three dimensional element, such as manipulating camera views in order to show different aspects/perspectives/rooms of the museum. I also think it would be difficult to try to pause the program and have the sprite figure turn to each of the images and consider each one.

Project 11: Landscape

peachsketch
var Stars = [];
var Planets = [];
var asteroids = [];
var terrain = [];
var noiseParam = 0;
var noiseStep = 0.007;

function setup() {
    createCanvas(480, 300); 
    // create an initial collection of stars, planets, and asteroids
    for (var i = 0; i < 100; i++){
        var rx = random(width);
        var ry = random(height);
        Stars[i] = makeStar(rx, ry);
    }
    for (var i = 0; i < 5; i++){
        var rx = random(width);
        var ry = random(height);
        Planets[i] = makePlanet(rx, ry);
    }
    for (var i = 0; i < 2; i++){
        var rx = random(width);
        var ry = random(height);
        asteroids[i] = makePlanet(rx, ry);
    }
//set up noise function to create scrolling planet terrain
  for (i = 0; i<=width/5; i++){
    var n = noise(noiseParam);
    var value = map(n, 0,1,height/2, height)
    terrain.push(value)
    noiseParam+= noiseStep
  }

    frameRate(20);
}

function draw() {
    background(0); 

    updateStars();
    removeStars();
    addNewStars(); 

    updatePlanets();
    removePlanets();
    addNewPlanets(); 

    updateasteroids();
    removeasteroids();
    addNewasteroids(); 

mars();
insideSpaceship();
astronaut();
}

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

function removeStars(){
    var StarsToKeep = [];
    for (var i = 0; i < Stars.length; i++){
        if (Stars[i].x + Stars[i].breadth > 0) {
            StarsToKeep.push(Stars[i]);
        }
    }
    Stars = StarsToKeep; 
}


function addNewStars() {
    var newStarLikelihood = 0.2; 
    if (random(0,1) < newStarLikelihood) {
        Stars.push(makeStar(width, random(height)));
    }
}

// method to update position of Star every frame
function StarMove() {
    this.x += this.speed;
}
    
// draw Stars
function StarDisplay() {
    fill(255);  
    push();
    translate(this.x, this.y);
    ellipse(0, this.breadth, this.nsize)
    pop();
}

function makeStar(birthLocationX, birthLocationY) {
    var star = {x: birthLocationX,
                breadth: 50,
                y:birthLocationY,
                speed: -2.0,
                nsize: round(random(1,8)),
                move: StarMove,
                display: StarDisplay}
    return star;
}

//view scrolling landscape from inside spaceship
function insideSpaceship(){
	noStroke()
fill(151, 163, 194)
	rect(0, height/9*7, width, height);
	rect(0,0, width, height/9);
	rect(0,0, width/9, height)
	rect(width/9*8, 0, width, height);
noFill();
strokeWeight(10);
stroke(61, 81, 133)
beginShape();
	vertex(width/9, height/9);
	vertex(width/9*8, height/9);
	vertex(width/9*8, height/9*7);
	vertex(width/9, height/9*7);
	vertex(width/9, height/9);
endShape();
strokeWeight(2);
var lx = 80;
var ly = 10;
var pt = 15
for (i=0; i<4; i++){
	line(lx, 0, lx, height/9)
	line(lx, height/9*7, lx, height)
	lx+=110
	line(0, ly, width, ly)
	ly += 250
	}
line(0, 120, width/9, 120)
line(width/9*8, 120, width, 120)
strokeWeight(7)
	point(width/9 + 10, height/9 +10)
	point(width/9 + 10, height/9*7 - 10)
	point(width/9*8-10, height/9 +10)
	point(width/9*8-10, height/9*7 - 10)
noStroke();
}

//draw astronaut looking out spaceship window
function astronaut(){
fill(255)
	ellipse(70, 230, 100);
	rect(30, 240, 80,100)
fill(143, 150, 168)
	ellipse(85,225, 60)
stroke(143, 150, 168)
strokeWeight(4);
	line(85, 270, 85, height)
noFill()
stroke(181, 199, 247)
	ellipse(85,225, 60)
noStroke();
}

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

function removePlanets(){
    var PlanetsToKeep = [];
    for (var i = 0; i < Planets.length; i++){
        if (Planets[i].x + Planets[i].breadth > 0) {
            PlanetsToKeep.push(Planets[i]);
        }
    }
    Planets = PlanetsToKeep; 
}

function addNewPlanets() {
    var newPlanetLikelihood = 0.01; 
    if (random(0,1) < newPlanetLikelihood) {
        Planets.push(makePlanet(width, random(height)));
    }
}

function PlanetMove() {
    this.x += this.speed;
}
    
function PlanetDisplay() {
    fill(this.clr);  
    push();
    translate(this.x, this.y);
    ellipse(0, this.breadth, this.nsize)
    pop();
}

function makePlanet(birthLocationX, birthLocationY) {
    var Planet = {x: birthLocationX,
                breadth: 50,
                y:birthLocationY,
                clr: color(random(1, 255), random(1, 255), random(1, 255)),
                speed: -1.0,
                nsize: round(random(10,50)),
                move: PlanetMove,
                display: PlanetDisplay}
    return Planet;

}

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

function removeasteroids(){
    var asteroidsToKeep = [];
    for (var i = 0; i < asteroids.length; i++){
        if (asteroids[i].x + asteroids[i].breadth > 0) {
            asteroidsToKeep.push(asteroids[i]);
        }
    }
    asteroids = asteroidsToKeep;
}

//asteroids appear the least frequently - "surprise element"
function addNewasteroids() {
    var newasteroidLikelihood = 0.005; 
    if (random(0,1) < newasteroidLikelihood) {
        asteroids.push(makeasteroid(width, random(height)));
    }
}

//make the asteroid move in both x direction and y direction
function asteroidMove() { 
    this.x += this.speed;
    this.y += this.speedy;
}
    
// draw asteroids
function asteroidDisplay() {
    fill(random(255), random(255), random(255));  
    push();
    translate(this.x, this.y);
    ellipse(0, 5, this.nsize)
    beginShape();
    	vertex(5,5);
    	vertex(15,5);
    	vertex(9,7);
    	vertex(15,10);
    	vertex(9,13);
    	vertex(10,15);
    	vertex(5,15);
    endShape();
    pop();
}

function makeasteroid(birthLocationX, birthLocationY) {
    var asteroid = {x: birthLocationX,
                breadth: 50,
                y:birthLocationY,
                speed: -5.0,
                speedy: -1.0,
                nsize: 10,
                move: asteroidMove,
                display: asteroidDisplay}
    return asteroid;
}
//generate landscape of planet in foreground, placed low on screen so low frequency of apearance
function mars (){
    var n = noise(noiseParam);
    var value = map(n, 0,1,height/5*3, height)
    terrain.push(value)
    terrain.shift();
    noiseParam+= noiseStep
  for (i = 0; i<=width/5; i++){
    noStroke();
    fill(222, 106, 11)
    beginShape();
    vertex(0, height)
    vertex(width, height)
    vertex(i*5, terrain[i])  
    endShape();
  if (terrain[i] < terrain[i+1] & terrain[i] < terrain[i-1]){
  drawAlien(i)
  }
}
}

  function drawAlien(i){ 
  fill(0,255,0)

  ellipse(i*5, terrain[i]-10, 10);
  stroke(0,255,0)
  strokeWeight(2);
    line(i*5,terrain[i]-20, i*5, terrain[i]-10)
   strokeWeight(10)
    ellipse(i*5, terrain[i]-5, 5)
   noStroke()
    fill(255)
   ellipse(i*5, terrain[i]-5, 8)
   fill(0)
     ellipse(i*5, terrain[i]-5, 5)

}

For this assignment, I had a lot of fun deciding what I wanted my landscape to be. However, I found that there were a lot of components that I wanted to introduce, but wasn’t able to efficiently generate them in a concise amount of code. I ended up utilizing methods from different classes to generate different aspects of my landscape – for example, objects in the background similar to what was provided in the sample code, as well as usage of the noise function for objects in the foreground. I was partially inspired by the game Among Us as well as a music video called “Where the Sea Sleeps.”

Looking Outwards – 11

One project that I admire is “Bot Party,” helmed by Phoenix Perry and aided by Freida Abtan, both women artists. The project is a game that requires the players to help the robots communicate with each other through audio interaction. They utilize a ‘bot to skin and skin to bot’ communication protocol – the user physically connects the bots so that they may send encoded messages to each other. I admire that the project is both thoughtful in its simplistic message, while simultaneously is efficient as well as aesthetically pleasing. It also utilizes robots for a considerably unique purpose. Phoenix Perry amusingly calls herself a cultural engineer, game designer, instigator, as well as “feminist killjoy.” She was educated at NYU Tandon. I admire her in that while she has evidently found personal success, she has used that success to help others – she founded the Code Liberation Institute, which teaches women how to program games, as well as Dozen Eyes Games, a studio aimed at games and installations that generate social change. She also gives lectures, and in general, her active pursuit of positive change in the world of a male dominated profession is really inspiring.

Project 10: Sonic Story

peachsketch
//There are two characters, red and blue, fighting each other video
//game style. The announcer starts the match, and they fight, 
//exchanging rapid punches and hits. Neither one does much damage.
//Suddenly, blue passes gas. The gas is deadly, and red dies.
//Blue wins, match is over.

var count = 0;

function preload() {
    fight = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/fight.wav")
    punch = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/punch.wav")
    kick = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/kick.wav")
    fart = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/fart.wav")
    victory = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/victory.wav")

}


function setup() {
    createCanvas(400, 300);
    frameRate(10)
    useSound();
}


function soundSetup() { // setup for audio generation
    // you can replace any of this with your own audio code:
    //osc = new p5.TriOsc();
    kick.setVolume(0.4);
    punch.setVolume(0.4);
    fight.setVolume(0.5);
    fart.setVolume(0.9);
    victory.setVolume(0.5);
}


function draw() {

    background(0);
    fill(100)
    rect (0,225, 400, 75);
    fill(0,255,0)
    rect(20,20, 100,10)
    rect(280,20, 100,10)
    textSize(50)
    fill(255)
    
    text("FIGHT!", 120, 100);
    //fighters are sizing each other up
    if (count < 2) {
        fight.play()
        fightLeft(100,200)
        fightRight(300,200)

    }
    if (count >=2 & count < 20){
        fightLeft(120,200)
        fightRight(320,200)
    }
// red throws first punch
    if (count >= 20 && count < 35){
        fightLeft(100,200)
        fightRight(300,200)
        fill(240, 220, 170)
        ellipse(260,230,20,15)
        if (count >=20 && count < 25){
        punch.play()
        
    }

    }
    //blue fights back
    if (count >= 35 && count < 50){
        fightLeft(120,200)
        fightRight(320,200)
        fill(240, 220, 170)
        ellipse(160,230,20,15)
        if (count>=35 && count< 38){
            kick.play()
        }
    }
    //red punches again
    if (count >= 50 && count < 65){
        fightLeft(100,200)
        fightRight(300,200)
        fill(240, 220, 170)
        ellipse(260,230,20,15)
        if (count >=50 && count < 55){
        punch.play()
        }
    }
    //blue releases gas
    if (count >= 65 && count < 80){
        fightLeft(120,200)
        fightRight(320,200)

        if(count>70 && count< 78){
                fartblue(60,230)
        }
        if (count > 70 && count<72){
            fart.play()
        }
    }
if (count>=80 && count<90){
        fightLeft(120,200)
        fightRight(320,200)
}
    
//red dies from fart, blue wins
if(count>=90 && count<120){
    fightLeft(120,200)
    deadRight(320,200)
    if (count>95 && count <98){
    victory.play()
    }
    textSize(20)
    fill(255)
    text("WINNER", 50, 150);
    fill(255,0,0)
    rect(280,20, 100,10)
}

//story ends
if (count >= 120){
    fill(0)
    rect(0,0,width,height)
    fill(255)
    text("game over", 90, height/2)

}
    count++
}

//left fight stance
function fightLeft(x,y){
fill(240, 220, 170)
ellipse(x, y,30)
fill(0,0,255)
beginShape();
    curveVertex(x,y-10)
    curveVertex(x+5, y+20)
    curveVertex(x+20, y+60)
    curveVertex(x, y+45)
    curveVertex(x-20, y+60)
    curveVertex(x-10, y+20)
    curveVertex(x-5,y-10)
    endShape();
rect(x-15, y-10, 30, 4)
fill(255);
ellipse(x, y, 8,12)
fill(0);
ellipse(x+2,y+2,6, 8)
stroke(0)
strokeWeight(3)
line(x,y-5,x+5,y)
line(x, y+11, x+6, y+11)
noStroke()

}
//red fight stance
function fightRight (x,y){
fill(240, 220, 170)
ellipse(x, y,30)
fill(255,0,0)
beginShape();
    curveVertex(x,y-10)
    curveVertex(x+5, y+20)
    curveVertex(x+20, y+60)
    curveVertex(x, y+45)
    curveVertex(x-20, y+60)
    curveVertex(x-10, y+20)
    curveVertex(x-5,y-10)
endShape();
rect(x-15, y-10, 30, 4)
fill(255);
ellipse(x, y, 8,12)
fill(0);
ellipse(x-2,y+2,6, 8)
stroke(0)
strokeWeight(3)
line(x,y-5,x-5,y)
line(x, y+11, x-6, y+11)
noStroke()
}

//draw fart cloud
function fartblue(x,y){
    fill(18, 135, 41)
ellipse(x,y,40,25)
}
//red dies
function deadRight (x,y){
fill(240, 220, 170)
ellipse(x, y,30)
fill(255,0,0)
beginShape();
    curveVertex(x,y-10)
    curveVertex(x+5, y+20)
    curveVertex(x+20, y+60)
    curveVertex(x, y+45)
    curveVertex(x-20, y+60)
    curveVertex(x-10, y+20)
    curveVertex(x-5,y-10)
endShape();
rect(x-15, y-10, 30, 4)

stroke(0)
strokeWeight(3)
line(x,y-6,x-6,y+2)
line(x-6, y-6, x, y+2)
noFill()
ellipse(x-3, y+10, 8)
noStroke()

}

For my story, I had trouble manipulating the noise to be used in an interesting way. Because the noises themselves were already distinctive, I wasn’t sure how to improve the way they were used. I had fun writing a silly story inspired by the classic, pixelated video game characters I grew up with.

I used sounds from the timeless Mortal Kombat series, which were available online for free use. I took the classic announcer sayings of “fight!” and “flawless victory.” as well as the punching and attacking noises. I also used a sound from the recommended free sounds website of a simple passing gas noise. I thought that the last noise would be a funny juxtaposition to the otherwise epic sounds.

Looking Outwards – 10: Computational Music

Holly Herndon is an electronic musician who has developed the first mainstream album, called Proto, with the help of artificial intelligence. What sets her apart is that she developed a machine learning AI named Spawn to copy her own voice, and be able to sing and harmonize with her. In regards to the learning curve of the AI, Herndon states that the beginning was uninteresting – when teaching the machine, the AI extracts rules from a training canon and follows them exactly, and is unable to go outside that canon. Herndon used different programs to teach Spawn. First, she used TensorFlow, which is a visual learning program that turned soundbytes into visual spectrograms that Spawn could ‘read’. The second program Herndon used is called SampleRNN, which is used for voice recognition, and she applied it to Spawn as a way for it to predict what would naturally come next in a flow of music. The last program used was a voice model-method which involved recording herself and her partner speaking arbitrary phrases for hours of audio that translates into hundreds of megabytes of data. At the end of the process, Spawn could independently sing unique melodies that Herndon herself is not capable of replicating. I think this usage of computation for a creative practice such as this is unprecedented, as Spawn can write music that compliments Herndon’s own style, while still being something never conceived before by a human. The AI technology is not surpassing the humans in this case, but working alongside it to create something new.

Project 09 – Portrait

peach1
let img;
let smallPoint, largePoint;
 var angle = 0


function preload() {
  img = loadImage("https://i.imgur.com/43WGeu8.jpg");
}

function setup() {

  createCanvas(500,500);
  imageMode(CENTER);
  noStroke();
  background(255);
  img.loadPixels();
  
}

function draw() {
  //retrive the image pixels in different sections to be able to assign specific 
  //pixel sizes for each section
  let x = floor(random(img.width));
  let y = floor(random(img.height/4));
  let y1 = floor(random(img.height/2));
  let y2 = floor(random(img.height/4*3));
  let y3 = floor(random(img.height));
  let pix = img.get(x, y);
  let pix1 = img.get(x, y1);
  let pix2 = img.get(x, y2);
  let pix3 = img.get(x, y3);
  //pixels are drawn where the mouse location is 
  let pixM = img.get(mouseX,mouseY);

//when the mouse is pressed, make the rectangles horizontally oriented,
//sizes change according to mouseY value
if (mouseIsPressed){
  fill(pix3);
  rectMode(CENTER)
  	rect(x,y3, 50, mouseY/50);
  fill(pix2)
  	rect(x,y2, 25,mouseY/100)
  fill(pix1)
	rect(x,y1, 10, mouseY/150)
  fill(pix)
	rect(x,y, 5, mouseY/200)
  fill(pixM)
	rect(mouseX,mouseY,5,10)
}
//naturally, rectangles are vertical. They are larger at the top of the canvas
//and towards the bottom, get smaller in size to get fading away/gradient effect.
//get larger proportionally (across different sections) as mouseX increases
 else{
  fill(pix);
  rectMode(CENTER)
  	rect(x,y, mouseX/50, 50);
  fill(pix1)
  	rect(x,y1, mouseX/100,25)
  fill(pix2)
	rect(x,y2, mouseX/150,10)
  fill(pix3)
	rect(x,y3, mouseX/200,5)
  fill(pixM)
	rect(mouseX,mouseY,5,10)
}
}
//when the mouse is clicked, the colors invert
function mousePressed(){
	filter(INVERT)

}

I had a lot of trouble with being able to manipulate the individual pixels – I wanted to make the pixels deliberately dynamic and varied, which I had trouble with because I couldn’t change them after they appeared. So, my solution was the divide up the image canvas – when I was using the “get pixels” function, I only retrieved the pixels for portions of the image. This way, I could depict those different portions with different pixels. I chose to use rectangles throughout, but of varying sizes across the different portions of the canvas in order to create the effect that the picture is fading or loading into existence. The sizes of the rectangles furthermore varies proportionally across the sections according to the mouseX location. When the mouse is pressed, the rectangles are oriented horizontally instead. I also added an invert filter that creates color interest when the mouse is clicked.

LO 09: on Looking Outwards

MTV: Love from Laurie Rowan on Vimeo.

I was scrolling through the previous Looking Outwards category on 3D Graphics when I stumbled upon eyelash’s post on Laurie Rowan. The work “MTV: Love” was extremely mesmerizing, to say the least. I agree with my peer’s analysis of Rowan’s work, that it is demonstrative of how a seemingly impractical artistic vision can find a place to reach and impact a greater audience. I really appreciate how each of his work’s is definitely idiosyncratic, yet clearly still his distinct style. Rowan’s work is absurd and adorable, appealing to people of all ages. I think it is interesting to consider how music and sounds come into play with his animations and add yet another degree of complexity. I would also like to add that Rowan creates pieces that comment on society as well, as evidenced by his piece for a Businessweek Editorial (seen below). His works are playful, but also critical.

Although I am not familiar with animation software, I agree with the assessment that these were likely made with a combination of rendering/animation programs such as Cinema4D and AfterEffects, and I believe that Blender might have had a role in their creation as well.

Eyeo 2015 – Nicky Case from Eyeo Festival on Vimeo.

Nicky Case is an extraordinary person. Nicky moved from Singapore to Canada at a young age. They largely confronted the world on their own, leaving home at age 16 after coming out as LGBTQ+ and not being accepted by their family. Nicky went on to pursue an internship at a video game development company, where they were faced with the idea “do video games matter?” which stuck with them ever since.

Nicky is an interactive storyteller. They develop deeply personal yet relatable games with nuanced choices that the user can make. Those choices are intended to cause the user to reflect on some aspect of society and identity. I really admire this aspect of Nicky’s work. While commonly played games tend to be relatively surface level, Nicky thinks about poignant, often subtle moments in life, and allows people to play through those moments to increase their own self awareness. It is a greatly heightened connection between game, player, and the developer. Nicky’s most popular game is probably their “Coming Out Simulator” which is autobiographical and follows the choices a young asian teen faces when coming out. Another one of my favorite works is “We become what we behold” which is a commentary on manipulation of the media and biases we develop. The games typically have simple often cute graphics, and easy game play that purposefully and effectively communicate their overarching ideas.

In regards to how Nicky presents, honestly when first watching their lecture I thought it was somewhat awkward with some jokes falling flat. However, thinking back, the message of the lecture stays with me, concerning telling stories through systems as well as making systems out of stories. What worked about the presentation was how Nicky presented in the method of the ideas they were discussing – Interweaving anecdotes and structure, all the while in a human, relatably not-smooth-sailing way, makes the presentation all the more memorable.

Project-07-Curves

For this project, I was interested in the different depictions that were shown in the example for how to generate a circle curve. I thought it would be fun to try and draw a circle, but with a specific math curve. I chose the petal curve, and created a code that allowed you to manipulate the shape and frequency of the curve based on the position of the mouse. At first, it looks like a relatively pattern, with the petal curve rotating in the center, and its shape becoming skewed the greater the mouseX position it. However, if the mouse is pressed, then the pattern becomes more intricate, with the curves increasing in frequency to create a void, or circle, in the center. I had difficulty being able to take the curve a step further to make it more dynamic to look at. At first I chose a much more complicated curve, but I could not get the parentheses right while typing it in and it never looked correct!

peachsketch
var nPoints = 100
var angle = 0
var m;
var n;

function setup() {
  
  createCanvas(400, 400);
  m = width/2
  n = height/2
}

function draw() {
  background(0);
  frameRate(20)
  drawPetalCurve(m,n);
  if (mouseIsPressed){ // if mouseIsPressed, draws higher frequency of rotating petal curves
    for (j= 0; j<10;j++){
    drawPetalCurve(m,n);
  }
}
 
}

function drawPetalCurve (m,n){
  var x; 
  var y;
  var a = 100
  var b = 100
  var p = (constrain(mouseX, 50, 300))/50 //change dimensions of curve based on mouse location
push();
stroke(255)
noFill();
  translate(width/2, height/2) // curve drawn at center
beginShape();
  for (var i = 0; i < nPoints; i++) {
    rotate(angle)
        var t = map(i, 0, nPoints, 0, TWO_PI);
        x = p*a*cos(t)*(sin(t)*sin(t))	
        y = a*(cos(t)*cos(t))*sin(t) 
          vertex(m/2+x, n/2+y)
    angle+=0.1
       }
    endShape(CLOSE); 

pop();
   
}

Looking Outwards-07: Computational Visualization

One piece of work that I admire is Jer Thorp’s “138 Years of Popular Science.” The data compiled is from Pop Science magazine’s past publications. The chart illustrates how different scientific terms have come into and out of popular usage over the years in scientific reports. As somewhat of an homage to the content, the data is visualized in a molecular chain format, with different atoms delineating distinct year clusters, further demarcated with different colors. Thorp developed a “simple, space-filling algorithm” that places the different molecules around the chain, and stacking them deliberately to create a neat flow. Further deepening the study is layered histograms in the background, showing the usage from different issues of specific terms. I like this work because it shows the artist’s personal design style with whimsical coloring and visualization, while also respecting the client for whom they are producing for with logic and thorough analysis. Every detail was clearly thought out. Furthermore, not only is it aesthetic but intellectually intriguing as it shows a progression and shift of technology and academic focus.

In a somewhat unrelated note, in the reddit app there is a subreddit that is interesting called r/dataisbeautiful which features data visualizations by anyone (ie regular people!) who chooses to submit a post. The content ranges from “Daily Polar Sea Ice Area with Monthly Ice Extent” to “The distribution of Minecraft Biomes in the overworld.”