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!
//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);
}*/
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.
// 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;
}
}
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:
// 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!
]]>“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:
To see this specific piece:
http://slork.stanford.edu/works/aura/
And here’s the video:
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.
// 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
}
}
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:
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:
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
]]>// 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.
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: