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.
/* 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;
}
}