// Jessica Timczyk
// Section D
// jtimczyk@andrew.cmu.edu
// Final-Project
///////// GLOBAL VARIABLES ///////////
var terrainDetail = 0.005;
var intercols = [];
/////// snow globals //////
var snow = [];
var gravity;
var zOff = 0;
var mt = [];
///// elephant globals //////
var frames = []; // store images
var frameIndex = 0;
var system; // particle system for elephants water
var trunkUp = false;
var counter = 0;
var click = -1;
//////// sound globals ////////
var elephantSound;
var birdSound;
var tigerSound;
///////// water waves globals /////////////
var t = 0;
///////// bush globals //////////////
var bush;
var bush1y= 240;
var bush2y = 350;
function preload() {
////////////////// ELEPHANT IMAGE PRELOADS ////////////////
// urls for each elephant image of movement cycle
var filenames = [];
filenames[0] = "https://i.imgur.com/PSJnCjQ.png";
filenames[1] = "https://i.imgur.com/PbWyeNh.png";
filenames[2] = "https://i.imgur.com/s0o7oWG.png";
// stores each picture into an array
for (var i = 0; i < 3; i++) {
frames[i] = loadImage(filenames[i]);
}
////////////////// BUSH PRELOADS ////////////////////
bush = loadImage("https://i.imgur.com/jdxSCfo.png");
////////////////// SOUND PRELOADS //////////////////
elephantSound = loadSound("https://courses.ideate.cmu.edu/15-104/f2018/wp-content/uploads/2018/12/139875__y89312__44-1.wav");
elephantSound.setVolume(0.5);
birdSound = loadSound("https://courses.ideate.cmu.edu/15-104/f2018/wp-content/uploads/2018/12/238144__m4d3r0__small-bird-jungle-sounds-v3-2.wav");
birdSound.setVolume(0.5);
tigerSound = loadSound("https://courses.ideate.cmu.edu/15-104/f2018/wp-content/uploads/2018/12/439280__schots__angry-tiger-4.wav")
tigerSound.setVolume(0.5);
}
function setup() {
createCanvas(600, 400);
background(219, 245, 250);
////////////// MOUNTAIN SET UP /////////////
for (var x = 0; x < width; x++) { // createse a random static mountain range using noise every time refreshed
var t = (x * terrainDetail)
var y = map(noise(t), 0,1, 0, height/ 1.5);
mt.push([x,y,height]); // pushes the array into the mt array
}
//////////// ELEPHANT WATER PARTICLE SYSTEM ///////////
system = new ParticleSystem(createVector(260, 230)); // creates a particle system for the elephants water
//////////// SNOWFLAKE SET UP ////////////
gravity = createVector(0, 0.2); // gravity vector
for (var i = 0; i < 200; i++){ // creates the 200 snowflakes and gives them random starting positions
var x = random(width);
var y = random(height);
snow.push(new Snowflake(x,y)); // pushes new snowflake into the array
}
}
function draw() {
background(25, 28, 84);
drawNorthernLights();
drawScenary();
drawTrees();
drawBush();
////////////////// ELEPHANT /////////////////////
drawElephant();
if (frameIndex === 2) { // water comes out of his trunk when its in the up position
elephantWater();
}
if (mouseIsPressed & trunkUp == false && mouseX > 150 && mouseX < 300 && mouseY > 190 && mouseY < 350 && (click%2 === 0)) { // if mouse pressed on elephant trunk moves up
counter = 0
trunkUp = true
}
if (trunkUp == true) {
moveUp()
}
if (mouseIsPressed && counter > 32 && (click%2 != 0) && mouseX > 150 && mouseX < 300 && mouseY > 190 && mouseY < 350) { // when the elephant is clicked a second time it puts and keeps trunk down
counter = 0;
frameIndex = 0;
trunkUp = false;
}
drawTrees2(); // second set of trees that are infront of the elephant
drawBush2(); // second set of bushes that are infront of elephant
if (mouseX > 400 & mouseX < 480 && mouseY > 220 && mouseY < 260) { // the bush hops when mouse is scrolled over it
bush1y += random(-5, 5);
}
if (mouseX > 30 & mouseX < 130 && mouseY > 345 && mouseY < 385) { // the bush hops when mouse is scrolled over it
bush2y += random(-5, 5);
}
////////////////// DRAWING SNOWFLAKE /////////////
zOff += 0.01; // z offset
for (flake of snow) { //the position, gravity and wind forces are unique to each snowflake
var xOff = flake.pos.x / width;
var yOff = flake.pos.y / height;
var wAngle = noise(xOff, yOff, zOff) * TWO_PI;
var wind = p5.Vector.fromAngle(wAngle);
wind.mult(0.2);
flake.applyForce(gravity);
flake.applyForce(wind);
flake.update();
flake.render();
}
mySounds(); // plays sounds
}
function drawScenary() {
/////////// MOUNTAINS /////////////
stroke(76, 86, 109); // Grey color of mountains
noFill();
beginShape();
for (var x = 0; x < width; x++) { // createse a random static mountain range using noise every time refreshed
line(mt[x][0], mt[x][1], mt[x][0], mt[x][2]);
}
endShape();
////////////// GROUND ///////////////
noStroke();
fill(196, 157, 112);
rect(0, height / 2 + 20, width, height / 2 - 20);
/////////// POND ///////////////
noStroke();
fill(69, 156, 223);
ellipse(width - 40, height - 60, 500, 150);
}
///////////////////// BUSHES ///////////////////////
function drawBush() { // draws bush images that sit behind the elephant
imageMode(CENTER);
image(bush, 440, bush1y, 150, 70); // variable so that it wiggles up and down
image(bush, 320, 260, 150, 70);
image(bush, 85, 240, 190, 70);
}
function drawBush2() { // draws bush images that sit infront of the elephant
imageMode(CENTER);
image(bush, 310, 380, 180, 70);
image(bush, 70, bush2y, 150, 70); // variable so that bush shakes when moused over
}
/////////////////// ELEPHANT /////////////////////
function drawElephant() { // elephant picture
imageMode(CENTER);
image(frames[frameIndex], 230, 270, 200, 200);
}
function moveUp() { // moves trunk all the way up when clicked once
if (click%2 == 0) { // when the elephant is clicked an odd time the trunk just goes down
counter += 1;
if (counter == 15) {
frameIndex = 1;
}
if (counter == 30) {
frameIndex = 2;
}
}
}
function mousePressed() { // increases click count when mouse is pressed once and mouse on elephant
if (mouseX > 150 & mouseX < 300 && mouseY > 190 && mouseY < 350){
click += 1;
}
}
function elephantWater() { // run particle system
system.addParticle();
system.run();
}
// simple particle class
var Particle = function(position) {
this.acceleration = createVector(0, 0.05);
this.velocity = createVector(random(-1, 1), random(-1, 0));
this.position = position.copy();
this.lifespan = 255;
}
Particle.prototype.run = function() {
this.update();
this.display();
}
// updating position
Particle.prototype.update = function() {
this.velocity.add(this.acceleration);
this.position.add(this.velocity);
this.lifespan -= 2;
}
// display method for particles
Particle.prototype.display = function() {
stroke(190, 244, 250, this.lifespan);
strokeWeight(2);
fill(143, 239, 250, this.lifespan);
ellipse(this.position.x, this.position.y, 12, 12);
}
// check if particle is still useful
Particle.prototype.isDead = function() {
return this.lifespan < 0;
}
var ParticleSystem = function(position) { // position of particles
this.origin = position.copy();
this.particles = [];
}
ParticleSystem.prototype.addParticle = function() { // pushes a new particle into the system at the starting point
this.particles.push(new Particle(this.origin));
}
ParticleSystem.prototype.run = function() { // gets rid of particles that have expired
for (var i = this.particles.length-1; i >= 0; i--) {
var p = this.particles[i];
p.run();
if (p.isDead()) {
this.particles.splice(i, 1);
}
}
}
////////////////// TREES ////////////////////////
function drawTrees() { // trees that are positioned begind elephant
push();
translate(550, 250);
drawBranch(0, map(mouseY, 0, 400, 15, 20));
pop();
push();
translate(150, 250);
drawBranch(0, map(mouseY, 0, 400, 15, 20));
pop();
push();
translate(100, 290);
drawBranch(0, map(mouseY, 0, 400, 15, 20));
pop();
}
function drawTrees2() { // trees that are positioned in front of elephant also rotate opposite way
push();
translate(100, 350);
drawBranch2(0, map(mouseY, 0, 400, 15, 20));
pop();
push();
translate(500, 260);
drawBranch2(0, map(mouseY, 0, 400, 15, 20));
pop();
}
function drawBranch2(depth, len) { // same as drawtree but these trees are positioned infront of the elephant
strokeWeight(depth / 3 + 1);
stroke(random( 15, 180), random(100, 244), random(10, 100)); // continuously changing green color
line(0, 0, 0, -len);
push();
translate(0, -len);
drawTree2(depth + 1, len);
pop();
}
function drawTree2(depth, len) { // same as drawtree but these trees are positioned infront of the elephant
if (depth < 8) {
rotate(radians(map(mouseX, 400, 0, -5, 5))); // allows trees to rotate with mouse
drawBranch2(depth, len);
rotate(radians(30));
drawBranch2(depth, len);
}
}
function drawBranch(depth, len) { // idividual branch details
strokeWeight(depth / 3 + 1);
stroke(random( 15, 180), random(100, 244), random(10, 100)); // continuously changing green color
line(0, 0, 0, -len);
push();
translate(0, -len);
drawTree(depth + 1, len);
pop();
}
function drawTree(depth, len) { // draws the two sides of the tree branches
if (depth < 8) {
rotate(radians(map(mouseX, 0, 400, -30, -20))); // allows trees to rotate with mouse
drawBranch(depth, len);
rotate(radians(30));
drawBranch(depth, len);
}
}
////////////////// NORTHERN LIGHTS ///////////////////
function drawNorthernLights() {
noStroke();
fill(random( 15, 180), random(10, 100), random(100, 244), 190); // make colors change and transparent to look like northern lights
// make a x and y grid of circles
for (let x = 0; x <= width; x = x + 30) {
for (let y = 0; y <= height / 2 + 20; y = y + 30) {
// starting point of each circle depends on mouse position
let xAngle = map(mouseX, 0, width, -4 * PI, 4 * PI, true);
let yAngle = map(mouseY, 0, height, -4 * PI, 4 * PI, true);
// also varies based on the particle's location
let angle = xAngle * (x / width) + yAngle * (y / height);
// each particle moves in a circle
let myX = x + 20 * cos(2 * PI * t + angle);
let myY = y + 20 * sin(2 * PI * t + angle);
ellipse(myX, myY, 10); // draw particle
}
}
t = t + 0.01; // update time
}
////////////////// SNOWFLAKES ///////////////////
function getRandomSize() { // makes a randomly sized snowflake that is more likely to be smaller
var r = pow(random(0, 1), 5);
return constrain(r * 32, 2, 36);
}
class Snowflake {
constructor() { // snowflake object
var x = random(width);
var y = random(-100, -10);
this.pos = createVector(x, y);
this.vel = createVector(0, 0);
this.acc = createVector();
this.angle = random(TWO_PI);
this.dir = (random(1) > 0.5) ? 1 : -1;
this.xOff = 0;
this.r = getRandomSize(); // random sizr of snowflakes
}
applyForce(force) {
// parallax effect hack
var f = force.copy();
f.mult(this.r);
this.acc.add(f); // add acceleration force
}
randomize() { // gives flakes a random starting poisiton above the canvas
var x = random(width);
var y = random(-100, -10);
this.pos = createVector(x, y);
this.vel = createVector(0, 0);
this.acc = createVector();
this.r = getRandomSize();
}
update() { // updates positions, speeds, angles and etc of snow
this.xOff = sin(this.angle * 2) * 2 * this.r; // sine wave making snow move in addition to perlin noise
this.vel.add(this.acc); // velocity calculations
this.vel.limit(this.r * 0.2);
if (this.vel.mag() < 1) {
this.vel.normalize();
}
this.pos.add(this.vel);
this.acc.mult(0);
if (this.pos.y > height + this.r){ //gives them a new random position when they reach the bottom of the screen
this.randomize();
}
// flakes wrap left and right
if (this.pos.x < -this.r) {
this.pos.x = width + this.r;
}
this.angle += this.dir * this.vel.mag() / 200; // spin of flakes goes different directions, also dependent on their speed
}
render(){ // draw the snowflakes
stroke(255);
push();
strokeWeight(this.r);
translate(this.pos.x + this.xOff, this.pos.y);
point(0, 0);
pop();
}
}
function mySounds() {
// elephant sound
// plays sound when elephants clicked on and only when trunk us down
if (mouseIsPressed & mouseX > 150 && mouseX < 300 && mouseY > 190 && mouseY < 350 && click%2 == 0) {
elephantSound.play();
}
// bird sound
// plays sound when bush is clicked on
if (mouseIsPressed & mouseX > 30 && mouseX < 130 && mouseY > bush2y - 20 && mouseY < bush2y + 20) {
birdSound.play();
}
// tiger sound
// plays sound when bush is clicked on
if (mouseIsPressed & mouseX > 400 && mouseX < 480 && mouseY > bush1y - 20 && mouseY < bush1y + 20) {
tigerSound.play();
}
}
After following the instructions for uploading sounds onto WP, my program will run perfectly but the sounds for some reason are still not working. Therefore, I have additionally included a zip of my final project so that you can see the working sounds. All you need to do is unzip the file and open it using a local server. After troubleshooting many times, I am still unsure why the sound will not work over WordPress. Final Project
I really enjoyed doing this project, it forced me to use new techniques and functions that I never had before. I really wanted this to be an interactive picture, using many complex computations to make things move and etc.
]]>For my final project, I would like to create an interactive animation. As I drew in my sketch of my final project, I would like to create a jungle- like scene with elephants, fish and possibly another animal. To make it interactive, many aspects of the photo will move or change in some way when the user clicks on them, for example, clicking on the elephants makes them either raise their trunk or move their ears, the leaves of the trees rustle, the fish fins move when they’re clicked, and etc. Some of the interaction will also depend on the movements of the user’s mouse rather than simply a click, for example, the sun will rotate and the rays will change size as the mouse moves across the screen, or the cattails will move when the mouse grazes over them. To additionally make it interesting, I will include sounds with the scene, making jungle-esque music play in the background, but then depending on what is clicked on, different sounds will play. Elephants will make their horn sounds when clicked on, leaves rustling and others. I hope to add a few more details than what is just on the drawing, but that is the basis for now.
]]>In preparation for making my own final project, which will be an interactive animation, I researched some other interactive animations and found these two very interesting projects. The first project is a VR and 3D interactive animated doodle by Fx Goby and Google Doodle artist Hélène Leroux made in 2018, in tribute to filmmaker Georges Méliès called ‘Back to the Moon‘. The doodle allows the viewer to move around and look at the animated environment in 360 degrees. The second project, called ‘Solace’ is also an interactive film created in 2017 by Evan Boehm and Jeff Noon in collaboration with Nexus Interactive Studios. The project takes the viewer through a narrated story in which the viewer can interact with almost all of the shapes and pictures making up the story with their mouse. Unlike the first interactive animation, ‘Solace‘ allows the viewer to actually interact with the images and shapes that make up the characters and etc of the story, whereas ‘Back to the Moon’ only allows the viewer to move around in the frame. Though I really enjoy the interactivity of ‘Solace’, I think I personally am partial to the 3D environment of ‘Back to the Moon’ and also the story line that accompanies it. I think that ‘Back to the Moon’, though very innovative in itself, missed an opportunity to make the actual story line and images interactive. Overall, I very much enjoyed both. You can play with both of them in the link or video below.
]]>
// Jessica Timczyk
// Section D
// jtimczyk@andrew.cmu.edu
// Project-
var turtle
function setup() {
createCanvas(480, 480);
background(0);
frameRate(10);
}
function draw() {
turtle = makeTurtle(mouseX, mouseY); // make turtle variables
angle = turtle.angleTo(mouseX, mouseY);
turtle.right(angle);
turtle.forward(40);
turtle.setWeight(6) // setting the specifications for the turtles lines
strokeJoin(MITER);
strokeCap(PROJECT);
turtle.setColor(random(255)); //random colors
turtle.penDown(); // make swirl shape
turtle.forward(3);
turtle.left(90);
turtle.forward(50);
turtle.right(90);
turtle.forward(50);
turtle.right(90);
turtle.forward(37.5);
turtle.right(90);
turtle.forward(25);
turtle.right(90);
turtle.forward(12.5);
turtle.right(90);
turtle.forward(12.5);
turtle.left(90);
turtle.forward(12.5);
turtle.left(90);
turtle.forward(25);
turtle.left(90);
turtle.forward(37.5);
turtle.left(90);
turtle.forward(47);
turtle.goto(mouseX,mouseY);
}
function turtleLeft(d) {
this.angle -= d;
}
function turtleRight(d) {
this.angle += d;
}
function turtleForward(p) {
var rad = radians(this.angle);
var newx = this.x + cos(rad) * p;
var newy = this.y + sin(rad) * p;
this.goto(newx, newy);
}
function turtleBack(p) {
this.forward(-p);
}
function turtlePenDown() {
this.penIsDown = true;
}
function turtlePenUp() {
this.penIsDown = false;
}
function turtleGoTo(x, y) {
if (this.penIsDown) {
stroke(this.color);
strokeWeight(this.weight);
line(this.x, this.y, x, y);
}
this.x = x;
this.y = y;
}
function turtleDistTo(x, y) {
return sqrt(sq(this.x - x) + sq(this.y - y));
}
function turtleAngleTo(x, y) {
var absAngle = degrees(atan2(y - this.y, x - this.x));
var angle = ((absAngle - this.angle) + 360) % 360.0;
return angle;
}
function turtleTurnToward(x, y, d) {
var angle = this.angleTo(x, y);
if (angle < 180) {
this.angle += d;
} else {
this.angle -= d;
}
}
function turtleSetColor(c) {
this.color = c;
}
function turtleSetWeight(w) {
this.weight = w;
}
function turtleFace(angle) {
this.angle = angle;
}
function makeTurtle(tx, ty) {
var turtle = {x: tx, y: ty,
angle: 0.0,
penIsDown: true,
color: color(128),
weight: 1,
left: turtleLeft, right: turtleRight,
forward: turtleForward, back: turtleBack,
penDown: turtlePenDown, penUp: turtlePenUp,
goto: turtleGoTo, angleto: turtleAngleTo,
turnToward: turtleTurnToward,
distanceTo: turtleDistTo, angleTo: turtleAngleTo,
setColor: turtleSetColor, setWeight: turtleSetWeight,
face: turtleFace};
return turtle;
}
I really enjoyed doing this project. I had originally intended for the swirls to make a continuous line across the screen but after multiple tries I couldn’t seem to get them to follow each other. I think using turtle to create visuals is very fun and makes it a lot easier because it allows me to create individual shapes and patterns, like these swirls that can be moved all together without having to individually put in each value. next time I would like to try to figure out to create these patterns but have them be all connected with each other in a nice line.
]]>The Eigenharp is an electronic instrument made by Eigenlabs in 2008, based in the UK and invented by John Lambert. The instrument is essentially a highly flexible and portable controller, in which the sound or music is being generated in the software that it drives. I really like this project because I find it interesting that it visually looks like a wind instrument like a bassoon, but is in fact an electronic instrument. Each of the keys are velocity sensitive and act like a joystick. Although I am not entirely sure how the algorithm behind the instrument works, I suppose that it works by changing or altering the sound that comes out the intstrument based upon the keys that the player presses. The artistic influence of the creator can be seen in the array of different manipulations that a player can influence given the keys on the instrument.
]]>// Jessica Timczyk
// Section D
// jtimczyk@andrew.cmu.edu
// Project-10-Landscape
var cacti = [];
var cactusClip;
var terrainSpeed = 0.0005;
var terrainDetail = 0.005;
var tumbleweed = [];
function preload() {
cactusClip = loadImage("https://i.imgur.com/f4O5OGj.png?1");
}
function setup() {
createCanvas(480, 240);
// create an initial collection of cacti
for (var i = 0; i < 10; i++){
var rx = random(width);
cacti[i] = makeCactus(rx);
}
frameRate(10);
}
function draw() {
background(212, 248, 251);
////////// Mountains //////////
stroke(129, 161, 164);
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail) + (millis() * terrainSpeed);
var y = map(noise(t), 0,1, 0, height);
line(x, y, x, height);
}
endShape();
/////// sun beam ////////
beginShape();
for (var x = 0; x < width; x++) {
fill(221, 204, 112);
var t = (x * terrainDetail) + (millis() * terrainSpeed);
var y = map(noise(t), 0,1, 0, height);
vertex(x, y);
}
endShape();
noFill();
rect(0, 0, width - 1, height - 1);
//// cactus //////
displayHorizon();
updateAndDisplayCacti();
removeCactiThatHaveSlippedOutOfView();
addNewCactiWithSomeRandomProbability();
//// tumble weed ///////
for (var k = 0; k < tumbleweed.length; k++){
tumbleweed[k].draw();
tumbleweed[k].move();
}
addNewTumbleWeedWithSomeRandomProbability();
}
function updateAndDisplayCacti(){
// Update the cacti positions and display them
for (var i = 0; i < cacti.length; i++){
cacti[i].move();
cacti[i].display();
}
}
function removeCactiThatHaveSlippedOutOfView(){
var cactiToKeep = [];
for (var i = 0; i < cacti.length; i++){
if (cacti[i].x + cacti[i].breadth > 0) {
cactiToKeep.push(cacti[i]);
}
}
cacti = cactiToKeep; // remember the cacti that stay
}
function addNewCactiWithSomeRandomProbability() {
// With a very tiny probability, add a new cacti to the end
var newBuildingLikelihood = 0.03;
if (random(0,1) < newBuildingLikelihood) {
cacti.push(makeCactus(width));
}
}
// method to update position of cactus every frame
function cactusMove() {
this.x += this.speed;
}
// draw the cactus
function cactusDisplay() {
var cHeight = this.cactusHeight;
fill(255);
stroke(0);
push();
translate(this.x, height - this.cactusPlacement);
image(cactusClip, 0, -cHeight);
pop();
}
function makeCactus(birthLocationX) { // cactus object
var cct = {x: birthLocationX,
breadth: 50,
speed: -3.0,
cactusHeight: round(random(0, 175)),
move: cactusMove,
cactusPlacement: round(random(0,70)),
display: cactusDisplay}
return cct;
}
function makeTumbleWeed() { // random colors
var tbwd = {x: width,
y: -height + 100,
move: moveTumbleWeed,
draw: drawTumbleWeed,
color: [random(50, 180), random(50, 165), random(20, 55)],
}
return tbwd;
}
// draw tumbleweed
function drawTumbleWeed(){
stroke(this.color);
strokeWeight(4);
noFill();
ellipse(this.x, height - this.y - 60, 30, 30,);
ellipse(this.x + 5, height - this.y - 62, 20, 20);
ellipse(this.x + 2, height - this.y - 57, 5, 5);
ellipse(this.x - 4, height - this.y - 61, 15, 15);
ellipse(this.x -1, height - this.y - 60, 20, 20);
}
function moveTumbleWeed(){ //tumble weed moves more quickle than cacti
this.x -= 10;
this.y = random(10);
}
function addNewTumbleWeedWithSomeRandomProbability() {
// tumble weeds are alot less likely than cacti
var newTumbleWeedLikelihood = 0.007;
if (random(0,1) < newTumbleWeedLikelihood) {
tumbleweed.push(makeTumbleWeed(width));
}
}
function displayHorizon(){
stroke(162, 126, 78);
fill(201, 160, 106);
rect(0, height - 75, width, height - 75);
}
I enjoyed doing this project because it allowed me to make my own landscape, where as in the past we have always been given a template for them. I struggled a bit to enter in new moving objects, and took me awhile to understand all the commands and what each function was doing. Some things, like the sunlight beam, happened by accident because I was messing with different variables but I’m very happy with how it turned out. If I were to do this again I would probably want to add more details to the sky, or figure out how to make more complicated generated landscapes besides the mountain like line that we were offered with. Overall I’m happy with how it came out.
Ingrid Burrington is an author, activist, and hacker and has worked on many exhibitions, projects making maps, writing books and teaching at various schools including Cooper Union and the Rhode Island School of Design. She is from and still lives in New York City, and I unfortunately was unable to find where she went to school. One of her most interesting works, I have found, is her website and book Seeing Networks in New York City, that details New York’s network infrastructure. I found this project incredibly interesting because when in New York, normally a visitor is looking for and paying attention to all the sight-seeing and famous buildings and etc. that are there, but this project provides a map of city focusing on features that are commonly over looked. For example man hold covers, street markings and antennas. This project provides a different way to look at New York that I find incredibly interesting.
]]>
// Jessica Timczyk
// Section D
// jtimczyk@andrew.cmu.edu
// Project-09-Portrait
// global variables
var underlyingImage;
var sx = [];
var sy = [];
var dx = [];
var dy = [];
function preload() { // preloads image
var myImageURL = "https://i.imgur.com/CKGh2Ed.jpg?1";
underlyingImage = loadImage(myImageURL);
}
function setup() {
createCanvas(300, 400);
background(255);
underlyingImage.loadPixels();
for (i = 0; i < 1000; i++){ // for loop to randomly pick the positions and speed of each square
sx[i] = random(width);
sy[i] = random(height);
dx[i] = random(-5, 5);
dy[i] = random(-5, 5);
}
frameRate(10);
}
function draw() {
background(255);
noStroke();
for (i = 0; i < 1000; i++) {
var colorAtSquare = underlyingImage.get(sx[i], sy[i]); // the color of each square changes as it moves across
// the screen to match the photo under neath
fill(colorAtSquare);
rect(sx[i], sy[i], 20, 20); // drawing the rectangles and updating their locations with the speed
sx[i] += dx[i];
sy[i] += dy[i];
// lets the rectangles wrap arround to the other side when they go off screen
if (sx[i] > width){
sx[i] = 0;
} else if (sx[i] < 0) {
sx[i] = width;
}
if (sy[i] > height) {
sy[i] = 0;
} else if (sy[i] < 0) {
sy[i] = height;
}
}
}
It took me a while to decide on how I wanted to make this portrait. Although I knew which photo I wanted to do, I wasn’t sure how I wanted to manipulate it. I ended up really like this project because it allowed me manipulate photos in fun and interesting ways.
For this looking outwards I decided to do JJ Legelis’ post on 3D computer graphics in the movie Star Wars: Rogue One from this year, 2018. In this movie they used CGI through motion capture technology that allows you to use a real life actor’s movements and motions to map a CGI model on top that creates the illusion that the diseased actor, in this case Peter Cushing, is actually there. This is extremely useful for not only Star Wars but other franchises in which a actor or actress may die before being able to film another sequel, that way writers do not have to completely get rid of their characters. I agree with JJ’s assessment of the technology because not only is it extremely impressive how accurate but also realistically flawless the CGI is. I would only like to add that though this technology is extremely interesting and effective, with this much replication power it becomes important to recognize morals and the wishes of the family and the passed person themselves in manipulating
their image.
]]>Zach Lieberman is an American new media artist and computer programmer, he received an MFA of Design and Technology from Parson’s School of Design. He is based in New York City and describes himself as an artist that creates with code, focusing on interactive and experimental drawing and animation tools. Most of his work involves these abstract drawing tools and interactive animations and environments in performances. I really like the artists’ work because the interactive aspect of it allows people who interact with it to become the “performer” themselves. One of his projects that I admire the most is the Eyewriter project. It is a very low cost and open source hardware tool that allows people to draw with their eyes. I found this one the most inspiring because it was originally created for a paralyzed graffiti artist so that he could draw graffiti with his eyes even after being paralyzed. What I admire most about how Zach Lieberman works is how all or most of the projects he create are not only artistic and beautiful but also contain real applications that are still useful and many times help people that sometimes wouldn’t otherwise be able to create their own art.
While he is presenting his work, he not only gives a demo of how it works, but then also goes on to explain why he created this thing and his process in getting there. He as well additionally gives examples to other applications of the technology he created, which is useful in seeing other applications. I think this would be helpful if I were presenting my own work to convey that what I’m presenting is not constrained to the form that it is presented in currently, but can also be used in other ways and applications.
Eyeo2012 – Zach Lieberman from Eyeo Festival on Vimeo.
A video showing the Eyewriter and how it is used and works.
]]>