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;
    }
}

Leave a Reply