Final Project – Maze

    For my project, I created a maze with a turtle guiding the path to get out of the maze. My goal was to make this environmentally themed because this is still a persistent issue. The wonderful thing about where technology is headed, however, we can do a lot more to solve some of these issues. For example, electric automobiles replacing gas ones. Another motivator was to continue to bring self awareness. It’s crazy to think that people were freaking out in the 2020 debates/election over the fear that Biden would “force” everyone to get an electric car. Of course I see the issue in getting rid of gas cars all of the sudden, but 1) he isn’t going to do it “all of the sudden” and 2) electric cars should replace gas cars completely, eventually. 

Anyway, the difference between this and most standard mazes is that there is always one clear path. However, my maze doesn’t have any clear paths. It does have one distinct path, but it is blocked by obstacles. There are six obstacles that are each a factor of environmental issues. In order to get rid of them, and clear the path for the turtle, you have to click on them once the turtle approaches each obstacle. Once you click on one, a fact will appear at the bottom of the page relating to environmental issues. Once you make it to the end, you are done and there will be an ending page, with a smiling earth. The idea of this project is to continue to bring awareness to the climate crisis/environmental issues and the player gets to “clean up” the messes or “get rid” of the issues along the way.

Some side notes: movement is with the wasd keys, instead of the arrow keys. So, “w” is up, “a” is left, “s” is down, and “d” is right. Also, sometimes the turtle may get stuck, just play around with the movement keys if this happens. I apologize for this, but I couldn’t figure out how to fix it. Of course if I had more time, I would’ve liked to figure out this problem, Overall, it works pretty well, so enjoy!

sketch.slmazeDownload
//Sarah Luongo
//sluongo
//Section A

// This code aims to create a maze with obstacles that are causes of
// environmental problems. As you go through, click on the obstacles to
// clear the path for the turtle and learn some facts along the way.

var walls = [];
var x = 120; // x location of circle
var y = 25; // y location of circle
var obstaclesx = []; // array to hold the x location of the obstacles
var obstaclesy = []; // array to hold the y location of the obstacles
var industry;
var litter;
var light;
var tree;
var car;
var rings;
var obstaclesarealive = [];
var facts = '';
var earth;
var facing = 0;
var turtlecol; // boolean for collision as turtle rotates

function preload() {
    industry = loadImage('https://i.imgur.com/kT2IbbF.png');
    litter = loadImage('https://i.imgur.com/iQ2mdUY.png');
    light = loadImage('https://i.imgur.com/uMRxZlH.png');
    tree = loadImage('https://i.imgur.com/vn4OlLX.png');
    car = loadImage('https://i.imgur.com/i4iop8I.png');
    rings = loadImage('https://i.imgur.com/BAAbVNY.png');
    earth = loadImage('https://i.imgur.com/RfrmGyt.png');
}

function setup() {
    createCanvas(600, 600);
    frameRate(60);
    // Maze lines are are drawn somewhat like a grid, so they are separated by
    // Row and column and seperated further to make up to rows and columns

    // Maze lines (columns) starting from left to right
    maze(140, 50, 140, 90, true);    
    maze(140, 130, 140, 210, true);
    maze(140, 250, 140, 330, true);
    maze(140, 370, 140, 410, true);

    maze(180, 50, 180, 130, true);
    maze(180, 170, 180, 250, true);
    maze(180, 370, 180, 410, true);

    maze(220, 170, 220, 210, true);
    maze(220, 250, 220, 330, true);

    maze(260, 90, 260, 170, true);
    maze(260, 210, 260, 250, true);
    maze(260, 290, 260, 330, true);
    maze(260, 410, 260, 450, true); 

    maze(300, 90, 300, 130, true);
    maze(300, 250, 300, 330, true);
    maze(300, 370, 300, 410, true);

    maze(340, 90, 340, 170, true);
    maze(340, 330, 340, 370, true);

    maze(380, 50, 380, 250, true);

    maze(420, 90, 420, 130, true);
    maze(420, 170, 420, 250, true);
    maze(420, 290, 420, 410, true);

    maze(460, 90, 460, 290, true);
    maze(460, 330, 460, 370, true);

    // Maze lines (rows) starting from top to bottom
    maze(220, 90, 260, 90, false);
    maze(300, 90, 340, 90, false);
    maze(420, 90, 460, 90, false);

    maze(140, 130, 220, 130, false);
	
    maze(220, 170, 340, 170, false);
    maze(380, 170, 420, 170, false);

    maze(180, 210, 340, 210, false);

    maze(220, 250, 260, 250, false);
    maze(300, 250, 380, 250, false);
    
    maze(140, 290, 220, 290, false);
    maze(260, 290, 300, 290, false);
    maze(340, 290, 460, 290, false);

    maze(100, 330, 180, 330, false);
    maze(300, 330, 380, 330, false);
    maze(460, 330, 500, 330, false); 

    maze(140, 370, 300, 370, false);
    maze(340, 370, 380, 370, false);

    maze(180, 410, 260, 410, false);
    maze(300, 410, 460, 410, false);

    // Resize images
    industry.resize(35, 40);
    litter.resize(35, 35);
    light.resize(35, 35);
    tree.resize(30, 30);
    car.resize(35, 35);
    rings.resize(60, 60);
    earth.resize(300, 300);

    obstaclesx = [140, 260, 223, 385, 462, 440]
    obstaclesy = [210, 53, 333, 255, 150, 410]

    obstaclesarealive = [true, true, true, true, true, true]
}

function draw() {
    background(220);
    
    // Maze background
    strokeWeight(1);
    stroke(0);
    fill(255);
    square(100, 50, 400);

    for (var i = 0; i < walls.length; i++) {
        line(walls[i].x1, walls[i].y1, walls[i].x2, walls[i].y2);
    }

    // Maze start and finish
    stroke(255);
    strokeWeight(1);
    line(101, 50, 139, 50);
    line(461, 450, 499, 450);
    
    noStroke();
    turtle(x, y);

    if (obstaclesarealive[0] == true) {
        image(industry, 140, 210);
    }
    if (obstaclesarealive[1] == true) {  
        image(litter, 260, 53);
    }
    if (obstaclesarealive[2] == true) {  
        image(light, 223, 333);
    }
    if (obstaclesarealive[3] == true) {  
       image(tree, 385, 255);
    }
    if (obstaclesarealive[4] == true) {  
        image(car, 462, 150);
    }
    if (obstaclesarealive[5] == true) {  
        image(rings, 440, 410);
    }

    // If statements to move and rotate the turtle:
    // Key 'w' moves up
    if (keyIsDown(87)) {
	facing = 180;
	turtlecol = false;
	y--;
	if (collision()) {
	    y++;
	}
    // Key 'a' moves left
    } else if (keyIsDown(65)) {
	facing = 90;
	turtlecol = true;
	x--;
	if (collision()) {
	    x++;
	}
    // Key 's' moves down
    } else if (keyIsDown(83)) {
	facing = 0;
	turtlecol = false;
	y++;
	if (collision()) {
	    y--;
	}
    // Key 'd' moves right
    } else if (keyIsDown(68)) {
	facing = -90;
	turtlecol = true;
	x++;
	if (collision()) {
	    x--;
	}
    }
    
    // Text attributes and placement after each obstacle is clicked
    textSize(15);
    fill(0);                         
    text(facts, 100, 500);
}

function turtle(a, b) {
    push();
    translate(a, b);
    // Rotate based on direction it's traveling
    rotate(radians(facing));

    // Head
    fill(153, 200, 130);
    ellipse(0, 9, 7, 8);

    // Tail
    strokeWeight(3);
    stroke(153, 200, 130);
    line(0, -10, 0, -8); 

    // Legs
    strokeWeight(4);
    line(-7, -8, -6, -7);
    line(7, 8, 6, 7);
    line(-7, 8, -6, 7);
    line(7, -8, 6, -7);

    noStroke();

    // Eyes
    fill(88, 130, 96);
    circle(-2, 11, 2); 
    circle(2, 11, 2);

    // Body
    fill(204, 223, 156);
    circle(0, 0, 16);
    pop();
}

// Maze object 
function maze(xone, yone, xtwo, ytwo, pos) {
    var mz = {x1: xone, y1: yone, x2: xtwo, y2: ytwo, p: pos}
    walls.push(mz);
}

// Function that deals with all collision types
function collision() {
    var xoffset = (turtlecol)? 12 : 13;
    var yoffset = (turtlecol)? 13 : 12;

    // Collision against maze border
    if (x == 111 || x == 489 || y == 65 || y == 430) {
        if (x >= 112 & x <= 128 && y <= 65) {
	    return false;
	}
	// End of maze
	if (x >= 450 & x <= 488 && y == 430) {
            endscreen();
        }
	return true;
    }
    
    // Collision against maze walls
    for (var i = 0; i < walls.length; i++) {
        if (walls[i].p == true) {
            if ((y+yoffset) > walls[i].y1 & (y-yoffset) <= walls[i].y2) {
	        if ((x+xoffset) >= walls[i].x1 && (x-xoffset) <= walls[i].x1) {
		    return true;
		}
	    }
	} else {
            if ((x+xoffset) >= walls[i].x1 & (x-xoffset) <= walls[i].x2) {
	        if ((y+yoffset) >= walls[i].y1 && (y-yoffset) <= walls[i].y1) {
		    return true;
		}
	    }
	}
    }
    return obstacleCollision();
}

// Collision against images
function obstacleCollision() {
    var xoffset = (turtlecol)? 12 : 13;
    var yoffset = (turtlecol)? 13: 12;

    for (var i = 0; i < obstaclesx.length; i++) {
        if ((x+xoffset) >= obstaclesx[i] & (x-xoffset) <= (obstaclesx[i] + 40)) {
	    if ((y+yoffset) >= obstaclesy[i] && (y-yoffset) <= (obstaclesy[i] + 40)) {
	        return obstaclesarealive[i];
	    }
	}
    }
    return false;
}

// Facts from the industry, electricity, and transportation obstacles come from
// the following website:
// https://www.epa.gov/ghgemissions/sources-greenhouse-gas-emissions
// Litter obstacle fact:
// https://www.metrobinhire.com.au/blog/9-surprisingly-and-alarming-facts-about-littering
// Deforestation obstacle fact:
// https://www.greenmatters.com/p/why-is-deforestation-a-problem
// 6 Pack Ring obstacle fact:
// https://www.nationalgeographic.com/environment/2018/09/news-plastic-six-pack-rings-alternatives-history/#close
function mousePressed() {
    if (mouseX >= 140 & mouseX <= 175 && mouseY >= 210 && mouseY <= 250) {
        obstaclesarealive[0] = false;
	facts = 'Greenhouse gas emissions from industry primarily come \nfrom burning fossil fuels for energy, as well as greenhouse \ngas emissions from certain chemical reactions necessary to \nproduce goods from raw materials.';
    }
    if (mouseX >= 260 & mouseX <= 295 && mouseY >= 53 && mouseY <= 88) {
	obstaclesarealive[1] = false;
	facts = 'Some alarming quick facts about littering: almost all litter \nends up in the ocean. The most littered item is fast food \npackaging many animals die from littering. Cigarette butts \nmake up 1/2 the amount of littered objects.';
	    
    }
    if (mouseX >= 223 & mouseX <= 258 && mouseY >= 333 && mouseY <= 368) {
        obstaclesarealive[2] = false;
	facts = 'Electricity production generates the second largest share \n(26.9% in 2018) greenhouse gas emissions. Approximately \n63 percent of our electricity comes from burning fossil fuels, \nmostly coal and natural gas.';
    }
    if (mouseX >= 385 & mouseX <= 415 && mouseY >= 255 && mouseY <= 285) {
        obstaclesarealive[3] = false;
	facts = 'Deforestation has many major (and way too often unforeseen) \nimpacts on the environment. There’s soil erosion, water cycle \ndisruption, greenhouse gas emissions, and biodiversity \nlosses with every tree that is chopped, and the planet feels its \nimpact.';
    }
    if (mouseX >= 462 & mouseX <= 499 && mouseY >= 150 && mouseY <= 185) {
        obstaclesarealive[4] = false;
	facts = 'The transportation sector generates the largest share (28.2%\nin 2018) of greenhouse gas emissions. Greenhouse gas \nemissions from transportation primarily come from burning \nfossil fuel for our cars, trucks, ships, trains, and planes.';
    }
    if (mouseX >= 440 & mouseX <= 500 && mouseY >= 410 && mouseY <= 440) {
        obstaclesarealive[5] = false;
	facts = 'Almost 700 species are now known to have been harmed \nby ocean plastic, and every year, around 18 billion pounds \nof plastic flows into the ocean. Producing plastic rings also \nrequires using petroleum—around eight percent of global \noil production is to make plastic.';
    }
}

function endscreen() {
    facts = '';
    fill(0, 0, 102);
    push();
    translate(width/2, height/2);
    square(-300, -300, 600);
    image(earth, -150, -200);
    textSize(50);
    fill(255);
    textAlign(CENTER);
    text('THE END', 0, 200);
    pop();
    noLoop();
}

// Code used to make the building/first obstacle
/*function industry() {
     // Building
     fill(139, 69, 19);
     rect(145, 225, 8, 20);
     rect(153, 234, 20, 11);

     //CO2
      fill(70);
      circle(149, 222, 5);
      circle(153, 220, 8);
      circle(159, 214, 11);
}*/

11 – Landscape

I was motivated by my experiencing driving. Additionally, a lot of the projects from previous years and such seem to have objects move left or right off the screen, or top to bottom, but I haven’t seen any with “one-point” perspective, so I thought I would give it a try. It was a little challenging and I would’ve like to have made the roadlines move in the mirror as well, but I just couldn’t figure it out.

sketch.sarlDownload
// Sarah Luongo
// Sluongo
// Section A
// Project

// This code aims to articulate the perspective of driving on the road, showing
//different scenery as the car moves forward.

var lines = [];
var cds = [];
var gps;

function preload() {
    gps = loadImage('https://i.imgur.com/tOwIpKP.png');
}

function setup() {
    createCanvas(420, 480);
    background(17, 124, 19);
    gps.resize(100, 100);
    // Creates 6 initial roadline objects
    for (var i = 0; i < 6; i++) {
        lines[i] = makeRoadlines(220,i*(7+(i*7)), i+4, (i+1)*10, -0.1, 0.4, i);
    }
    // Creates 2 initial cloud objects
    for (var i = 0; i < 2; i++) {
        cds[i] = makeCloud(100+(i*200), 40, 50, 40, .3);
    }
}

function draw() {
    road();
    roadlines();
    sky();
    updateRoads();
    driverseat();
}

function driverseat() {
    //Dashboard
    noStroke();
    fill(50);
    rect(0, 360, width, 120);

    //Fuel Meter and Speedometer
    fill('white');
    circle(110, 430, 50);	
    circle(190, 430, 50);
    fill('black');
    circle(110, 430, 40);
    circle(190, 430, 40);

    // Fuel meter lines
    push();
    translate(110, 430)
    rotate(radians(-45));
    for (var i = 0; i < 5; i++) {
	stroke('white');
        strokeWeight(.8);
	line(-15, 0, -10, 0);
	rotate(radians(55));
    }
    pop();

    // Speedometer lines
    push();
    translate(190, 430)    
    rotate(radians(-45));
    for (var i = 0; i < 10; i++) {
        stroke('white');
        strokeWeight(.8);
        line(-15, 0, -10, 0);   
        rotate(radians(25));
    }
    pop();
   
    // Needle
    fill('red');
    push();
    translate(110, 430);
    triangle(-2, -6, 8, 16, 12, 14);
    translate(80, 0);
    triangle(-2, -6, 8, 16, 12, 14);
    pop();

    //Steering Wheel
    stroke('black');
    strokeWeight(20);
    noFill();
    arc(150, 490, 200, 200, PI, PI);
    noStroke();
    fill('black');
    ellipse(150, 500, 200, 100);

    // GPS
    image(gps, 300, 380);

    //Mirror
    fill('black');
    rect(300, 0, 120, 45);
    fill(17, 124, 19);
    rect(310, 0, 100, 35);
    fill('gray');
    triangle(310, 35, 350, 0, 400, 35);
    fill('lightblue');
    rect(310, 0, 100, 10); 
}

function road() {
    noStroke();
    fill('gray');
    triangle(-(width), height, width/2, 80, 1.5*width, height);
}

function sky() {
    noStroke();
    fill('lightblue')
    rect(0, 0, width, 100);
    
    // Sun
    fill('yellow');
    circle(10, 10, 70);

    // Clouds
    clouds();
    updateClouds();
}

function roadlines() {
    fill('white');
    push();
    rotate(radians(20));
    for (var i = 0; i < 6; i++) {                           
        rect(lines[i].x, lines[i].y, lines[i].sx, lines[i].sy);
    }
    pop();
}

function makeRoadlines(xPos, yPos, xSize, ySize, changeX, changeY, c) {
    var roadlines = {x: xPos, y: yPos,
	             sx: xSize, sy: ySize,
                     dx: changeX, dy: changeY,
                     change: c}
    return roadlines;
}

// Updates roadlines & adds to size of road as it moves towards bottom of canvas
function updateRoads() {
    for (var i = 0; i < 6; i++) {
        // Makes new line when each line is greater than 300
        if (lines[i].y > 300) {
            lines[i] = makeRoadlines(220,0*(7+(0*7)),
	    0+4, (0+1)*10, -0.1, 0.4, 0);
	    // How far apart each line is
	    var k = i;
            for (var j = 0 ; j < 6; j++) {
	        if (k > 5) {
		    k = 0;
		}
	        lines[k].change = j;
		k++;
	    }
        }
	// Makes lines move and change size toward bottom of canvas
	lines[i].y += lines[i].dy + lines[i].change/4;
	lines[i].sx += 0.01;
	lines[i].sy += 0.1;
    }
}

function makeCloud(xPos, yPos, w, h, changeX) {
    var clouds = {x: xPos, y: yPos,
	          dx: changeX}
    return clouds;
}

function clouds() {
    fill('white');
    for (var i = 0; i < 2 ; i++) {
        ellipse(cds[i].x, cds[i].y, 50, 40);
        ellipse(cds[i].x + 20, cds[i].y + 20, 50, 40);
        ellipse(cds[i].x + 30, cds[i].y - 10, 50, 40);
        ellipse(cds[i].x + 60, cds[i].y + 15, 50, 40);
        ellipse(cds[i].x + 70, cds[i].y, 50, 40);
    }
}

// Makes cloads reappear at the left of the screen
function updateClouds() {
    // If cloads greater than 450 makes new one reappear from left of canvas
    for (var i = 0; i < 2; i++) {
        if (cds[i].x > 450) {
	    cds[i].x = -100;
	}
        // Makes them move towards right of canvas
	cds[i].x += cds[i].dx;
    }
}

LO – 11

Camille Utterback is from Bloomington, Indiana and attend Williams College for undergrad and NYU for a master’s within the school of art. She is known as an interactive installation artist, and has worked as a contractor for many art exhibits.

Camille Utterback’s piece, “Precarious”, utilizes a ceiling mounted camera with KinectV2 camera tracking to draw silhouettes on a backlit screen. Her work was created for and installed in the National Portrait Gallery exhibition Black Out:Silhouettes Then and Now that opened on May 18, 2018. The Gallery and Raphael Palefsky-Smith, developer of the cameras, helped Utterback create this work of art.

Precarious was built on the  algorithmically generated visual language that she has spent many years refining with her custom coded interactive drawing system. While not much is spoken about her custom software it creates very cool and interactive artwork for others to enjoy. This piece, specifically, does more than just trace those who visit the installation on the backlit screen. As people play with the piece more and more they realize that when more than one person is present each person can alter the other’s silhouette by pushing it and manipulating it with their own outline. Additionally, past outlines erase after one leaves and others join.

I found this to be a funky and inspiring way to represent history as it both represents and deviates from the popularity of silhouettes back in the day. While silhouettes were a form of art, they generally only had one person in the frame. This piece makes that impossible, but aligns with how important relationships are versus back then, as in more and more people care about each other and the future of the World.

Here’s a video representation of the piece:

You can check out a more complete story on the piece here:

Project 10 – Sonic Story

sketch.slDownload
// Sarah Luongo
// Section A
// Project

/* This code aims to tell a short story of traveling home during the holidays, and the joy upon finally arriving home.*/

var train;
var car;
var house;
var xmastree;
var family;
var trainN;
var drive;
var walk;
var bell;
var cheers;

// Load images and sounds
function preload() {
    // Images
    train = loadImage('https://i.imgur.com/8nQo4PL.png');
    car = loadImage('https://i.imgur.com/J9C4YkK.png');
    house = loadImage('https://i.imgur.com/ck3pJGM.png');
    family = loadImage('https://i.imgur.com/GKtqVl2.png');
    xmastree = loadImage('https://i.imgur.com/BTleSuv.png');

    // Sounds
    trainN = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/train.wav");
    drive = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/drive.wav");
    walk = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/walk.wav");
    bell = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/bell.wav");
    cheers = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/cheers.wav");
}


function setup() {
    createCanvas(400, 300);
    frameRate(1);
    train.resize(100, 100);
    car.resize(100, 100);
    house.resize(200, 200);
    xmastree.resize(150, 200);
    family.resize(width, 100);
    useSound();
}


// Setup for audio generation
function soundSetup() {
    trainN.setVolume(0.2);
    drive.setVolume(1);
    walk.setVolume(1);
    bell.setVolume(0.5);
    cheers.setVolume(0.5);
}


function draw() {
    background(200);
    noStroke();
    // On the train:
    if (frameCount <= 10) {
        // Sky
        fill(20, 40, 80);
        rect(0, 0, width, height/1.3);
	//Mountains
        fill(200);
        triangle(-50, height/1.3, 200, height/1.3, 75, height/3);
        triangle(200, height/1.3, width, height/1.3, 300, height/2);
        //Snow on top of mountain
        fill(240)
        triangle(60, height/2.6, 90, height/2.6, 75, height/3);  
        triangle(280, height/1.8, 320, height/1.8, 300, height/2);
        // Snow
        rect(0, height/1.3, width, height/4); 
        // Train
        image(train, 0, height/2);
	//trainN.play();

    //Driving home:
    } else if (frameCount > 10 & frameCount <= 20) {
        // Sky
        fill(20, 40, 80);
        rect(0, 0, width, height/1.3);
        // Snow 
        fill(240);
        rect(0, height/1.5, width, height/3);
        // Car
        image(car, width/2, height/2.3);
	//drive.play();

    // Home:
    } else if (frameCount > 20 & frameCount <= 25) {
        // Sky
        fill(20, 40, 80);
        rect(0, 0, width, height/1.3);
        // Snow
        fill(240);
        rect(0, height/1.5, width, height/3);
        // House
        image(house, 200, 8);
        // Tree
        fill(56, 28, 0);
        rect(0, 60, 13, 150);
        push();
        rotate(radians(150));
        rect(-20, -100, 65, 2);
        pop();
        // Car
        image(car, 50, height/2.3);
	// Sounds:
	/*if (frameCount > 10 & frameCount <= 11) {
	    door.play();
	} else if (frameCount > 11 & frameCount <= 14) {
	    walk.play();
	} else if (frameCount > 14 & frameCount <= 15) {
	    bell.play();
	}*/

    // Inside home:
    } else if (frameCount > 25 & frameCount <= 30) {
        // Wall
        fill(220, 51, 80);
        rect(0, 0, width, height/1.5);
        // Floor
        fill(200);
        rect(0, height/1.5, width, height/3); 
        // Christmas tree
        image(xmastree, 250, 10);
        // Family
        image(family, 0, height/2.3);
	//cheers.play();

    // The end:
    } else {
        background(0);
        fill(255);
        textSize(20);
        text("The End", width/2.5, height/2);
    }
    //Sounds
    switch (frameCount) {
        case 1: trainN.play(); break;
        case 9: drive.play(); break;
        case 21: walk.play(); break;
	case 25: bell.play(); break;
	case 26: cheers.play(); break;
    }
}

For this project, I was inspired by Christmas and the “traveling home for the holidays” time of the year which is soon upon us. I decided to make the travel happen via a train and car, because that was how I got home my first time during freshman year. Then there’s the mini (or large) celebration when you finally return home! The five sounds I chose were, a train noise for the first scene, a car driving for the second, walking and a door bell ring for the third, and cheers for the last scene. The first two scenes last for about 10 seconds and the last two scenes last for about 5 seconds, making the entire story about 30 seconds long. I hope you enjoy!

LO – 10

“Aura” by the Stanford Laptop Orchestra, who also go by SLOrk, is a wonderful work or art that is very harmonic and calming. Using ChucK, a programing language specifically for music creation, and SLOrk music lanterns about nine artists move the lanterns – “auras” – from side to side to communicate with ChucK via WiFi to create the music, lights, and colors. This piece starts with one voice, and gradually the rest join in to create harmony. The initial voice “calls” the other voices to join in and their auras all have the same light, thus creating “harmony”. However, as they all join the auras become unique in color though still in harmony. As the piece ends, the artist move apart leaving their auras behind. What makes this work so special is that it embodies the “why” qualities of humans. The idea was that as human relationships grow, their auras blend and harmonize, and remain as memories. It’s the positive light radiating off others that forms as we grow close with one another and share memories. Something that we see with our “third eye” as we interact and reminisce. A lot of SLOrk’s work explores and embodies humans through music and technology. This piece was such a wonderful embodiment and a light in some stressful times we are all going through right now. Even during these crazy times we all have relationships with people that are helping us through these times.

If you want to see more of their work check out their website:

http://slork.stanford.edu

To see this specific piece:

http://slork.stanford.edu/works/aura/

And here’s the video:

Project 9: Portrait

I really wanted to implement a little bit of what we did two weeks ago, so I created a heart and infinity code, and used those as pixels. I have four different “portraits” each time the mouse is clicked. The first one randomly draws hearts and draws the text “This Is Me” with your cursor. The second one randomly draws the text “Sarah” and draws infinity signs with you cursor. The third one randomly draws infinity signs and draws the text “This Is Me” with your cursor. The fourth one randomly draws random sizes from 10 to 25 of the text “Sarah” and draws infinity signs with you cursor. Additionally, every click increases (to a certain number) sizes of all the pixels, and changes the transparency of the background and decreases (to a certain number), going back and forth between the two.

sketch.slslslDownload
// Sarah Luongo   
// sluongo
// sluongo@andrew.cmu.edu
// Project

// This code aims to draw a self-image with pixels.

var oI; // 'Original image'
var nP = 1; // 'New portrait'
var t = 210; // 'Transparency'
var tS = 10; // 'Text size'
var hS = .3; // 'Heart size'
var iS = 15; // 'Infinity size'
incT = 51; // Variable to increase size of transparency
incH = .1; // Variable to increase size of hearts
incIT = 1; // Variable to increase size of texts and infinity sign

// Loads image
function preload() {
    var ImageURL = "https://i.imgur.com/UJthwzP.jpg";
    oI = loadImage(ImageURL);
}

function setup() {
    createCanvas(480, 480);
    oI.resize(width, height); // Resizes original image
    background(59, 17, 21, t); // Redish
    oI.loadPixels();
    frameRate(60); // Rate pixels are drawn
    t = 0;
}

function draw() {
    // Generates random locations for the pixels within image size 
    var pX = floor(random(oI.width));
    var pY = floor(random(oI.height));
    var cP = oI.get(pX, pY); // 'Color picker' based on location of pixel
    var cM = oI.get(mouseX, mouseY); // Color selected based on mouse location
    noStroke();

    if (nP == 1) {
        // Draws heart pixels randomly
        fill(cP);
        heart(pX, pY);
        // Draws text pixels w/ cursor
        fill(cM);
        textSize(tS);
        text("This Is Me", mouseX, mouseY);
    } else if (nP == 2) {
        fill(cP);
        textSize(tS);
        text("Sarah", pX, pY);
        fill(cM);
        infinity(mouseX, mouseY);
    } else if (nP == 3) {
        fill(cP);
        infinity(pX, pY);
        fill(cM);
        textSize(tS);
        text("This Is Me", mouseX, mouseY);
    } else {
        fill(cP);
        textSize(random(10, 25));
        text("Sarah", pX, pY);
        fill(cM)
        heart(mouseX, mouseY);
    }	
}

// Heart Curve
// https://mathworld.wolfram.com/HeartCurve.html
function heart(pX, pY) {
    var da = .01; // How round the "curve" is
    // Creates the heart curve
    beginShape();
    for (var t = 0; t <= TWO_PI; t += da) {
        // The parametric equations found on the website commented above
        var x = (16*(pow(sin(t), 3))) * hS;
        var y = (13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t)) * -hS;
        vertex(x+pX, y+pY);
    }
    endShape();
}

// Infinity Curve
// https://en.wikipedia.org/wiki/Lemniscate_of_Bernoulli
function infinity(pX, pY) {
    var da = .01;
    // Creates the infinity curve
    beginShape();
    for (var t = 0; t <= TWO_PI; t += da) {
        // The parametric equations found on the website commented above
        var x = (iS*cos(t))/(1+(pow(sin(t), 2)));
        var y = (iS*sin(t)*cos(t))/(1+(pow(sin(t), 2)));
        vertex(x+pX, y+pY);
    }
    endShape();
}

function mousePressed() {
    if (nP == 4) {
        clear();
        background(59, 17, 21, t);
        nP = 1;
    } else {
        clear();
        background(59, 17, 21, t);
        nP += 1;
    }
    // Increase size of each pixel symbol
    t += incT;
    tS += incIT;
    hS += incH;
    iS += incIT;
    // Decrease size after certain point
    if (t == 255 || tS == 30 || hS == 1.5 || iS == 30) {
        incT *= -1;
	incH *= -1;
	incIT *= -1;
    } if ( t == 1 || tS == 10 || hS == .3 || iS == 15) {
	incT *= -1;
	incH *= -1;
	incIT *= -1
    }
}
First portrait at 1 minute w/o drawing w/ cursor
After a minute using cursor
After 30 secs w/ cursor

LO – 9

I decided to look at Helen Cheng’s looking outwards from week 2. It was on Robert Hodgin’s ‘Traffic’ piece. Being a driver myself, I found this piece very interesting and agreed on many of the points Helen mentioned in her blog post. The simulation is busy, and the cars have an “aggressiveness” to them like humans do. I can’t tell you how many times I’ve been overwhelmed by cars running reds, blocking the intersection, etc. People don’t always make the smartest decisions on the road, and this simulation captures it pretty well. The thing I find the most interesting, however, is the attempt to make a computer act human. Even with the “aggressiveness” coded in, this project doesn’t make accidents happen and the traffic still flows more seamlessly than traffic in real life. I know it would be much more difficult to code and he wanted to keep things pretty simple, but it somewhat works in a way. What I mean by that is the whole idea of self-driving cars. Once self-driving cars are at their finest, and everyone is using them accidents should be minimal and traffic will probably look quite similar to this. It was very interesting to think about how code can be manipulated to show human flaws, and on the flip-side, give us insight into what automation has the potential for.

As always, here’s the link to Robert’s website:

And two videos of his simulation:

Looking Outwards – 08

Mike Tucker is an interactive designer and developer currently living in London. For the past five years he has worked at Magic Leap, based in Florida, with the official title of Interactive Director, Designer, and Developer. He is somewhat of a quirky guy, who likes to refer to himself in the third person. He attended Virginia Commonwealth University earning a Bachelor of Fine Arts degree in Graphics Design. Mike is working on developing the future of Spatial Computing and hopes the next wave of spatial designers will question expectations of the media, and have the opportunity in designing a mixed reality future. 

While initially his art pieces attracted me, learning about how he works inspired me. His search for more reminds me of an entrepreneur I interviewed last year. He has this entrepreneurial spirit, which I admire as I attempt to minor in innovation and entrepreneurship and am very driven to the entrepreneurial world. He started out drawing, but he wanted something more. He was on a quest to find the perfect medium for creating. He went through various platforms, such as websites, mobile apps, etc. until he stumbled upon virtual reality. My favorite piece from him to date is Tónandi, where music and virtual reality interact. With the Icelandic artist Sigur Rod and Magic Leap, he created a work of art where tone spirits (the translation of Tónandi) inhibit your space and together form a music soundscape. You the “player” interact with the virtual creatures to evolve the soundscape. I love this because as I have mentioned in previous looking outwards posts, I am very interested in seeing how the music industry can change with computer interaction. 

I will close with highlighting his presentation. I appreciated him starting from the beginning, after giving a general overview, and breaking down what he was going to talk about in his presentation. There were also many visuals, static and moving, to help explain and visualize his work. While he stumbled over his words a bit, I was definitely more engaged by seeing all the images and videos. Even with his being awkward on stage he was very clear and articulate by outlining his talk and providing engaging material to keep the audience from nodding off. I would definitely take these techniques into consideration for future presentations.

Here’s a link to his website:

https://mike-tucker.com/15/

Here’s the lecture, you’ll have to search it on the page four of the website because apparently it is private:

https://vimeo.com/channels/eyeo2019/page:4

Here’s a video of the project I like most:

And here’s a link to the Magic Leap’s website featuring Tónandi:

https://world.magicleap.com/en-us/details/com.magicleapstudios.tonandi

Project-07-Butterfly Curve

sketchsl07.Download
// Sarah Luongo   
// sluongo
// sluongo@andrew.cmu.edu
// Project

/* This code aims to create the curve, butterfly curve, as explained on Wolfram
MathWorld. In addition to drawing the curve I played around with the fill color
and stroke depending on the X position of the mouse. */

// Setups canvas size and speed
function setup() {
    createCanvas(480, 480);
    frameRate(10);
}

// Draws the butterfly curve
function draw() {
    var red = random(255); // Random shade of red
    var green = random(255); // Random shade of green
    var blue = random(255); // Random shade of blue

    background(0); // Black background
    translate(width/2, height/1.64); // Translate to the "center" of canvas
    rotate(PI); // Rotate 180 degrees

    if (mouseX < width/3) {                           
        fill(red, green, blue); // Random fill color      
	stroke(0); // Black
	// Draws butterfly curve 4 times
        for (var i = 0; i < 4; i++) {
            drawButterflyCurve(i);
        }  
    } else if (mouseX >= width/3 & mouseX < 2*(width/3)) {
	noFill();
	stroke(red, green, blue); // Random stroke color
	// Draws butterfly curve 4 times
        for(var i = 0; i < 4; i++) {
            drawButterflyCurve(i*2); // i*2 makes size of curve bigger
        }
    } else if (mouseIsPressed) {
	background(225, 200, 255); // Purple background
	noFill();
	stroke(0); // Black
	drawButterflyCurve(1); // To see original curve
    } else {
	noStroke();
	fill(red, green, blue); // Random fill color
	// Draws butterfly curve 4 times
        for(var i = 0; i < 4; i++) {  
            drawButterflyCurve(i/3); // i/3 makes size of curve smaller
        }
    }
}

// Butterfly Curve
// https://mathworld.wolfram.com/ButterflyCurve.html
function drawButterflyCurve(j) {
    var da = .01; // How round the "wings" are
    var a = map(mouseX, 0, width, 0, width/9); // Constrain x size of butterfly curve 
    var b = map(mouseY, 0, height, 0, width/8); // Constrain y size of butterfly curve
    // Creates the butterfly curve
    beginShape();
    for (var t = 0; t <= 24*PI; t += da) {
	// The parametric equations found on the website commented above
	var r =  exp(cos(t))-2*cos(4*t)-pow(sin(t/12), 5);
	var x = a * sin(t) * r * j;
	var y = b * cos(t) * r * j;
	vertex(x, y);
    }
    endShape();
}

When I saw this curve on Wolfram MathWorld, I was super excited because I had attempted to draw a butterfly in my last project. I think this curve is way cooler because there’s a lot more curves and more going on. So, it wasn’t just a boring (although I don’t find it so boring) Butterfly Curve, I added some if statements to duplicate the curves, change colors of the fill and stroke, but if this is too much for you you can also click the mouse in the bottom right to get the normal curve. Also, moving the mouse up and down and side to side within each if statement changes the size of the curves. If you move it left to right within a third of the width it kind of looks like the butterfly is flapping it’s wings.

Mouse within 0 and 1/3 of the width
Mouse within 1/3 and 2/3 of the width
Within 2/3 and 3/3 of the width
Within 2/3 and 3/3 of the width if mouse is pressed (best if clicked at bottom right)

LO-07

When I saw this assignment I immediately thought of the subreddit DataIsBeautiful. As I was scrolling through it, I found one that was very cool and interesting. It was a Visualizations of Color Themes in Pixar Films by redditor /keshava7 created about 4 months ago. I love Pixar films, and I’ve watched almost every one. Some of the older ones give me a great sense of nostalgia. Their visualization of data using Pixar films is very pretty, and I like how they are all shaped like disks. It reminds me of the old Blu Ray disks (although I also remember the older format of VHS). They created this visualization in Python by extracting 5000 frames per movie, and they compressed each frame into a pixel. They start each movie at 270 degrees and go clockwise, so the first frame of each movie starts at 270 degrees. There is another redditor /julekca who gives a more detailed description on how to do it, it makes me want to try it myself. It is very beautiful to see all the different colors of some of the films I watched as a child.

Here’s a link to the post: