Chelsea Fan & Katrina Hu – Final Project

Final copy

/* Chelsea Fan and Katrina Hu
Section 1B and Section 1C
chelseaf@andrew.cmu.edu and kfh@andrew.cmu.edu
Project-15
*/

//important variables
var killCount = 0;
var score = 0;
var yCoord = 0;
var snow = [];
var bear = [];
var c1;
var c2;

function setup() {
    createCanvas(600, 480);
    frameRate(60);
    //initial collection of bears
    for (i = 0; i < 1; i++) {
        var bearY = -40;
        bear[i] = makeBear(bearY);
    }
    //setting color of background
    c1 = color(106, 197, 252);
    c2 = color(126, 127, 207);
    //initial collection of snows
    for (i = 0; i < 60; i++) {
        var snowx = random(width);
        var snowy = random(0, height);
        snow[i] = makeSnow(snowx, snowy);
    }
}

function draw() {
    setGradient(c1, c2);
///////// BY CHELSEA
    //draw Sun
    noStroke();
    fill(255, 252, 227, 120);
    ellipse(80, 250, 85, 85);
    fill(255, 246, 179, 140);
    ellipse(80, 250, 70, 70);
    fill(255, 238, 112, 200);
    ellipse(80, 250, 50, 50);
    //draw background
    drawMountains2();
    drawMountains();
    //bears
    updateBear();
    removeBearFromView();
    addBear();
    drawKill();
    //more scenery things
    drawWater();
    drawIce();
    snows();
    //end of game
    endGame();
}

///////// BY KATRINA
function drawKill() {
    //printing score and number of bears killed
    fill(255);
    textSize(20);
    textAlign(RIGHT);
    noStroke();
    text("Kill Count = " + killCount, width - 70, 50);
    text("Score = " + score, width - 70, 75);
}

///////// BY CHELSEA
function endGame() {
    //end screen if five bears killed 
    //and restart game button
    if(killCount == 5) {
        textSize(50);
        fill(255);
        textAlign(CENTER);
        text("GAME OVER", width/2, height/2-100);
        for (var i = 0; i < bear.length; i++) {
            bear[i].speed = 0;
        }
        textSize(25);
        fill(255, 150);
        noStroke();
        rect(width/2 - 80, height/2 - 40, 160, 60);
        fill(50);
        text("RESTART", width/2, height/2);
    }
}

///////// BY KATRINA
function mouseClicked() {
    //if restart button clicked, reset game 
    if(killCount == 5) {
        if (mouseX > 220 & mouseX < 380 && mouseY > 200 && mouseY < 260) {
            bear = [];
            killCount = 0;
            score = 0;
            for (var i = 0; i < bear.length; i++) {
                bear[i].speed = 2;
            }
        }
    }
}

///////// BY KATRINA
function setGradient(c1, c2) {
    //gradient color sky background
    noFill();
    for (var y = 0; y < height; y++) {
        var inter = map(y, 0, height, 0, 1);
        var c = lerpColor(c1, c2, inter);
        stroke(c);
        line(0, y, width, y);
    }
}

///////// BY CHELSEA
function drawWater() {
    //water color and transparency
    fill(0, 107, 214, 100);
    noStroke();
    //water level 
    rect(0, height - (96 * killCount) - 20, width, height + 30)
}

///////// BY KATRINA
function drawIce() {
    fill(245, 68, 59);
    rect(mouseX + 8, height - (96 * killCount) - 100, 55, 30); //sign
    textSize(10);
    textFont('Georgia');
    fill(255);
    rect(mouseX + 8, height - (96 * killCount) - 100, 8, 75); //pole
    text('NORTH', mouseX + 55, height - (96 * killCount) - 90); //words
    text('POLE', mouseX + 50, height - (96 * killCount) - 75);
    fill(162, 232, 250)
    rect(mouseX, height - (96 * killCount) - 15, 100, 4); //ice
    fill(255);
    rect(mouseX, height - (96 * killCount) - 25, 100, 10); //ice
    fill(245, 68, 59);
    for(lines = 0; lines < 4; lines++) { //stripes
        rect(mouseX + 8, height - (96 * killCount) - lines * 20 - 33, 8, 7);
    }
    fill(255, 242, 145);
    ellipse(mouseX + 12, height - (96 * killCount) - 106, 15, 15) //top of pole
}

///////// BY CHELSEA
function drawSnow() {
    noStroke();
    fill(255, 255, 255, 170); ///snow color and transparency
    push();
    translate(this.x2, this.y2); //draw snow at x2, y2
    ellipse(10, 10, 5, 5); //snow shape
    pop();
}

///////// BY CHELSEA
function makeSnow(xlocation, ylocation) {
    //snow object
    var makeS = {x2: xlocation, 
                y2: ylocation, 
                snowx: random(0, width), 
                snowy: 0,
                speed: random(1, 2),
                move: moveSnow,
                draw: drawSnow}
    return makeS;
}

///////// BY CHELSEA
function moveSnow() {
    this.y2 += this.speed; //speed of snow moving
    if (this.y2 >= height - (96 * killCount) - 30) { //restart snow on top
        this.y2 -= height;
    }
}

///////// BY CHELSEA
function snows() {
    //move and draw all individual snows
    for(i = 0; i < snow.length; i++) {
        snow[i].move();
        snow[i].draw();
    }
}

///////// BY CHELSEA
function drawMountains(){
    noStroke();
    fill(192, 200, 207); //mountain color
    beginShape(); 
    for (i = 0; i < width; i++) {
        var mountainSpeed = .0005; //speed of mountains moving
        var mountainDetail = 0.009; //smoothness of mountains
        var t = (i * mountainDetail) + (millis() * mountainSpeed);
        //mountain y coord
        var y = map(noise(t), 0, 1.2, height/2, height);
        //keep drawing mountain
        vertex(i, y);
    }
    //height constriant of mountains
    vertex(width, height);
    //restart mountains at left side 
    vertex(0, height);
    endShape();
}

///////// BY CHELSEA
function drawMountains2(){
    noStroke();
    fill(245); //mountain color
    beginShape(); 
    for (i = 0; i < width; i++) {
        var mountainSpeed = .0003; //speed of mountains moving
        var mountainDetail = 0.007; //smoothness of mountains
        var t = (i * mountainDetail) + (millis() * mountainSpeed);
        //mountain y coord
        var y = map(noise(t), 0, 2, height/2, height);
        //keep drawing mountain
        vertex(i, y);
    }
    //height constriant of mountains
    vertex(width, height);
    //restart mountains at left side 
    vertex(0, height);
    endShape();
}

///////// BY KATRINA
function updateBear() {
    //move and draw all individual bears
    for (var i = 0; i < bear.length; i++) {
        bear[i].move();
        bear[i].display();
    }
}

///////// BY KATRINA
function removeBearFromView() {
    //if bear lands on ice, delete bear
    for(var i = 0; i < bear.length; i++) {
        if (bear[i].x > mouseX & bear[i].x < mouseX + 100 && (bear[i].y > height - (96 * killCount) - 50 && bear[i].y < height - (96 * killCount) - 40)) {
            bear.splice(i, 1);
            score += 1;
        }
        //if bear leaves screen, remove from array
        else if (bear[i].y > height + 40) {
            bear.splice(i, 1);
            killCount += 1;
        }
    }
}

///////// BY KATRINA
function makeBear(startY) {
    //bear object
    var myBear = {x: random(30, 570),
                y: startY,
                speed: 2,        
                move: bearMove,
                display: bearDisplay}
    return myBear;
}

///////// BY KATRINA
function bearMove() {
    //to move bear
    this.y += this.speed;
}

///////// BY KATRINA
function bearDisplay() {
    //drawing bear shape
    noStroke();
    fill(255);
    ellipse(this.x, this.y, 43, 60); //body
    ellipse(this.x + 14, this.y + 25, 12, 20); //right leg
    ellipse(this.x - 14, this.y + 25, 12, 20); //left leg
    ellipse(this.x, this.y - 30, 27, 32); //head
    ellipse(this.x + 9, this.y - 42, 8, 8); //right ear
    ellipse(this.x - 9, this.y - 42, 8, 8); //left ear
    fill(240);
    ellipse(this.x, this.y, 30, 36); //body
    fill(210);
    ellipse(this.x + 9, this.y - 42, 5, 5); //right inner ear
    ellipse(this.x - 9, this.y - 42, 5, 5); //left inner ear
    ellipse(this.x, this.y - 31, 9, 9); //snout
    fill(0);
    ellipse(this.x + 5, this.y - 37, 4, 4); //right eye
    ellipse(this.x - 5, this.y - 37, 4, 4); //left eye
    ellipse(this.x, this.y - 32, 6, 3); //nose
    fill(255);
    ellipse(this.x + 5.5, this.y - 35.5, 2, 2); //right inner eye
    ellipse(this.x - 5.5, this.y - 35.5, 2, 2); //left inner eye
    stroke(0);
    line(this.x, this.y - 32, this.x1, this.y - 29) //line from nose
}

///////// BY KATRINA
function addBear() {
    //add new bears to array with small probability
    var newBearProb = 0.005;
    if(random(0,1) < newBearProb) {
        bear.push(makeBear(-40));
    }
}

Instructions: Move the ice block with mouse to catch the falling bears. If you miss the bears, they will drown and the water level rises. If you miss 5 bears, the game ends. Press Restart to play again!

This was a fun project to make. Collaborating together was very helpful as we could learn from each other’s mistakes. However, it is difficult to code on two computers. We really enjoyed this experience and hope you enjoy the game!

Emma N-M — Final Project


My project is a spirograph application. You can move the two radius sliders, and vary the line length to change the design the math equation will create (the radii must be different values for the DRAW button to work). There are three different math equations you can use to create different designs (spirograph, epitrochoid, or another cool equation). The square in the top right hand corner allows you to set the pen color when you click on the box. This will open up a color gradient. Click anywhere and the box in the bottom righthand will show you a preview of the color you clicked on. Once you are happy with your pen color, hit “ENTER”. This will take you back to the set up screen. Hit the DRAW button to watch your design be created. When watching your drawing, you may hit the back arrow button or press “LEFT ARROW” key to go back to the set up screen. That’s it! Enjoy being mesmerized by art created with math.

finalProject-ENM

/* Emma Nicklas-Morris
enicklas
Section B
Final Project
*/ 

// radius1 46, radius2 31, LL 30 -- cool design

// point to draw the lines for the design
var x1;
var y1;
var x2 = x1;
var y2 = y1;

// used in sprigraph equations
var scaleN = 2.8;
var i = 0; // counter
var r1 = 10;
var r2 = 11;
var p = 2; // length of line from center

// used in other cool math equation
var l = p / r1;
var k = r1 / r2;

// epitrochoid equation variables
var a;
var b;

// drawing button
var drawing = false;
var justClicked = false; 
// back button
var backB = 30;
var backBX = 21;

var buttons = [];
var buttonText = [];
var equationText = [];
var equationCount = 1; // counts times the equation button is clicked
var e; // index to get the right equation displayed

var r1x = 25; // x position of radius 1 slider
var ry = 50; // y position for slider
var r2x = 175; // x position of radius 2 slider
var r1Min = 25; // min x position for radius 1
var r1Max = 125; // max x position for radius 1 
var r2Min = 175; // min x position for radius 2
var r2Max = 275; // max x position for radius 2
var radMin = 10; // user min for radii
var rad2Max = 70; // user radius 2 max
var rad1Max = 100; // user radius 1 max
var llMin = 2; // user line length min
var llMax = 65; // user line length max
var px = 315; // x position of line length (p)
var pMin = 315; // min x position of line length (p)
var pMax = 415; // max x position of line length (p)
var dragging = false;
var sliderCol = 170;

// which radius slider is clicked
var rad1 = false; 
var rad2 = false;
var lineL = false;
var rd = 12; // ball slider diameter
var r1Num = 10; // radius1 number displayed to user
var r2Num = 10; // radius2 number displayed to user
var lineNum = 5; // line length number displayed to user
var r12;        // radius1 - radius2
var diffRadii = false; // can't have the same radii

var backCol = 240; // background color
var userCol = 100; // intializes pen color
var gradSection = 84; // max width of each gradient section
var choosing = false;

var radius2; // object text for radius 2
var lineLen; // object text for line length

// location for elements on the screen
var diffRadX = 150;
var diffRadY = 100;
var eqX = 20;
var eqY = 30;
var rad2X = 190;
var llX = 320;
var colorX = 445;
var colorY = 25;
var colorMid = 165;
var colorPink = 147;
var eqW = 120;


function setup() {
	createCanvas(500, 400);
	background(backCol);
	frameRate(40);

}

function draw() {
	// stroke(cos(i/10)*(255/2), 0, sin(i/20)*(255/2), i);
	
	// screen mode: draws the spirograph
	if ((drawing) & (diffRadii)) {

		// back button on draw screen
		drawBackButton();

		// hide all setting buttons when in draw mode
		if (justClicked) {
            fill(backCol);
            rect(0, 0, width, height);
            justClicked = false; 
		}
		
        x1 = width / 2;
        y1 = height / 2;

        // spirograph
        if (e === 0) {
            spirograph();
            
        }

        // Epitrochoid
        else if (e === 1) {
            epitrochoid();
        }

        // other cool math equation
        else if (e === 2) {
            other();
        }

	}

	// screen mode: set the settings
	else {
		noStroke();
		// new screen -- hides drawing
		fill(backCol);
		rect(0, 0, width, height);

        // draws the buttons
		makeAndDrawButtons();
        makeTextForButtons();
        drawText();
        displayEquation();
        
        // which slider user is dragging
        checkDragging();

        // draw choose color button
        chooseColor();

        // draw radius sliders
        radiusSliders();

        // draws the example circles for the math
        exampleCircles();

        // line length (p)
        drawLineLength();

        // can't draw using the same radii
        checkRadii();

        // choosing pen color
        choosePenColor();

		// reset equation variables
		x1 = width / 2;
		y1 = height / 2;
		x2 = undefined;
		y2 = undefined;
		i = 0;   

	}

    i += 0.1;

}

function checkDragging() {
    if (dragging) {
        if (rad1) {
            r1x = mouseX;
        }
        else if (rad2) {
            r2x = mouseX;
        }

        else if (lineL) {
            px = mouseX;
        }
    }
}

function drawLineLength() {
    if (e === 0) { // spirograph color pallete
        stroke("#65cdca");
    }

    else if (e === 1) { // epitrochoid color pallete
        stroke("#c26571");
    }

    else if (e === 2) { // other cool equation color pallete
        stroke("#a0e3b9")
    }

    line(width/2 + r12, height/2, width/2 + r12 - lineNum, height/2);
    ellipse(width/2 + r12, height/2, 2, 2);
    ellipse(width/2 + r12 - lineNum, height/2, 3, 3);
}

function exampleCircles() {
    strokeWeight(2);
    noFill();
    // radius 1 circle
    stroke(0);
    ellipse(width/2, height/2, 2*r1Num, 2*r1Num);

    // radius 2 circle
    if (e === 0) { // spirograph
        stroke("#3f807e");
    }

    else if (e === 1) { // epitrochoid
        stroke("#82444c");
    }

    else if (e === 2) { // other cool equation
        stroke("#3d5747")
    }

    
    if ((e === 0) || (e === 2)) { // spirograph -- circles inside
        r12 = r1Num - r2Num;
    }

    else { // epitrochoid -- cirlces outside
        r12 = r1Num + r2Num;
    }

    ellipse(width/2 + r12, height/2, 2*r2Num, 2*r2Num);
    
}

function choosePenColor() {
    if (choosing) {
        noStroke();
        fill(255);
        rect(0 ,0, width, height);
        
        // the six color gradients
        gradient();

        // color box to see which color is clicked
        stroke(0);
        strokeWeight(2);
        fill(userCol);
        rect(445, 350, 30, 30);
    }
}

function checkRadii() {
    if (diffRadii == false) {
        noStroke();
        if (e === 0) { // spirograph
            fill("#65cdca");
        }

        else if (e === 1) { // epitrochoid
            fill("#c26571");
        }

        else if (e === 2) { // other cool equation
            fill("#a0e3b9");
        }
        
        textSize(18);
        text("Please choose two different radii", diffRadX, diffRadY);
    }
}

function spirograph() {
    // update spirograph variables according to user input
    r1 = r1Num;
    r2 = r2Num;
    p = lineNum;
    k = r2 / r1;

    x1 += scaleN*(r1 - r2)*cos(k*i) + p * cos((1-k)*i);
    y1 += scaleN*(r1-r2)*sin(k*i) - p * sin((1-k)*i);
    
    
    strokeWeight(2);
    stroke(userCol);
    // draw small portion of design
    line(x2, y2, x1, y1);
    noStroke();

    x2 = x1;
    y2 = y1;
}

function epitrochoid() {
    r1 = r1Num;
    r2 = r2Num;
    p = lineNum;
    a = r1 + r2;
    b = a / r2;
    scaleN = .9;

    x1 += scaleN*a*cos(i) - p * cos(b*i);
    y1 += scaleN*a*sin(i) + p * sin(b*i);

    stroke(userCol);
    strokeWeight(2);
    line(x2, y2, x1, y1); // draw small portion of design
    noStroke();
    x2 = x1;
    y2 = y1;
}

function other() {
    // update spirograph variables according to user input
    r1 = r1Num;
    r2 = r2Num;
    p = lineNum;
    l = p / r1;
    k = r2 / r1;
    scaleN = 2;

    x1 += scaleN*r1*((1-k)*Math.cos(i) + l*k*cos(i*((1-k)/k)));
    y1 += scaleN*r1*((1-k)*Math.sin(i) + l*k*sin(i*((1-k)/k)));
    
    stroke(userCol);
    strokeWeight(2);
    line(x2, y2, x1, y1); // draw small portion of design
    noStroke();
    x2 = x1;
    y2 = y1;
}

function makeAndDrawButtons() {
    // make the buttons
        var drawButton = makeButton(7/9 * width, 6/7 * height, 4 * eqX, eqY, "rect");
        drawButton.color(0);
        buttons.push(drawButton);

        var equationB = makeButton(eqX, 7/8 * height, diffRadX, eqY - 5, "rect");
        equationB.color(0);
        buttons.push(equationB);

        // draw all the buttons
        for (var b = 0; b < buttons.length; b++) {
            buttons[b].draw();  
        }
}

function makeTextForButtons() {
    // make text for buttons
        var textOnButton = makeText("DRAW", 7/9 * width + 9, height - eqY - 5, eqX);
        textOnButton.color(240);
        buttonText.push(textOnButton);

        var spiro = makeText("SPIROGRAPH", eqX * 2, height - eqY - 1, 16);
        spiro.color("#65cdca");
        equationText.push(spiro);

        var epi = makeText("EPITROCHOID", eqX * 2, height - eqY - 1, 16);
        epi.color("#c26571");
        equationText.push(epi);

        var other = makeText("COOL EQUATION 3", eqX + 6, height - eqY - 1, 15);
        other.color("#a0e3b9");
        equationText.push(other);

        var radius1 = makeText("Radius 1", eqX * 2, eqY, 18);
        radius1.color(0);
        buttonText.push(radius1);

        radius2 = makeText("Radius 2", rad2X, eqY, 18);
        radius2.color("#3f807e");
        buttonText.push(radius2);

        lineLen = makeText("Line Length", llX, eqY, 18);
        lineLen.color("#65cdca");
        buttonText.push(lineLen);
        
}

function drawText() {
    textAlign(LEFT);

    // change color pallete based on math equation
    
    if (e === 1) { // purple-pink: epitrochoid
        lineLen.color("#c26571");
        radius2.color("#753d45")
    }

    else if (e === 2) {
        lineLen.color("#a0e3b9");
        radius2.color("#3d5747");
    }

    // draw the button's text
    for (var t = 0; t < buttonText.length; t++) {
        buttonText[t].draw();
    }
}

function radiusSliders() {
    ellipseMode(CENTER);
    stroke(sliderCol);
    strokeWeight(3);
    // radius 1
    line(r1Min, ry, r1Max, ry);
    noStroke();
    fill(0);
    r1x = constrain(r1x, r1Min, r1Max);
    ellipse(r1x, ry, rd, rd);
    textAlign(CENTER);
    r1Num = floor(map(r1x, r1Min, r1Max, radMin, rad1Max));
    text(str(r1Num), r1x, ry + 2 * rd);

    // radius 2
    stroke(sliderCol);
    strokeWeight(3);
    line(r2Min, ry, r2Max, ry);
    noStroke();
    fill(0);
    r2x = constrain(r2x, r2Min, r2Max);
    ellipse(r2x, ry, rd, rd);
    r2Num = floor(map(r2x, r2Min, r2Max, radMin, rad2Max));
    text(str(r2Num), r2x, ry + 2 * rd);

    // line length
    stroke(sliderCol);
    strokeWeight(3);
    line(pMin, ry, pMax, ry);
    noStroke();
    fill(0);
    px = constrain(px, pMin, pMax);
    ellipse(px, ry, rd, rd);
    lineNum = floor(map(px, pMin, pMax, llMin, llMax));
    text(str(lineNum), px, ry + 2 * rd);

    // radii can't be same size
    if (r1Num === r2Num) {
        diffRadii = false;
    }
    
    else {
        diffRadii = true;
    }
}


// button for the user to chose their pen color
function chooseColor() {
    stroke(0);
    strokeWeight(2);
    fill(userCol);
    rect(colorX, colorY, eqY, eqY);
}

function gradient() {
    //gradient red to orange
    for (var r = 0; r < gradSection; r += 2) {
        var startR = color(255, 0, 0); // red
        var endO = color(255, colorMid, 0); // orange
        for (var c = 0; c < height; c += 2) {
            var interCol1 = lerpColor(startR, endO, r/(width/6));
            var white = color(255);
            var interLight1 = lerpColor(interCol1, white, c/height);
            fill(interLight1);
            rect(r, c, 2, 2);
        }
    }

    // gradient orange to yellow
    for (var r = 0; r < gradSection; r += 2) {
        var startO = color(255, colorMid, 0); // orange
        var endY = color(255, 255, 0); // yellow
        for (var c = 0; c < height; c += 2) {
            var interCol2 = lerpColor(startO, endY, r/(width/6));
            var interLight2 = lerpColor(interCol2, white, c/height);
            fill(interLight2);
            rect(r + gradSection, c, 2, 2);                
        }
    }

    // gradient yellow to green
    for (var r = 0; r < gradSection; r += 2) {
        var startY = color(255, 255, 0); // yellow
        var endG = color(0, 255, 0); // green
        for (var c = 0; c < height; c += 2) {
            var interCol3 = lerpColor(startY, endG, r/(width/6));
            var interLight3 = lerpColor(interCol3, white, c/height);
            fill(interLight3);
            rect(r + 2 * gradSection, c, 2, 2);               
        }
    }

    // gradient green to blue
    for (var r = 0; r < gradSection; r += 2) {
        var startG = color(0, 255, 0); // green
        var endB = color(0, 0, 255); // blue
        for (var c = 0; c < height; c += 2) {
            var interCol4 = lerpColor(startG, endB, r/(width/6));
            var interLight4 = lerpColor(interCol4, white, c/height);
            fill(interLight4);
            rect(r + 3 * gradSection, c, 2, 2);               
        }
    }

    // gradient blue to purple
    for (var r = 0; r < gradSection; r += 2) {
        var startB = color(0, 0, 255); // blue
        var endPp = color(colorMid, 0, colorMid); // purple
        for (var c = 0; c < height; c += 2) {
            var interCol5 = lerpColor(startB, endPp, r/(width/6));
            var interLight5 = lerpColor(interCol5, white, c/height);
            fill(interLight5);
            rect(r + 4 * gradSection, c, 2, 2);               
        }
    }

    // gradient purple to pink
    for (var r = 0; r < gradSection; r += 2) {
        var startPp = color(colorMid, 0, colorMid); // purple
        var endPk = color(255, eqX, colorPink); // pink
        for (var c = 0; c < height; c += 2) {
            var interCol6 = lerpColor(startPp, endPk, r/(width/6));
            var interLight6 = lerpColor(interCol6, white, c/height);
            fill(interLight6);
            rect(r + 5 * gradSection, c, 2, 2);               
        }
    }
}

function displayEquation() {
    // switch between the 2 equations

        if (equationCount % 3 === 1) {
            e = 0; // spirograph
        }

        else if (equationCount % 3 === 2) {
            e = 1; // Epitrochoid
        }

        else if (equationCount % 3 === 0) {
            e = 2;
        }

        // draw the equation name
        eText = equationText[e];
        fill(eText.tColor);
        textSize(eText.size);
        text(eText.t, eText.x, eText.y);
}

// back button to setting screen
function drawBackButton() {
	var backButton = makeButton(backB, backB, backB, backB, "ellipse");
		backButton.color(0);
        noStroke();
		backButton.draw();
		stroke(255);
		strokeWeight(2);
        // arrow
		line(backBX, backB, backB, backB + 8);
		line(backBX, backB, backB, backBX + 1);
		line(backBX, backB, backB + 9, backB);
}

// Object: Creates Buttons
function makeButton(bx, by, bw, bh, bShape) {
	var button = {x: bx, y: by, bColor: color(0),
				  shape: bShape, w: bw, h: bh,
				  draw: displayButton, color: setbColor}
	return button
}

// draws the buttons
function displayButton() {
	fill(this.bColor);
	if (this.shape == "rect") {
		rect(this.x, this.y, this.w, this.h);
	}
	else if (this.shape === "ellipse") {
		ellipse(this.x, this.y, this.w, this.h);
	}
}

// sets the button color
function setbColor(c) {
	this.bColor = color(c);
}

// Object: Creates text
function makeText(input, tx, ty, tSize) {
	var textForButton = {x: tx, y: ty, size: tSize, tColor: color(backCol),
						 t: input, draw: displayText, color: setTColor}
	return textForButton;
}

// draw the text
function displayText() {
	fill(this.tColor);
	textSize(this.size);
	text(this.t, this.x, this.y);
}

// set the text color
function setTColor(c) {
	this.tColor = color(c);
}

function mousePressed() {

	// click draw button to go to draw mode
	if ((mouseX > 7/9 * width) & (mouseX < 7/9 * width + 80) 
		&& (mouseY > 6/7 * height) && (mouseY < 6/7 * height + 30)
		&& (drawing == false) && (diffRadii)) {
		drawing = ! drawing;
		justClicked = true;
	}

    // back button -- send to settings screen
	else if (dist(mouseX, mouseY, backB, backB) <= backB / 2) {
		drawing = false;
	}

    // 3 math equations -- button to rotate the math equations
    else if ((mouseX > eqX) & (mouseX < eqX + eqW) 
        && (mouseY > 7/8 * height) && (mouseY < 7/8 * height + eqY - 5)
        && (drawing == false)) {
        equationCount += 1;
    }

    // drag radius 1 slider
    if (dist(r1x, ry, mouseX, mouseY) < rd / 2) {
        dragging = true;
        rad1 = true;
        justClicked = false;
        drawing = false;

    }

    // drag radius 2 slider
    else if (dist(r2x, ry, mouseX, mouseY) < rd / 2) {
        dragging = true;
        rad2 = true;
        justClicked = false;
        drawing = false;
    }

    // drag line length slider
    else if (dist(px, ry, mouseX, mouseY) < rd / 2) {
        print("t");
        dragging = true;
        lineL = true;
        justClicked = false;
        drawing = false;

    }

    // click inside color box
    if ((mouseX <= colorX + eqY) & (mouseX >= colorX)
        && (mouseY <= colorY + eqY) && (mouseY >= colorY) 
        && drawing === false) {
        choosing = true;
    }

    // set pen color to user's click
    if (choosing) {
        userCol = color(get(mouseX, mouseY));
    }
}

function mouseReleased() {
    dragging = false;
    rad1 = false;
    rad2 = false;
    lineL = false;
}

function keyPressed() {
    // use left arrow key to go back to the settings screen
    if ((drawing) & (keyCode === LEFT_ARROW)) {
        drawing = false;
    }

    // set pen color by hitting enter key
    if ((choosing) & (keyCode === ENTER)) {
        choosing = false;
    }
}

Siwei Xie – Final Project

sketch

//Siwei Xie
//Section B
//sxie1@andrew.cmu.edu
//Final Project

var size = 10;//original size of brush stroke

function setup() {
    createCanvas(480, 480);
    background("white");
    frameRate(500);//speed of drawing balls
}

function draw() {
    //fill unwanted borders with purple rectangels
	noStroke();
	fill(194, 192, 216);
	rect(0, 0, 480, 70);
    rect(0, 0, 150, 480);
    rect(450, 0, 30, 480);
    rect(0, 450, 480, 30);

    //titles & functions of drawing pad
	textStyle(NORMAL);
    textStyle(BOLD);
    textSize(27);
    fill("white");
    text('My Drawing Pad', 200, 50);

    textSize(15);
    fill(101, 67, 89);
    text('1. Drag mouse', 9, 115);
    text('to draw', 25, 133);
    text('2. Click buttons', 15, 220);
    text('to add patterns', 20, 235); 

    //notes for buttons
    textSize(12);
    fill("black");
    textStyle(ITALIC);
    text('Press B for big brush', 15, 153);
    text('Press S for small brush', 15, 168);

    //buttons for BACKGROUND 
    fill(185, 88, 84);//maroon square
    square(20, 250, 20); 

    fill("gray");//gray square
    square(60, 250, 20);

    fill("yellow");//yellow square
    square(100, 250, 20);

    //button for ERASE
    fill("white");
    rect(40, 360, 60, 40);
    fill("black");
    text('ERASE', 50, 385);
    
    //draw by using BRUSH
    if (mouseIsPressed) {
        fill(random(255), random(255), random(255));
        ellipse(mouseX, mouseY, size);
    }
} 

function keyPressed(){
    if (key === "B" || key === "b") {
        size += 10;//increase width of stroke
    }

    if (key === "S" || key === "s") {
        size -= 10;//decrease width of stroke
    }
}

function mouseClicked(){
    //PATTERN 1: use nested Loop to create shapes
    if(mouseX > 20 & mouseX < 40 && 
        mouseY > 250 && mouseY < 270){
    for (var j = 0; j < 12; j++) {
        for (var i = 0; i < 8; i++) {

        //maroon circles
        noStroke();
        fill(185, 88, 84);
        circle(i * 40 + 160, j * 30 + 95, 20);
        
        //white verticle lines
        fill("white");
        rect(i * 40 + 155, 80, 3, 370);
        }
    }
    noLoop();
    }

    //PATTERN 2: 
    if(mouseX > 60 & mouseX < 80 && 
        mouseY > 250 && mouseY < 270){
        fill("white");
        rect(150, 70, 300, 380);
        for (var y = 0; y < 360; y += 45) {
            for (var x = 0; x < 270; x += 45) {
                fill(182, 182, 182);
                circle(x + 180, y + 105, 45);
        }
    }
    noLoop();
    }

    //PATTERN 3: 
    if(mouseX > 100 & mouseX < 120 && 
        mouseY > 250 && mouseY < 270){
        for (var a = 0; a < 280; a = a + 1) {
        strokeWeight(20);
        stroke("yellow");
        //curve's starting point, height - curving extent * direction
        point(a + 160, 250 - 100 * sin(radians(a)));
        stroke(253, 241, 161);
        point(a + 160, 250 - 100 * cos(radians(a)));
        }
    noLoop();
    }

    //ERASE:
    if(mouseX > 40 & mouseX < 100 && 
        mouseY > 360 && mouseY < 400){
        noStroke();
        fill("white");
        rect(150, 70, 300, 380);
    }
}

In my final project, I created an “Interactive drawing pad.” Firstly, users can drag mouse on the white drawing pad to draw colorful stroke. They can change width of stroke by pressing S or B. Secondly, users can click on the 3 buttons on the left to select different patterns to fill the pad. Finally, they can use ERASE function to erase previously drawn strokes or patterns.

Ghalya Alsanea – LO – 12

Project 1: Turning biometric data into art by The Mill+

The Lush Spa Experiment was designed to capture biometric data. This data drove a series of unique and meditative visualisations, which mirror the multisensory experiences of a Lush Spa treatment.

The Mill+ joined forces with Lush to create a 2-minute film created via biometric data visualization – the aim being to visualize the physical response someone has to a Lush spa treatment. Essentially, turning biometric data into art.

The film is an artistic rendition of the body’s response to the spa treatment.

Mill+ Creative Director Carl Addy comments, “The data captured was fascinating. It shows a clear correlation between the treatment and the subject’s biometric response. You can actually see the moments when a sound or touch elicited a shift in brain wave which then triggers a reaction in breath and heart rate.”

Find more here(credits) & here(behind the scenes).

PROJECT 2: Visualization Techniques to Calm Your Anxious Mind by Barbara Davidson

This post shows 7 visualization techniques to help ease your anxiety. For my final project I am looking at how visual queues can trigger emotional calming responses, and I was using this project as a study point. Here are some examples:

The stop sign technique is best used when you have an unwanted thought.
This technique is best used when you feel overwhelmed by your chattering mind .

I love the how coherent and consistent the graphics are. Something that I wouldn’t necessary do is put people in the visualization, unless they’re vague enough figures, because I worry when something is as personal as your mind, you wouldn’t want someone to feel like they can’t relate to the visualization because “it doesn’t look like them”.

Read more here.

Concolusions..

When comparing the two, I admire both the visual coherency that exists within each project. The first one is interesting because it is a visualization the takes inputs and does not necessarily have a specific output in mind. The second one is the opposite in the sense that it has a highly specific output it is trying to achieve through the visualization. For my final project, I want to find a way to do both and play with the two balances based on what’s needed.

Ghalya Alsanea – Project – 12 – Proposal

I want to create a smart watch interface for someone with anxiety and panic disorder. I plan on using real-time biometric data from sensors and using the data to trigger and display things using p5.js. I have done projects before the use p5 serial communication, but my plan b is that is it does not work, then I will simply use button interactions in p5.js to trigger the different modes.

The watch has two modes: Normal Mode & Panic Mode.

Normal Mode includes a watch interface that displays the time and date, in addition to the sensor data in an artistic, data-visualization way (I am thinking something similar to a mood visualizer type of thing). The panic mode can be triggered through two ways: a panic button the user presses or sensor data that indicates the user is having a panic attack. In Panic Mode, the canvas cycles through the following anxiety relieving techniques:

  1. Deep Breathing Exercise: using calming graphics to help guide the user through a deep breathing exercise. I will use online resources to figure out how the breathing exercise need to be in order to work, like WebMed’s Techiques for deep breathing.
  2. Body Scan: using the body scan technique found here.
  3. Distraction/Game Technique: using a jigsaw puzzle or some sort of mind occupying game that reduces stress but still allow you to channel your overactive brain somewhere.
  4. 5 Senses Technique: using the 5 senses to ground you, as shown below:
This is a type of grounding technique to help bring you back to reality during a panic attack.

If all of the following techniques do not work, then this triggers a “call emergency contact” state, which calls someone you designated as a person to reach out to. For example, “calling your mom…”

The biometric sensors I am thinking of using are: a heart rate (PPG) sensor, a GSR sensor, and a respiratory rate sensor. The last one, I might not need, I am waiting to confirm with a specialist…

The photoplethysmography (PPG) circuit ascertains the user’s heart rate.
The galvanic skin response (GSR) circuit ascertains the user’s skin conductance level – a measurement loosely coupled with perspiration indicative of stressful conditions (in other words, the more stressed you are, the more you sweat).

Julia Nishizaki – Project 12 – Proposal

For my final project, I want to create an instrument of sorts that is based on the sounds around us, both sounds of nature as well as sounds related to machinery, technology, or man-made systems. I was thinking about Greta Thunberg’s speech at the French Parliament in July, and I realized that I’m really not familiar with the IPCC’s reports or the fact that in just 11 years we’ll reach some tipping points that we likely won’t be able to recover from. Through this project, I want to help visualize and create a more concrete image of what the future could look and sound like if we don’t change, in terms of animal and plant life, water levels, weather, and technology. Similar to patatap.com, I want my instrument to have different sounds and visuals for each letter, so that as you type and your words appear on the screen, the landscape starts to scroll past, and forms like plants, animals, buildings, and cars start to populate it. However, when you press a key such as shift or the space bar, the landscape changes to a future where we didn’t actively try to combat climate change, and all the images and sounds your words create in this possible future reflect that.

Sketches and notes for final project proposal

Julia Nishizaki – Looking Outwards – 12

I am taking my second late day for this looking outwards post. Because I’m considering visualizing type as a part of my project, the two works I chose to look at explore type, one through sound, and the other through visuals.

A demonstration of typatone.com, an online instrument

The first work is typatone.com, by Lullatone and Jono Brandel, the same individuals who created patatap.com. I really enjoyed the visuals of patatap.com, but I like typatone’s direct connection between the user’s thoughts and what they see. It gives the sounds more meaning, and makes the interaction more personal.

“A Flowering Theory,” a visual depiction of the grammar structure of Darwin’s last lines in “On the Origin of Species”

The other work I decided to look at is called “A Flowering Theory,” by Stefanie Posavec and Abbie Stephens, and commissioned by Protein as a part of “Channel 4 Random Acts.” I was intrigued by this work, because rather than associate a sound or a visual with a single letter, Posavec analyzed the text’s grammatical structure, and the Stephens used that data to construct the growing plants and forms. I am interested in combining typatone.com’s more experimental approach and interactions, with visuals of flowers or smog that grow or change, like Posavec and Stephen’s interpretations.

Crystal-Xue-Project-12-Proposal

For my final proposal, I want to create a sound interactive project. There will be sound visualization for the main piece and mouse interactive parts that can control the pitch/volume etc. I will also make the changes to be perceivable in the visualization part. The geometry is not fully designed yet. I’ll have to experiment with the sound itself to decide the best way to deliver my project (possibly use the z-coordinate)

final project proposal

Crystal Xue-LookingOutwards-12

For my final project, I want to do sound visualization. And here are two projects that I found particularly interesting.

This first project is called WAVES is created by students from OPENLIGHT: the creative lab of Intelligent Lighting Institute of the TU Eindhoven. Using a “sound camera”, a device with 1024 microphones which can very precisely locate a sound in space, students place it in an industrial place and visualized waves. People can interact with the device by making sounds, whistles, stomping their feet etc.

The next project is VOICE ARRAY. by Rafael Lozano-Hemmer. The LED light blinking gives a visual representation of the recorded sound

Rafael Lozano-Hemmer, “Voice Array, Subsculpture 13”, 2011. “Recorders”, Museum of Contemporary Art, Sydney, 2011. Photo by: Antimodular Research
Rafael Lozano-Hemmer, “Voice Array, Subsculpture 13”, 2011. “Recorders”, Museum of Contemporary Art, Sydney, 2011. Photo by: Antimodular Research

Both of them showed different techniques and interactions that might happen in sound visualization. And I hope my project can have similar achievement like them.

Xu Xu – Looking Outwards – 12

I am using 1 of my grace days for this late submission.

For this looking outwards, I found two interactive art projects that are relevant to the project I have in mind: Hershman Leeson’s Lorna in 1984 and John Lennon’s The Bermuda Tapes in 2015. The first project is the first artwork that used laserdisc technology. Using this medium to explore the possibilities and extent of interactiveness, the artist enables users to explore and intervene in the world of an agoraphobic woman named Lorna. Lorna’s actions can be controlled using a remote control, and three outcomes are possible: Lorna remains trapped by her apartment and her insecurities; she commits suicide; or she shoots the television instead, in a sense ’murdering’ the medium. The second project is an interactive Album App that tells the story of John Lennon’s journey, sailing through a mid-Atlantic storm to Bermuda in June 1980. Through the screen of an iPad or iPhone, you are able to interact with the narrative, moving, swiping and tilting, to give the story a sense of personal touch. 

Both of these projects relate to the final project I have in mind, which is an interactive game composed of choices that eventually leads to an ending. I chose the first project to discuss it because it is one of the earliest works of interactive game/film, with a really similar game structure that makes the players feel relatable (because they are the ones making the choices). The second one is graphically more developed. However, I think it has more room to grow in terms of interactivity. Players can only interact with certain things in the story, but don’t necessarily have the ability to change the story.

LORNA 1984: https://zkm.de/en/artwork/lorna

THE BERMUDA TAPES 2015: https://www.design-io.com/projects/lennonbermudatapes