Final Project – Interactive Calendar

sketch
//Diana McLaughlin and Shaun Murray
//dmclaugh@andrew.cmu.edu and shaunmur@andrew.cmu.edu
//Section A and Section B
//A calendar commemorating a major event from each month in 2020
//All global variables except image variables are with the start of the respective month's program. Some of these variables are called in set up, but you'll find them before their clickMonthX() function
//Shaun's code starts at clickMonthJan(). He also wrote the makeCalendar() function
//Diana's code starts at clickMonthJul(). She also wrote the writeMonths() function
//Aside from the makeCalendar and writeMonths functions, Shaun did everything related to January - June and Diana did everything related to July - December
//"The biggest waste of computer processing power in 15-104"

//Image Variables
//for the main calendar
var imgJanCal, imgFebCal, imgMarCal, imgAprCal, 
	imgMayCal, imgJunCal, imgJulCal, imgAugCal, 
	imgSepCal, imgOctCal, imgNovCal, imgDecCal;

//for the month functions
var imgJan2, imgMar, aprImg, aprImg2, 
    aprImg3, imgJun1, imgJun2, imgJun3, 
    imgJul, imgOct, imgNov;


function preload() {
	imgJanCal = loadImage("https://i.imgur.com/mGCWr67.jpg?2"); //January main calendar
	imgFebCal = loadImage("https://i.imgur.com/8hI9x3x.jpg"); //February main calendar
	imgMarCal = loadImage("https://i.imgur.com/hozlVRU.jpg"); //March main calendar
	imgAprCal = loadImage("https://i.imgur.com/PUDQpPe.jpg"); //April main calendar
	imgMayCal = loadImage("https://i.imgur.com/FyUdmy7.png"); //May main calendar
	imgJunCal = loadImage("https://i.imgur.com/1V9Akde.jpg"); //June main calendar
	imgJulCal = loadImage("https://i.imgur.com/Tvukiin.jpg"); //July main calendar
	imgAugCal = loadImage("https://i.imgur.com/kECFW1b.jpg"); //August main calendar
	imgSepCal = loadImage("https://i.imgur.com/O6e3LcQ.jpg"); //September main calendar
	imgOctCal = loadImage("https://i.imgur.com/CcQpShS.jpg"); //October main calendar
	imgNovCal = loadImage("https://i.imgur.com/8Sqt5Um.jpg"); //November main calendar
	imgDecCal = loadImage("https://i.imgur.com/DrModlG.jpg"); //December main calendar

    imgJan = loadImage("https://i.imgur.com/UO8RoiW.png"); //santa hat for JAN
    imgJan2 = loadImage("https://i.imgur.com/lM5i1Gp.jpeg") //A-Bomb Jan
    imgFeb = loadImage("https://i.imgur.com/AIq3z8n.jpeg"); //House Chamber background
    imgMar = loadImage("https://i.imgur.com/VFoP91O.png"); //background image for March
    mayImg1 = loadImage("https://i.imgur.com/RhNvf13.jpeg"); //Kim Jong Un
	mayImg2 = loadImage("https://i.imgur.com/huOal0b.png"); //podium
	mayImg3 = loadImage("https://i.imgur.com/20G2Bj4.jpg"); //NK flag
    aprImg = loadImage("https://i.imgur.com/G0SnXSB.jpg"); //Tiger
	aprImg2 = loadImage("https://i.imgur.com/VVfSCll.jpeg"); //Oklahoma
	aprImg3 = loadImage("https://i.imgur.com/IgLfZQb.png"); //Joe Exotic
	imgJun1 = loadImage("https://i.imgur.com/V8MHehF.jpg"); //St John's Church
	imgJun2 = loadImage("https://i.imgur.com/on3fzqb.jpg"); //President
	imgJun3 = loadImage("https://i.imgur.com/SAUkUd3.jpg"); //Protesters
	imgJul = loadImage("https://i.imgur.com/FXdV1Bk.jpg"); //John Lewis photograph for July
    imgOct = loadImage("https://i.imgur.com/a7W8anl.png"); //map for Oct
    imgNov = loadImage("https://i.imgur.com/OCT1IpR.jpg"); //auditorium for November
}

function setup() {
    createCanvas(500, 400);
    makeCalendar();

    //set up March
    for (var i = 0; i < 1; i++) {
    // make virus cell
    	var v = makeVirus(200, 200,
                             random(-50, 50), random(10, 50));
        viruses.push(v);
    }

    //set up for April
    for (var i = 0; i < 12; i++){ // create an initial collection of cats
        var rx = random(width);
        tigers[i] = makeTigers(rx);
    }

    //set up August
    for (var i = 0; i < 1; i++){
        var hy = random(height/3, height);
        hurricane[i] = makeHurricane(hy);
    } 
    
    //set up September
    //set up mountains
    for (var i = 0; i <= 100; i++) {
        var n = noise(noiseParam);
        var value = map(n, 0, 1, 0, height/2);
        mountain.push(value);
        noiseParam += noiseStep;
    }  

    //set up fire
    for (var i = 0; i <= 100; i++) {
        var n = noise(fNoiseParam);
        var value = map(n, 0, 1, 0, height);
        fire.push(value);
        fNoiseParam += fNoiseStep;
    }  
    
    //draw initial trees
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        trees[i] = makeTree(rx);
    }
    
    //draw initial smoke clouds
    for (var i = 0; i < 10; i++){
        var cx = random(width);
        smoke[i] = makeSmoke(cx);
    }
    
}

function draw() {
	clickMonthJan();
	clickMonthFeb();
	clickMonthMar();
	clickMonthApr();
	clickMonthMay();
	clickMonthJun();
	clickMonthJul();
	clickMonthAug();
	clickMonthSep();
	clickMonthOct();
	clickMonthNov();
	clickMonthDec();
	backButton();
}

function makeCalendar() {
	fill(0);
    strokeWeight(1);
    //draw lines between the months on the calendar
    for (let i = 0; i < 3; i++) {
        line(0, i*133.33 + 133, width, i*133.33 + 133);
        line(i*125 + 125, 0, i*125 + 125, height);
    }

    //background pictures
    var calPics = [imgJanCal, imgFebCal, imgMarCal, imgAprCal, imgMayCal, imgJunCal, imgJulCal, imgAugCal, imgSepCal, imgOctCal, imgNovCal, imgDecCal];
    var xCo = [0.5, 125.5, 250.5, 375.5, 0, 125.5, 250.5, 375.5, 0.5, 125.5, 250.5, 375.5];
    var yCo = [0, 0, 0, 0, 132.83, 132.83, 132.83, 132.83, 267.16, 267.16, 267.16, 267.16];
    for (var i = 0; i < calPics.length; i++) {
    	image(calPics[i], xCo[i], yCo[i], 124.5, 132.83);
    }

    writeMonths();

}

function writeMonths() {
	//display text on calendar
	var monthText = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
	var monthCode = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", " ", "="];
	var monthX = [55, 180, 305, 430, 55, 180, 305, 430, 55, 180, 305, 430];
	var monthY = [65, 65, 65, 65, 200, 200, 200, 200, 335, 335, 335, 335];
	strokeWeight(1);
	textFont('Times');
    textSize(24);
    textAlign(CENTER);
    stroke(0);
    fill(255);
    for (var i = 0; i < monthText.length; i++) {
    	text(monthText[i], monthX[i], monthY[i]);
    	text(monthCode[i], monthX[i], monthY[i] + 30);
    }
    textSize(40);
    text("-", 300, 363);
    textSize(15);
    textAlign(LEFT);
    text("Press a key to begin", 3, 25); //written instruction
    text("Press ESC to return", 380, 25);
}

function backButton() { //click to return to calendar
    if (keyCode === 27) {
        clearBkrd();
        makeCalendar();

        //reset March
        v.diam = 25;

        //reset November
        pCount = 0;
        vpCount = 0;
    }
}

function clearBkrd() { //clear background
    background(255);
}

//Shaun's Code

function clickMonthJan() {
	//Referencing the anticipation of North Korea's overdue X-mas gift
    if (keyCode === 49) {
        clearBkrd();
        frameRate(30);
        JanBackground();
        USflag();
        NKflag();
        nuclear(width/2, height/2);
        JanText(45, height-85);
        backButton(); 
    }
         
}

	function JanBackground() {
		image(imgJan2, 0, 0, width, height);
	}

    function starJan() {
        var x1 = [340, 348, 364, 354, 356, 340, 324, 326, 315, 332]; //star points
        var y1 = [44, 58, 62, 75, 92, 85, 92, 75, 62, 58];
        var nPoints= x1.length;
        beginShape();
        fill('Red');
        for (var i= 0; i< nPoints; i++) {
            vertex(x1[i] + 35, y1[i] + 5);
        }
        endShape(CLOSE);
    }

    function USflag() {// United States Flag minus stars
        fill('Red');
        rect(25, 25, width/3, height/4);
        for(let i = 0; i < 7; i++) { //white rects on flag
            fill('white');
            rect(25, 30 + (i * 13.5), width/3, 7);
        }
        fill(0, 0, 155);
        rect(25, 25, 50, 50);
    }

    function NKflag() { //North Korean Flag
        fill('Blue');
        rect(width-164, 25, width/3, height/4);
        push();
        fill('Red');
        strokeWeight(5);
        noStroke();
        rect(width-163, 40, width/3 + 6, 70); //white border in flag
        stroke('White');
        line(width, 40, width-161, 40);
        line(width, 110, width-161, 110);
        pop();
        noStroke();
        fill('White');
        circle(width-125, 75, 53);
        stroke(0);
        push();
        starJan();
        pop();
    }

    function nuclear(x, y) { //nuclear symbol
        push();
        translate(x, y);
        let d = 80
        let d1 = 10
        stroke(0);
        strokeWeight(3);
        fill('yellow'); //draw circles
        circle(0, 0, d);
        fill('black');
        circle(0, 0, d1);

        let deg = 120;
        let dx = 5;
        let angle = 45;

        rotate(radians(angle));
        for (let i = 0; i < 3; i++) { //draw triangles 
            rotate(radians(deg));
            beginShape();
            fill('black');
            vertex(-7, -7);
            vertex(-30, -10);
            vertex(-10, -30);
            endShape(CLOSE);
        }

        angle = angle + dx;
        pop();

        push();
        rotate(radians(-20));
        image(imgJan, 135, 185, 100, 100); //santa hat
        pop();

    }

    function JanText(x, y) { //display text for Jan
        push();
        translate(x, y);
        textSize(23);
        fill(255);
        text("United Shaysh of America VS. North Korea", 0, 0);
        pop();
    }

//Global variables for Feb
var rip = 0//checks to see if SotU is ripped

function clickMonthFeb() {
	//Referencing the ripped speech at the State of the Union address
    if (keyCode === 50) {
        clearBkrd();
        frameRate(30);
        drawPaper();
		drawRip();
		mendPaper();
        backButton();
    }   
    
}

	//February helper functions
	function drawPaper() { //draw initial SotU
		push();
		background('grey');
		image(imgFeb, 0, 0);
		fill('white');
		rectMode(CENTER);
		rect(width/2+30, height/2, 200, 300);
		rect(width/2+15, height/2, 200, 300);
		rect(width/2, height/2, 200, 300);
		textStyle(ITALIC);
		textSize(22);
		fill('black');
		text("State of the Union", 160, 80);
		fill('white');
		text("Click and hold to rip!", width-205, 25);
		text("Nancy Pelosi Simulator", 10, 25);
		line(180, 110, 320, 110);
		for (let i = 0; i < 20; i++) {
			line(165, 120 + i*11, 335, 120 + i*11);
		}
		pop();
	}

	function drawRip() { //Rip SotU
		push();
		if (mouseIsPressed) {
			background('grey');
			image(imgFeb, 0, 0);
			textStyle(ITALIC);
		    textSize(22);
			fill('white');
			text("Release mouse to mend...", 10, 25);
			push();
			rotate(radians(-30));
			fill('white');
			rectMode(CORNER);
			rect(width/2-300, height/2-80, 100, 300);
			for (let i = 0; i < 20; i++) {
				line(-40, 190 + i*11, 40, 190 + i*11);
			}
			fill('black');
			text("State of t", -50, 160);
			rotate(radians(60));
			fill('white');
			rect(width/2+160, height/2-345, 100, 300);
			for (let j = 0; j < 20; j++) {
				line(width/2+175, height/2-280 + j*11, width/2+250, height/2-280 + j*11);
			}
			fill('black');
			text("he Union", width/2+162, height/2-300);
			pop();
			pop();
			rip = 1;
		}
	}

	function mendPaper() { //Tape SotU back together like a good American
		push();
		if (rip == 1 & !mouseIsPressed) {
			background('grey');
			image(imgFeb, 0, 0);
			fill('white');
			rectMode(CENTER);
			rect(width/2+30, height/2, 200, 300);
			rect(width/2+15, height/2, 200, 300);
			rect(width/2, height/2, 200, 300);
			textStyle(ITALIC);
			textSize(22);
			fill('black');
			text("State of the Union", 160, 80);
			fill('white');
			text("Click and hold to rip!", width-205, 25);
		    text("Nancy Pelosi Simulator", 10, 25);
			fill('black');
			line(180, 110, 320, 110);
			for (let i = 0; i < 20; i++) {
				line(165, 120 + i*11, 335, 120 + i*11);
			}
	        fill(255, 248, 220);
			rect(width/2-15, height/2, 30, 300);
			pop();
		}
	}
//Global variable for March
var viruses = [];

function clickMonthMar() {
	//Referencing the spread of COVID-19 in the U.S.
    if (keyCode === 51) {
        clearBkrd();
        backButton();
        frameRate(15);
        image(imgMar, 0, 0, 500, 400);

	    for (var i = 0; i < viruses.length; i++) {
	        var v = viruses[i];
	        v.stepFunction();
	        v.drawFunction();
	        if (v.diam > 450) {
	        	background(0);
	        	stroke(255, 0, 0);
	        	strokeWeight(4);
	        	push();
	        	textSize(48);
	        	translate(width/2, height/2)
	        	rotate(radians(90));
	        	text(":(", 0, 0);
	        	pop();
	        	stroke(0);
	        	strokeWeight(2);
	        	fill('white');
	        	text("Sad", width/2, height/2 + 100);
	        }
	    }
    }   
    
}

	//March Helper Functions
	function virusStep() {
    this.age++;
    this.x += this.dx;
    this.y += this.dy;
    if (this.x > width) { // bounce off right wall
        this.x = width - (this.x - width);
        this.dx = -this.dx;
        this.diam *= 1.25;
    } else if (this.x < 0) { // bounce off left wall
        this.x = -this.x;
        this.dx = -this.dx;
        this.diam *= 1.25;
    }
    if (this.y > height) { // bounce off bottom
        this.y = height - (this.y - height);
        this.dy = -this.dy;
        this.diam *= 1.25;
    } else if (this.y < 0) { // bounce off top
        this.y = -this.y;
        this.dy = -this.dy;
        this.diam *= 1.5;
    }
	}


	function virusDraw() {
		stroke('black');//body of virus
		strokeWeight(2);
		fill('red');
		push();
	    translate(this.x, this.y);
		circle(0, 0, this.diam);
		strokeWeight(3);//stems of virus
		var angle = 45;
		for (let i = 0; i < 8; i++) {
			rotate(radians(angle));
			beginShape();
	        vertex(this.diam/2 - 10, 0)
	        vertex(random(this.diam/2 + 4, this.diam/2 + 8), random(-2, 2));
	        endShape(CLOSE);
	        ellipse(random(this.diam/2 + 8, this.diam/2 + 6), random(1, 3), 11, 9);
	    }
	    pop();
	}


	// create a "Particle" object with position and velocity
	function makeVirus(vx, vy, vdx, vdy) {
	    v = {x: vx, y: vy,
	         dx: vdx, dy: vdy,
	         age: 0,
	         diam: 25,
	         stepFunction: virusStep,
	         drawFunction: virusDraw
	        }
	    return v;
	}	

// Global variables for April
var tigers = [];
var deg = 10
var joe = 1;

function clickMonthApr() {
	//Referencing the popularity of the Tiger King documentary on NETFLIX in March/April
    if (keyCode === 52) {
        clearBkrd();
        frameRate(12);
        displayHorizon();
   		updateAndDisplayTigers();
    	removeTigersThatHaveSlippedOutOfView();
    	addNewTigersWithSomeRandomProbability();
        backButton();
    }
       
}

	function updateAndDisplayTigers(){
	    // Update the cats' positions, and display them.
	    for (var i = 0; i < tigers.length; i++){
	        tigers[i].move();
	        tigers[i].display();
	    }
	}


	function removeTigersThatHaveSlippedOutOfView(){
	    var tigersToKeep = [];
	    for (var i = 0; i < tigers.length; i++){
	        if (tigers[i].x + tigers[i].breadth > 0) {
	            tigersToKeep.push(tigers[i]);
	        }
	    }
	    tigers = tigersToKeep; // remember the surviving tigers
	}


	function addNewTigersWithSomeRandomProbability() {
	    // With a very tiny probability, add a new cat to the end.
	    var newTigersLikelihood = 0.03; 
	    if (random(0,1) < newTigersLikelihood) {
	        tigers.push(makeTigers(width));
	    }
	}


	// method to update position of cat every frame
	function tigersMove() {
	    this.x += this.speed;
	}
	    

	// draw the cat and more cats
	function tigersDisplay() {
	    push();
	    translate(this.x, height - floor(random(30, 40))); 
	    image(aprImg, 0, -15, 80, 35);
	    pop();
	}


	function makeTigers(birthLocationX) {
	    var tgs = {x: birthLocationX,
	                breadth: 50,
	                speed: -1.0,
	                move: tigersMove,
	                display: tigersDisplay}
	    return tgs;
	}

	function displayHorizon(){
		image(aprImg2, 0, 0, width, height);
		push();
		translate(60, 80);
		imageMode(CENTER);
		rotate(radians(deg));
		for (let i = 0; i < joe; i++) {
			image(aprImg3, 0, 0, 80, 80);
		}
		pop();
		deg = deg + 10;
	}

function clickMonthMay() {
	//Referencing Kim Jong Un's questionable health and reappearance
    if (keyCode === 53) {
        clearBkrd();
        frameRate(60);
        drawBackdrop();
		leader();
		drawPodium();
        backButton(); 
    }  
    
}

	//May helper functions
	function leader() {
		push();
		var top = height/2;
	    var bottom = height;
	    var conY = constrain(mouseY, top, bottom);
		imageMode(CENTER);
		image(mayImg1, width/2, conY, 120, 180);
		pop();
	}

	function drawPodium() {
		push();
		imageMode(CENTER);
		image(mayImg2, 250, 400, 300, 250);
		pop();
	}

	function drawBackdrop() {
		push();
		imageMode(CENTER);
		image(mayImg3, width/2, height/2, 500, 400);
		textSize(20);
		fill('black');
		text("N.K. Leader Simulator", 10, 30);
		text("Moves with your mouse!", width-210, 30);
		pop();
	}

//Global variable June
var moveJun = 1;

function clickMonthJun() {
	//Referencing President Trump's removal of protesters from St. John's church in D.C.
    if (keyCode === 54) {
        clearBkrd();
        frameRate(30);
        drawChurch();
	    drawPres();
	    drawProtest();
	    fightBack();
        backButton();  
    } 
}

	function drawChurch() {
		push();
		imageMode(CENTER);
		image(imgJun1, width/2, height/2, 500, 400);
		textSize(20);
		fill('black');
		text("Click and hold mouse to fight back!", 10, 25);
		pop();
	}

	function drawPres() {
		push();
		var junX1 = width - 50;
		var conX1 = constrain(junX1 - moveJun, 230, width + 60);
		imageMode(CENTER);
		image(imgJun2, conX1 , height-50, 120, 130);
		pop();
	}

	function drawProtest() {
		push();
		var junX2 = 80;
		var conX2 = constrain(junX2 - moveJun, -100, 230);
		imageMode(CENTER);
		image(imgJun3, conX2, height-50, 200, 150);
		pop();
	}

	function fightBack() {
		push();
		moveJun ++;
		print(moveJun);

		if (mouseIsPressed) {
			moveJun -= 2;
		}

		moveJun = constrain(moveJun, -150, 230);
		pop();
	}

//Diana's Code

var julXPoints = [];
var julYPoints = [];
var julClr = [];

function clickMonthJul() {
//Remembering John Lewis
    if (keyCode === 55) {
    	clearBkrd();
    	frameRate(60);
        imgJul.resize(width, height);
        imgJul.loadPixels();
        var x = random(width); //randomly draw pixels for a portrait of John Lewis
	    var y = random(height);
	    var clr = imgJul.get(x, y);
    	stroke(clr);
		strokeWeight(5);
	   	noFill();
	   	point(x, y); 
	   	julXPoints.push(x); //push the coordinates into arrays so it doesn't look like the background keeps drawing over it
	   	julYPoints.push(y);
	   	julClr.push(clr);
	   	for (var i = 0; i < julXPoints.length; i++) {
	   		stroke(julClr[i]);
	   		point(julXPoints[i], julYPoints[i]);
	   	}
        backButton(); 
    }
      
}

function clickMonthAug() {
//SpaceX Launch
	strokeWeight(1);
	stroke(0);
    if (keyCode === 56) {
        clearBkrd();
        background(0);
        frameRate(30);
		for (var i = 0; i < 3; i++) {
			for(var j = 0; j < 4; j++){
				star(i*200 + 25, j*100);
			}	
		}

		for (var a = 0; a < 2; a++) {
			for (var b = 0; b < 4; b++) {
				star(a*200 + 125, b*100 + 50);
			}
		}
		spaceship(200, 150);
		backButton(); 
	    }
}
    //August Helper Functions
	function spaceship(x, y) {
		push();
		translate(x, y);
		rotate(radians(30));
		fill(255);
		ellipse(25, 0, 50, 100); //spaceship body
		rect(0, 0, 50, 150);
		stroke(255, 0, 0);
		strokeWeight(3);
		push();
		rotate(radians(-90));
		text("SpaceX", -120, 25);
		pop();
		stroke(0);
		strokeWeight(1);
		triangle(0, 75, 0, 150, -35, 150); //wings
		triangle(50, 75, 50, 150, 85, 150);
		push();
		translate(-35, 150);
		for (var i = 0; i < 3; i++) { //draw flames
			fill(255, 175, 0);
			triangle(i*40, 0, (i+1)*40, 0, (i*40 + random(15, 25)), random(95, 105));
		}
		pop();
		pop();
	}

	function star(x, y) {
		var sx = [0, 5.5, 16.5, 9.5, 10.5, 0, -10.5, -9.5, -16.5, -5.5];
		var sy = [0, 9.5, 12.5, 21, 32, 27.5, 32, 21, 12.5, 10.5];
		push();
		translate(x, y);
		fill(255, 255, 0);
	    var nPoints = sx.length;
	    beginShape();
	    for (var i = 0; i < nPoints; i++) {
	    	vertex(sx[i] + random(-1, 1), sy[i] + random(-1, 1));
	    }
	    endShape(CLOSE);
	    pop();
	}

//Global Variables for September
var trees = [];
var smoke = [];
var mountain = [];
var fire = [];
var noiseParam = 0; //controls mountain landscape
var noiseStep = 0.01;
var fNoiseParam = 0; //controls fire
var fNoiseStep = 0.05;

function clickMonthSep() {
//West Coast Wildfires
    if (keyCode === 57) {
        clearBkrd();
        text("Sep TEST", width/2, height/2);
        backButton();
        frameRate(10);
        background(100); //dark grey

	    updateAndDisplaySmoke();
	    removeSmokeThatHasSlippedOutOfView();
	    addNewSmokeWithSomeRandomProbability();

	    mountains();
	    makeFire();
	    fill(75);
	    rect(0, 335, width, 65); //ground

	    updateAndDisplayTrees();
	    removeTreesThatHaveSlippedOutOfView();
	    addNewTreesWithSomeRandomProbability();   
	}
}

//September Helper Functions
	function updateAndDisplayTrees(){
	    // Update the trees' positions
	    for (var i = 0; i < trees.length; i++){
	        trees[i].move();
	        trees[i].display();
	    }
	}


	function removeTreesThatHaveSlippedOutOfView(){
	    //remove these trees from the array
	    var treesToKeep = [];
	    for (var i = 0; i < trees.length; i++){
	        if (trees[i].x + trees[i].breadth > 0) {
	            treesToKeep.push(trees[i]);
	        }
	    }
	    trees = treesToKeep;
	}


	function addNewTreesWithSomeRandomProbability() {
	    // Add a new tree to the end of the array
	    var newTreeLikelihood = 0.05; 
	    if (random(0,1) < newTreeLikelihood) {
	        trees.push(makeTree(width));
	    }
	}

	function treeMove() {
	    this.x += this.speed;
	}
	    
	function treeDisplay() {
	    //draw the tree
	    var tHeight = 90; 
	    strokeWeight(5);
	    stroke(0); 
	    push();
	    translate(this.x, height - 40);
	    line(0, -tHeight, 0, 0);
	    line(0, -40, -22, -75);
	    line(0, -40, 22, -75);
	    line(0, -50, -15, -85);
	    line(0, -50, 15, -85);
	    line(0, -30, -30, -65);
	    line(0, -30, 30, -65);
	    stroke(200); 
	    pop();
	}


	function makeTree(birthLocationX) {
	    var tr = {x: birthLocationX,
	                breadth: 50,
	                speed: -3.5,
	                move: treeMove,
	                display: treeDisplay}
	    return tr;
	}

	//Smoke Clouds

	function updateAndDisplaySmoke(){
	    // Update the smoke positions
	    for (var i = 0; i < smoke.length; i++){
	        smoke[i].move();
	        smoke[i].display();
	    }
	}


	function removeSmokeThatHasSlippedOutOfView(){
	    // remove clouds that are no longer visible
	    var smokeToKeep = [];
	    for (var i = 0; i < smoke.length; i++){
	        if (smoke[i].x + smoke[i].breadth > 0) {
	            smokeToKeep.push(smoke[i]);
	        }
	    }
	    smoke = smokeToKeep;
	}


	function addNewSmokeWithSomeRandomProbability() {
	    // Add smoke clouds to the end of the arrayS
	    var newSmokeLikelihood = 0.02; 
	    if (random(0,1) < newSmokeLikelihood) {
	        smoke.push(makeSmoke(width));
	    }
	}

	function smokeMove() {
	    this.x += this.speed;
	}
	    

	// draw smoke
	function smokeDisplay() { 
	    fill(50); 
	    noStroke(); 
	    push();
	    translate(this.x, this.y);
	    ellipse(0, this.y, 90, 15);
	    ellipse(0, this.y+10, 100, 15);
	    ellipse(0, this.y-10, 80, 15);
	    pop();
	}


	function makeSmoke(birthLocationX) {
	    var smk = {x: birthLocationX,
	    	        y: random(0, height/2),
	                breadth: 50,
	                speed: -3.,
	                move: smokeMove,
	                display: smokeDisplay}
	    return smk;
	}


	function mountains() {
	    //use random noise to draw mountains
	    mountain.shift();
	    var n = noise(noiseParam);
	    var value = map(n, 0, 1, 0, height);
	    mountain.push(value);
	    noiseParam += noiseStep;
	    
	    
	    fill(0); //black - mountain shadows
	    beginShape();
	    vertex(0, height);
	    for (var i = 0; i <= 100; i++) {
	        vertex(i*5, mountain[i]);
	    }
	    vertex(width, height);
	    endShape(); 
	}

	function makeFire() {
	    //use random noise to draw mountains
	    fire.shift();
	    var n = noise(fNoiseParam);
	    var value = map(n, 0, 1, 0, height);
	    fire.push(value);
	    fNoiseParam += fNoiseStep;
	    
	    
	    fill(255, 0, 0); //red layer
	    beginShape();
	    vertex(0, height);
	    for (var i = 0; i <= 100; i++) {
	        vertex(i*5, fire[i]);
	    }
	    vertex(width, height);
	    endShape(); 

	    fill(255, 175, 0); //orange layer
	    beginShape();
	    vertex(0, height);
	    for (var j = 0; j <= 100; j++) {
	    	vertex(j*5, fire[j] + 50);
	    }
	    vertex(width, height);
	    endShape();

	    fill(255, 255, 0); //yellow layer
	    beginShape();
	    vertex(0, height);
	    for (var p = 0; p <= 100; p++) {
	    	vertex(p*5, fire[p] + 100);
	    }
	    vertex(width, height);
	    endShape();
     
}

//October Global Variables
var hurricane = [];
var xMove = [];
var imgOct;

function clickMonthOct() {
	//Busiest hurricane season on record
    if (keyCode === 48) {
        clearBkrd();
        frameRate(15);
        translate(width, 0);
	    image(imgOct, -width-50, -107, 650, 560);
		updateAndDisplayHurricane(); 
		removeHurricanesThatHaveSlippedOutOfView();
		addNewHurricanesWithSomeRandomProbability();
        backButton();
    }
}

	//October Helper Functions
		function updateAndDisplayHurricane(){
	    // Update the hurricanes' positions
	    for (var i = 0; i < hurricane.length; i++){
	        hurricane[i].move();
	        hurricane[i].display();
	    }
	}

	function removeHurricanesThatHaveSlippedOutOfView(){
	    //remove these hurricanes from the array
	    var hurricanesToKeep = [];
	    for (var i = 0; i < hurricane.length; i++){
	        if (hurricane[i].x > -550 || hurricane[i].y > -50) {
	            hurricanesToKeep.push(hurricane[i]);
	        }
	    }
	    hurricane = hurricanesToKeep;
	}

	function addNewHurricanesWithSomeRandomProbability() {
	    // Add a new hurricane to the end of the array
	    var newHurricaneLikelihood = 0.025;
	    var newHY = random(height/3, height);
	    this.xMove = random(10);
	    this.yMove = random(10);
	    if (random(0,1) < newHurricaneLikelihood) {
	        hurricane.push(makeHurricane(newHY));
	    }
	}

	function hurricaneMove() {
		this.x -= this.hxMove;
		this.y -= this.hyMove;
		this.spin += 10;
	}

	function hurricaneDisplay() {
		push();
		translate(this.x, this.y);
		rotate(radians(this.spin));
	    noStroke();
	    fill(255, 0, 0);
	    ellipse(0, 0, 30, 30);
	    fill(230);
	    ellipse(0, 0, 10, 10);
		push();
		scale(0.7);
		translate(-40, 5);
		stroke(255, 0, 0);
		strokeWeight(5);
		noFill();
		beginShape();
		for (var i = 2; i <= 4; i += 0.1) {
			var y1 = Math.pow(2.6, i);
	    	vertex(i*25, -y1);
		}
		endShape();
		pop();
	    
	    push();
	    scale(0.7);
	    stroke(255, 0, 0);
		strokeWeight(5);
		noFill();
	    translate(40, -5);
	    rotate(radians(180));
		beginShape();
		for (var i = 2; i <= 4; i += 0.1) {
			var y1 = Math.pow(2.6, i);
	    	vertex(i*25, -y1);
		}
		endShape();
		pop();
		pop();
	}

	function makeHurricane(birthLocationY) {
		var h = {x: 0, y: birthLocationY, hxMove: xMove, hyMove: 5, move: hurricaneMove, spin: 0, display: hurricaneDisplay}
	    return h;
	}

//November Global Variables
var theta = 0;
var txp = 0;
var typ = 0;
var thetavp = 0;
var txvp = 0;
var tyvp = 0;
//counters
var pCount = 0;
var vpCount = 0;

function clickMonthNov() {
//2020 US Presidential Election
    strokeWeight(1);
	stroke(0);
	textSize(14);

    if (keyCode === 189) {
        clearBkrd();
        frameRate(15);
        backButton();
        image(imgNov, -150, -60, 800, 650);
        stroke(255);
		president(150, 200);
		vicePresident(350, 200);
		fill(255);
		text("Who will be the first to 270?", 150, 20);
		text("Click the mouse on the left to give Alec Baldwin electoral votes", 75, 45)
		text("Click the mouse on the right to give Jim Carrey electoral votes", 75, 70);
		text(pCount, 150, 120);
		text(vpCount, 350, 120);
		debate();
	}

    	if (pCount >= 270) {
			background(255, 0,0);
			textSize(30);
			stroke(0);
			fill(0);
			text("I did it! It was RIGGED but I won!", 20, height/2 - 15);
			text("Very good for our Great Country", 25, height/2 + 15);
		}

		if (vpCount >= 270) {
			background(0, 0, 255);
			textSize(50);
			stroke(255);
			fill(255);
			text("Will you shut up man!", 5, height/2);
		}
	
}
    //November Helper Functions    
	function debate(){
		if (mouseIsPressed) {
			if (mouseX < width/2) { //move president
				theta = 15;
				txp = 150;
				typ = -100
				pCount = pCount + 5;				
			}

			if (mouseX >= width/2) { //move vice president
				thetavp = -15;
				txvp = -150;
				tyvp = 0;
				vpCount = vpCount + 5;
			}
		}
	} 

	function mouseReleased() {
		if (theta === 15) { //reset president
			theta = 0;
			txp = 0;
			typ = 0;					
		}

		if (thetavp === -15) { //reset vice president
			thetavp = 0;
			txvp = 0;
			tyvp = 0;				
		}
	}

	function president(x, y) {
		push();
		rotate(radians(theta));
		translate(x + txp, y + typ);
		noStroke();
		fill(255, 175, 0);
		push();
		rotate(radians(75)); //mouth
		ellipse(17, -12, 4, 15);
		rotate(radians(30));
		ellipse(15, -17, 4, 15);
		pop();
		fill(255, 175, 0); //head
		ellipse(0, 0, 40, 50);
		fill(255, 255, 0); //hair
		ellipse(3.5, -20, 45, 15);
		fill(255); //eyes
		ellipse(10, -2, 8, 8);
		fill(0);
		ellipse(10, -2, 4, 4);
		stroke(0);
		line(25, 17, 40, 17);
		line(25, 9, 40, 1);
		line(25, 25, 40, 33);
		noStroke();

		//suit
		fill(255); //shirt
		rect(-15, 23, 32, 50);
		fill(0, 0, 255); //suit jacket
		rect(-15, 23, 25, 50);
		fill(255, 0, 0); //tie
		rect(14, 23, 3, 30);
		fill(0); //shoes
		ellipse(3, 133, 35, 15);
		fill(0, 0, 255); //pants
		rect(-15, 73, 27, 60);
		push(); //arm
		rotate(radians(-40));
		fill(255, 175, 0);
		ellipse(15, 40, 15, 10);
		fill(0, 0, 255);
		rect(-35, 35, 50, 10);
		pop();
		pop();
	}

	function vicePresident(x, y) {
		push();
		rotate(radians(thetavp));
		translate(x + txvp, y + tyvp);
		noStroke();
		fill(250, 237, 203); //head
		ellipse(-2, 0, 40, 50);
		fill(255); //hair
		ellipse(0, -22, 35, 8);
		fill(255); //eyes
		ellipse(-10, -4, 8, 8);
		fill(0);
		ellipse(-10, -4, 4, 4);
		fill(255, 0, 0); //mouth
		ellipse(-12, 13, 8, 8);
		stroke(0);
		line(-25, 13, -40, 13);
		line(-25, 8, -40, 0);
		line(-25, 18, -40, 26);
		noStroke();

		//suit
		fill(255); //shirt
		rect(-15, 23, 25, 50);
		fill(0, 0, 255); //suit jacket
		rect(-8, 23, 18, 50);
		fill(255, 0, 0); //tie
		rect(-15, 23, 3, 30);
		fill(0); //shoes
		ellipse(-7, 133, 35, 15);
		fill(0, 0, 255); //pants
		rect(-15, 73, 25, 60);
		push(); //arm
		rotate(radians(40));
		fill(250, 237, 203);
		ellipse(-18, 45, 10, 10);
		fill(0, 0, 255);
		rect(-18, 40, 50, 10);
		pop();
		pop()
		}

//December global variables - firework coordinate arrays     
var xpos = 0;
var xcoord = [35, 25, 55, 200, 240, 400, 470, 440, 455, 230, 280, 415, 100, 280];
var ycoord = [25, 100, 350, 120, 150, 75, 45, 175, 300, 320, 365, 340, 215, 50];

function clickMonthDec() {
	//abstract clock to wait for the end of 2020
    if (keyCode === 187) {
        clearBkrd();
        backButton();
        frameRate(5);
    	background(0);
	    var sec = second();
	    var min = minute();
	    var hr = hour();
	    var d = day();
	    background(0);

	    //draw fireworks in the background
	    for (var i = 0; i < 14; i++) {
	        firework(xcoord[i], ycoord[i]);
	    }

	    push();
	    scale(0.5);
	    president(16*d, 40); //moves with day
	    pop();
	    decVirus(20*hr, 150); //hour
	    image(aprImg3, 8*min, 200, 80, 80); //minute
	    decHurricane(8*sec, 350); //second

	}
}

	//December helper functions
	function firework(x, y) { 
	    var r = random(255);
	    var g = random(255);
	    var b = random(255);
	    push();
	    translate(x, y);
	    stroke(r, g, b);
	    for (var i = 0; i < 12; i++) { //draw lines
	        push();
	        rotate(radians(i*30));
	        line(xpos, 0, xpos + 15, 0);
	        pop();
	    }

	    if (xpos <= 25) { //grow
	    xpos += 1;
	    }

	    else if (xpos > 25) { //reset
	        xpos = 0;
	    }
	    pop();
	}

	function decVirus(x, y) { //design taken from Shaun's virus object - I did not code
	        stroke('black');//body of virus
	        strokeWeight(2);
	        fill('red');
	        push();
	        translate(x, y);
	        circle(0, 0, 35);
	        strokeWeight(3);//stems of virus
	        var angle = 45;
	        for (let i = 0; i < 8; i++) {
	            rotate(radians(angle));
	            beginShape();
	            vertex(35/2 - 10, 0)
	            vertex(random(35/2 + 4, 35/2 + 8), random(-2, 2));
	            endShape(CLOSE);
	            ellipse(random(35/2 + 8, 35/2 + 6), random(1, 3), 11, 9);
	        }
	        pop();
	}

    function decHurricane(x, y) { //from October 
        push();
        translate(x, y);
        noStroke();
        fill(255, 0, 0);
        ellipse(0, 0, 30, 30);
        fill(230);
        ellipse(0, 0, 10, 10);

        //hurricane lines
        push(); 
        scale(0.7);
        translate(-40, 5);
        stroke(255, 0, 0);
        strokeWeight(5);
        noFill();
        beginShape();
        for (var i = 2; i <= 4; i += 0.1) {
            var y1 = Math.pow(2.6, i);
            vertex(i*25, -y1);
        }
        endShape();
        pop();
        push();
        scale(0.7);
        stroke(255, 0, 0);
        strokeWeight(5);
        noFill();
        translate(40, -5);
        rotate(radians(180));
        beginShape();
        for (var i = 2; i <= 4; i += 0.1) {
            var y1 = Math.pow(2.6, i);
            vertex(i*25, -y1);
        }
        endShape();
        pop();
        pop();
    }
      

Press any key in the row from “1” to “=” to select a month

Press “esc” to return to the main calendar and select another month

Shaun and I made this interactive monthly calendar recap of 2020 based on the memes from the beginning of the year that something big and strange was happening every month. It was not that hard to come up with events. I picked the events that I did partly based on what I had programming ideas for and partly in order to include some variety and show how many different things happened this year. We have many different types of events, from satire to more serious ones that we wanted to commemorate.
To use the program, press a key in line from “1” down to “=” to display a different month (“-” corresponds to November and “=” is December). Press “esc” to leave the month and return to the main calendar, or you can move between the months themselves. The counters in the March and November functions will reset if you leave the month by hitting “esc” so you can go back and run the simulation again, but they will not reset if you leave the month and return to it from another month (without hitting “esc” in between). I never have July reset because the portrait takes awhile to draw, so I didn’t think it needed to start over every time the month is replayed.
If I had more time, I would have liked to do more with the August function to make it interactive in some way, but I didn’t want to just link the spaceship to mouseX and mouseY, so I left it as is for now. Maybe eventually I could make it so that you can steer the spaceship through space or something.

Project-11

sketch
//Diana McLaughlin, dmclaugh@andrew.cmu.edu, Section A
//A generative landscape that shows trees, clouds, and mountains on a fall day

var trees = [];
var clouds = [];
var mountain = [];
var noiseParam = 0;
var noiseStep = 0.04;

function setup() {
    createCanvas(480, 380);
    
    //set up mountains
    for (var i = 0; i <= 96; i++) {
        var n = noise(noiseParam);
        var value = map(n, 0, 1, 0, height);
        mountain.push(value);
        noiseParam += noiseStep;
    }  
    
    //draw initial trees
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        trees[i] = makeTree(rx);
    }
    
    //draw initial clouds
    for (var i = 0; i < 10; i++){
        var cx = random(width);
        clouds[i] = makeCloud(cx);
    }
    frameRate(10);
}


function draw() {
    background(0, 200, 255); //sky blue

    updateAndDisplayClouds();
    removeCloudsThatHaveSlippedOutOfView();
    addNewCloudsWithSomeRandomProbability();

    mountains();
    fill(0, 120, 0);
    rect(0, 335, width, 65);

    updateAndDisplayTrees();
    removeTreesThatHaveSlippedOutOfView();
    addNewTreesWithSomeRandomProbability();   
}


function updateAndDisplayTrees(){
    // Update the trees' positions
    for (var i = 0; i < trees.length; i++){
        trees[i].move();
        trees[i].display();
    }
}


function removeTreesThatHaveSlippedOutOfView(){
    //remove these trees from the array
    var treesToKeep = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x + trees[i].breadth > 0) {
            treesToKeep.push(trees[i]);
        }
    }
    trees = treesToKeep;
}


function addNewTreesWithSomeRandomProbability() {
    // Add a new tree to the end of the array
    var newTreeLikelihood = 0.05; 
    if (random(0,1) < newTreeLikelihood) {
        trees.push(makeTree(width));
    }
}

function treeMove() {
    this.x += this.speed;
}
    
function treeDisplay() {
    //draw the tree
    var tHeight = 70; 
    fill(this.clr); 
    stroke(0); 
    push();
    translate(this.x, height - 40);
    triangle(0, -tHeight, -this.breadth/2, tHeight-90, this.breadth/2, tHeight-90);
    fill(255, 255, 150);
    rect(-5, tHeight-90, 10, 20);
    stroke(200); 
    pop();
}


function makeTree(birthLocationX) {
    var tr = {x: birthLocationX,
                clr: color(random(0, 255), random(0, 255), 0),
                breadth: 50,
                speed: -6.0,
                move: treeMove,
                display: treeDisplay}
    return tr;
}

//Clouds

function updateAndDisplayClouds(){
    // Update the clouds' positions
    for (var i = 0; i < clouds.length; i++){
        clouds[i].move();
        clouds[i].display();
    }
}


function removeCloudsThatHaveSlippedOutOfView(){
    // remove clouds that are no longer visible
    var cloudsToKeep = [];
    for (var i = 0; i < clouds.length; i++){
        if (clouds[i].x + clouds[i].breadth > 0) {
            cloudsToKeep.push(clouds[i]);
        }
    }
    clouds = cloudsToKeep;
}


function addNewCloudsWithSomeRandomProbability() {
    // Add clouds to the end of the arrayS
    var newCloudLikelihood = 0.02; 
    if (random(0,1) < newCloudLikelihood) {
        clouds.push(makeCloud(width));
    }
}

function cloudMove() {
    this.x += this.speed;
}
    

// draw the clouds
function cloudDisplay() {
    var cHeight = 250; 
    fill(255); 
    noStroke(); 
    push();
    translate(this.x, height - 40);
    ellipse(0, -cHeight, 30, 30);
    ellipse(15, -cHeight, 15, 15);
    ellipse(5, -cHeight+10, 50, 20);
    pop();
}


function makeCloud(birthLocationX) {
    var cld = {x: birthLocationX,
                breadth: 50,
                speed: -2.5,
                move: cloudMove,
                display: cloudDisplay}
    return cld;
}


function mountains() {
    //use random noise to draw mountains
    mountain.shift();
    var n = noise(noiseParam);
    var value = map(n, 0, 1, 0, height);
    mountain.push(value);
    noiseParam += noiseStep;
    
    
    fill(0, 150, 0); //land green
    beginShape(); //shape the terrain
    vertex(0, height);
    for (var i = 0; i <= 96; i++) {
        vertex(i*5, mountain[i]);
    }
    vertex(width, height);
    endShape(); 
}

This shows a landscape of a fall day. The trees have random colors as they pass like colorful leaves. I also set the speeds so that the foreground (trees) moves the fastest, the mountains move less than the trees, and the clouds move more slowly than the mountains.

LO-11

Caroline Record is a designer who uses computer art to create interactive experiences. She is currently the Computer Analyst and Programmer for Antimodular Research and a Creative Technologist for the Carnegie Museums of Pittsburgh. According to her Linkedin profile, she has held multiple positions in museums and as an educator. Record graduated from Carnegie Mellon University with a BFA in Electronic Time Based Art and Human Computer Interaction, then also completed an MS in Human Computer Interaction from CMU.
One of Record’s projects that I enjoy is “She.” The project is a sculpture of a printer that prints text on a long roll of paper. The text includes every sentence (614) in “Anna Karenina” by Leo Tolstoy (1878) that begin with the word “she.” The paper prints continuously through these sentences, resulting in a disorganized pile on the floor. Mounted on the wall behind the printer sculpture is a screen of a woman, who Record aims to show in “a haze of authorship.” The woman is singing and typing, which lines up with the printer’s rhythm. I found this project interesting because it combines audio and visual elements and incorporates classic literature to provide commentary on women at the corporate level.

She by Caroline Record (uploaded to YouTube in 2015)

Project-10

sketch
//Diana McLaughlin, dmclaugh@andrew.cmu.edu, Section A
//story project - a cat wanders around the house in search of dinner and runs into other characters - each more unlikely to live in the house than the last

var meow;
var bark;
var buzz;
var angry;
var aln;
var door;
var nom;

function preload() {
    meow = loadSound("http://127.0.0.1:8887/meow.wav");
    bark = loadSound("http://127.0.0.1:8887/bark.wav");
    buzz = loadSound("http://127.0.0.1:8887/fly.wav");
    angry = loadSound("http://127.0.0.1:8887/angry.wav");
    aln = loadSound("http://127.0.0.1:8887/alien.wav");
    door = loadSound("http://127.0.0.1:8887/door.wav");
    nom = loadSound("http://127.0.0.1:8887/nom.wav");
}


function setup() {
    createCanvas(400, 400);
    frameRate(1);
    createDiv("p5.dom.js library is loaded.");
    textSize(16);
    textAlign(CENTER);
    useSound();
}


function soundSetup() { // setup for audio generation
    meow.setVolume(1);
    bark.setVolume(1);
    buzz.setVolume(1);
    angry.setVolume(1);
    aln.setVolume(1);
    door.setVolume(1);
}


function draw() {
    // you can replace any of this with your own code:
    background(0, 200, 255);
    if (frameCount <= 8) {
        cat(width/2, height/2);
        thoughtBubble(300, 75);
        foodbowl(300, 75);
        stroke(0);
        text('Where is my dinner?', width/2, 325);
        text('I have never eaten in my life', width/2, 350);
        meow.play();
    }

    if (frameCount > 8 & frameCount <= 13) {
        cat(100, 200);
        dog(300, 200);
        text('Dog, have they fed you?', width/2, 325);
        text('Dinner is not for another hour, Cat', width/2, 350);
        if (frameCount <= 7) {
            meow.play();
        } else {
            bark.play();
        }

    }

    if (frameCount > 13 & frameCount <= 18) {
        cat(150, 300);
        fly (300, 300);
        text('Fly, have you eaten', width/2, 25);
        text('I just got here, I was on Mike`s head', width/2, 50);
        if (frameCount <= 12) {
            meow.play();
        } else {
            buzz.play();
        }
    }

    if (frameCount > 18 & frameCount <= 21) {
        text('The cat wandered so far away from the kitchen', width/2, height/2);
        text('that he found an alien', width /2, height/2 + 25);
    }

    if (frameCount > 21 & frameCount <= 26) {
        cat(300, 150);
        alien(100, 150);
        text('Alien I will starve if no one feeds me', width/2, 325);
        text('Go back to the kitchen, Cat.', width/2, 350);
        text('You still have 20 minutes until dinner', width/2, 370);
        if (frameCount <= 20) {
            angry.play();
        } else {
            aln.play();
        }
    }

    if (frameCount > 26 & frameCount <= 29) {
        text('Dejected and starving, cat made the long journey', width/2, height/2);
        text('from the closet back to the kitchen', width/2, height/2 + 25);
        angry.play();
    }

    if (frameCount > 29 & frameCount <= 32) {
        text('Suddenly, Cat heard a noise', width/2, height/2);
    }

    if (frameCount > 32 & frameCount <= 37) {
        surprisedcat(width/2, height/2);
        text('Could it be? Is the human home to save me?', width/2, 325);
        if (frameCount <= 32) {
            door.play();
        } else {
            meow.play();
        }
    }

    if (frameCount > 37) {
        cat(width/2, height/2);
        foodbowl(width/2, height/2 + 18);
        nom.play();
    }
}

function cat(x, y) {
    push();
    translate(x, y);
    noStroke();
    fill(200);
    ellipse(0, 0, 100, 100); //head
    triangle(-10, -49, -28, -70, -35, -35); //ears
    triangle(10, -49, 28, -70, 35, -35);
    fill(255, 0, 50);
    triangle(-13, -47, -26, -60, -30, -40);
    triangle(13, -47, 26, -60, 30, -40);
    fill(0, 255, 0);
    ellipse(-20, -20, 12, 12); //eyes
    ellipse(20, -20, 12, 12);
    fill(0); 
    ellipse(-20, -20, 7, 7);
    ellipse(20, -20, 7, 7);
    fill(255, 0, 50);
    stroke(0); //nose & mouth
    triangle(0, 5, -7, -3, 7, -3);
    line(0, 5, 0, 12);
    line(0, 12, -12, 20);
    line(0, 12, 12, 20);
    line(35, 5, 75, 5); //whiskers
    line(35, 5, 75, -5);
    line(35, 5, 75, 15);
    line(-35, 5, -75, 5);
    line(-35, 5, -75, -5);
    line(-35, 5, -75, 15);
    pop();
}

function dog(x, y) {
    push();
    translate(x, y);
    noStroke();
    fill(180, 100, 100);
    ellipse(0, 0, 110, 140); //head
    triangle(-11, -68, -29, -91, -36, -53); //ears
    triangle(11, -68, 29, -91, 36, -53);
    fill(0);
    ellipse(-20, -20, 13, 13); //eyes
    ellipse(20, -20, 13, 13);
    ellipse(0, 10, 25, 15); //nose
    stroke(0);
    strokeWeight(2);
    line(-20, 30, 20, 30); //mouth
    noStroke();
    fill(255, 0, 50);
    rect(10, 30, 10, 5);
    ellipse(15, 35, 10, 8);
    noStroke();
    fill(255, 0, 0); //collar
    rect(-45, 65, 90, 20);
    fill(255, 255, 0);
    ellipse(0, 90, 20, 20);
    pop();
}

function fly(x, y) {
    push();
    translate(x, y);
    fill(0);
    ellipse(0, 0, 45, 75); //body
    fill(55);
    push(); //wings
    rotate(radians(45));
    ellipse(-14, 15, 30, 45);
    pop();
    push();
    rotate(radians(315));
    ellipse(14, 15, 30, 45);
    pop();
    pop();
}

function alien(x, y) {
    push();
    translate(x, y);
    noStroke();
    fill(0, 255, 0);
    ellipse(0, 0, 95, 150); //head
    rect(-30, -100, 8, 70); //antenna
    rect(22, -100, 8, 70);
    fill(0);
    ellipse(-20, -20, 15, 25); //eyes
    ellipse(20, -20, 15, 25);
    stroke(0);
    strokeWeight(5);
    line(-30, 30, 30, 30); //mouth
    pop();
}

function foodbowl(x, y) {
    push();
    translate(x, y);
    ellipseMode(CENTER);
    for (var a = -17; a < 17; a += 4) { //food
        fill(180, 50, 80);
        ellipse(a, -11, 4, 4);
    }
    rectMode(CENTER);
    fill(255, 0, 0);
    rect(0, 0, 40, 20); //bowl
    pop();

}

function surprisedcat(x, y) {
    push();
    translate(x, y);
    noStroke();
    fill(200); //head
    ellipse(0, 0, 100, 100);
    triangle(-10, -49, -28, -70, -35, -35); //ears
    triangle(10, -49, 28, -70, 35, -35);
    fill(255, 0, 50);
    triangle(-13, -47, -26, -60, -30, -40);
    triangle(13, -47, 26, -60, 30, -40);
    fill(0, 255, 0); //eyes
    ellipse(-20, -20, 12, 12);
    ellipse(20, -20, 12, 12);
    fill(0); 
    ellipse(-20, -20, 7, 7);
    ellipse(20, -20, 7, 7);
    fill(255, 0, 50); //nose
    stroke(0);
    triangle(0, 5, -7, -3, 7, -3);
    fill(0);
    ellipse(0, 16, 10, 10); //mouth
    line(35, 5, 75, 5); //whiskers
    line(35, 5, 75, -5);
    line(35, 5, 75, 15);
    line(-35, 5, -75, 5);
    line(-35, 5, -75, -5);
    line(-35, 5, -75, 15);
    pop();
}

function thoughtBubble(x, y) {
    push();
    translate(x, y);
    fill(255);
    ellipse(-50, 50, 12, 12);
    ellipse(-36, 36, 12, 12);
    ellipse(-22, 22, 12, 12);
    ellipse(0, 0, 60, 45); //biggest bubble
    pop();
}

I was working on this while my cat was waiting for dinner (over an hour early) and it gave me this idea

LO-10

Badlands by Don Ritter is a sound art project that pairs sound with images of the Canadian Badlands. The image aspect of the project is controlled by live music; the speed at which the image moves is based on the tempo and pitch of the music being played. I was very interested in this project because the music controls the image, not the other way around. Most projects that I have looked at up to this point are based around the image first. In order to do this, Ritter uses a software called o8, which is based on Orpheus. The software is made to interpret and analyze the music that is being played in order to control the image. This also allows for artistic interpretation: Ritter (or anyone with the proper set up) could set the image to any music that he wanted and the project would be different than it would be with any other musical selection.

A link to a diagram that shows the technical requirements and setup, along with other information about Don Ritter’s Badlands project (2001)

Don Ritter’s website

Project-09

I found the stock photo on imgur and experimented with the two different shapes. At first, I didn’t have noFill() for the shapes, so the circle half looked funny because there were white circles all over the place. The diamond side looked better because everything was square. I ended up putting in the noFill(), so both halves look much more similar once enough of the shapes have drawn.

Image after the program has run for a few seconds

Image after the program runs for awhile

LO-09

This week, I looked at Shaun’s post about Ariel Waldman. It is crazy that she got a job with NASA right out of art school by cold calling them! I think that this background makes her perfect for the project that Shaun talks about in his blog: she seems to be all about making space exploration (and all of her other projects) more accessible to the average person. I wonder if this is because she did not have as much of a science background coming out of school, and therefore she is able to articulate concepts in ways that average people understand.
When I looked through her website, I saw that she also wrote a book titled “What’s It Like in Space?: Stories from Astronauts Who’ve Been There.” This is another project that, like Spaceprob.es that Shaun talked about in his post, gives everyone a look into what going to space is like. Right now, few people can actually go to space; significantly more people can read her book or visit her website.

Shaun’s original LO-08 post

Ariel Waldman’s website

Ariel Waldman’s book: What’s It Like in Space?: Stories from Astronauts Who’ve Been There (2016)

LO-08

Yuri Suzuki is a London based designer who works with sound. Before getting into design and technology, Suzuki was a musician and a DJ. When he started to get into design, he wanted to keep his musical background in his career, so he got into sound design. He is now a partner at Pentagram, which is the largest independently owned design studio in the world, and is also on faculty at the Royal College of Art in London.
Suzuki’s work makes people think about how they perceive sound in the world around them. One of my favorite projects that he introduced in his presentation was the Sound of Earth. The project is a large black globe with grooves that mimic the Earth’s topography. A needle plays the globe like a record and as it passes over each country, it plays sounds and music that Suzuki recorded on his phone while visiting the country.
Suzuki’s presentation is a brief overview of several of his projects. He introduces the project, then shows a video to demonstrate it. The video component was definitely an effective presentation method because he covered so many projects that there is no way that he can bring them to his presentations. Each overview was so brief that I don’t feel that I got an amazing idea of the process behind each piece through the presentation, but it certainly gives the viewer a great idea of the scope of his work.

Yuri Suzuki’s website can be accessed here: https://yurisuzuki.com/

Suzuki’s presentation at the Eyeo Festival (2015)

Project-07

sketch
//Diana McLaughlin, dmclaugh@andrew.cmu.edu, Section A
//a code that experiments with epicycloids and hypotrochoids

var nPoints = 500;
var theta = 0;

function setup() {
    createCanvas(480, 480);

}

function draw() {
	var g = map(mouseX, 0, 480, 0, 160);
	var b = map(mouseX, 0, 480, 75, 255);
    background(0, g, b); //shades of blue

    for(var y = 0; y <= 480; y += 100) { //draw the vertical yellow epicycloids
    	push();
    	translate(0, y);
    	Epicycloid2();
    	pop();
    	push();
    	translate(480, y);
    	Epicycloid2();
    	pop();
    }

    for (var x = 20; x <= 480; x += 100) {
    	    push(); //top row, yellow epicycloids
    	    translate(x, 0);
    	    Epicycloid2(); 
    	    pop();
            push(); //second row, pink hypotrochoids
            translate(x, 120);
            Hypotrochoid1();
            pop();
            push(); // middle row, purple epicycloids
    	    translate(x, 240);
    	    Epicycloid1();
    	    pop();
            push(); //fourth row, green hypotrochoids
            translate(x, 360);
            Hypotrochoid2();
            pop();
            push(); //bottom row, yellow epicycloids
            translate(x, 480);
            Epicycloid2();
            pop();

    }

    
}

function Epicycloid1() { //purple epicycloid
    var a = map(mouseX, 0, 480, 0, 70); //inner radius
    var b = map(mouseY, 0, 480, 0, 20); //outter radius

    strokeWeight(1);
    stroke(255, 128, 255); //light purple
    noFill();
    beginShape();
    for (var i = 0; i < nPoints; i++) {
        var theta = map(i, 0, 125, 0, TWO_PI);
        x = (a+b) * cos(theta) - b * cos(((a+b)/b) * theta);
        y = (a+b) * sin(theta) - b * sin(((a+b)/b) * theta);
        vertex(x, y);
    }
    endShape();
}

function Epicycloid2() { //yellow, epicycloid, used for the border
    var a = map(mouseX, 0, 480, 0, 30); //inner radius
    var b = map(mouseY, 0, 480, 0, 20); //outter radius

    strokeWeight(0.75);
    stroke(255, 255, 0); //yellow
    noFill();
    beginShape();
    for (var i=0; i<nPoints; i++) {
        var theta = map(i, 0, 45, 0, TWO_PI);
        x = (a+b) * cos(theta) - b * cos(((a+b)/b) * theta);
        y = (a+b) * sin(theta) - b * sin(((a+b)/b) * theta);
        vertex(x, y);
    }
    endShape();
}


function Hypotrochoid1() { //pink hypotrochoid
    var a = map(mouseX, 0, 480, 0, 125); //outter radius
    var b = map(mouseY, 0, 480, 0, 50); //inner radius
    var h = map(mouseX, 0, 480, 0, 60); // tracing distance from center of inner circle

    strokeWeight(1);
    stroke(255, 128, 200); //pink
    noFill();
    beginShape();
    for (var i=0; i<nPoints; i++) {
        var theta = map(i, 0, 120, 0, TWO_PI);
        x = (a-b) * cos(theta) + h * cos(((a-b)/b) * theta);
        y = (a-b) * sin(theta) - h * sin(((a-b)/b) * theta);
        vertex(x, y);
    }
    endShape();
}

function Hypotrochoid2() { //green hypotrochoid
    var a = map(mouseX, 0, 480, 0, 100); //outter radius
    var b = map(mouseY, 0, 480, 0, 40); //inner radius
    var h = map(mouseY, 0, 480, 0, 60); //tracing distance from center of inner circle

    strokeWeight(1);
    stroke(0, 255, 0);
    noFill();
    beginShape();
    for (var i=0; i<nPoints; i++) {
        var theta = map(i, 0, 120, 0, TWO_PI);
        x = (a-b) * cos(theta) + h * cos(((a-b)/b) * theta);
        y = (a-b) * sin(theta) - h * sin(((a-b)/b) * theta);
        vertex(x, y);
    }
    endShape();
}

I made this as a way to mess around with hypotrochoids and epicycloids. It took awhile to figure out the math and variables, but once I did, it was fun to play around with. The top pink row is my favorite.

LO-07

Ben Fry is a leading member of Fathom, a team that creates programs and applications to visualize, analyze, and understand data of all sorts. They have a wide range of projects, such as COiN, which helps people read and understand contracts. The program breaks the document down into sections, provides definitions, and allows the reader to switch back and forth easily throughout the “living” document.
I like this project because everybody will have to sign multiple contracts and agreements in their lifetimes and most people will have questions as they are going through them. These would traditionally be directed to a lawyer, which can get expensive. This program provides a more even playing field for the average person, without needing to add the expense of a lawyer.
The algorithms that generated the work most likely focus on data analysis and key words that break the document into sections. While the creators do not have much artistic day in data, they were able to use creativity to determine how the agreements are presented in the program. Overall, this program has the potential to serve any adult who has access to a computer, making contracts less daunting overall.

COiN, a project by Fathom, founded in 2010