Catherine Coyle – Final Project – Garden Game

Garden Game

// Catherine Coyle
// Final Project
// Section C
// ccoyle@andrew.cmu.edu

var flowers = [];

// number of the tool determines which tool the mouse is
var tool = 0;
var seedType = 0;
var SEEDTYPES = ['daisy', 'sunflower', 'tulip', 'violet'];
// 0 = seed pack
// 1 = watering can
// 2 = shovel

var filenames = [];
var images = [];
var menu = false;
var points = 0;
var flowerCount = 0;

// will be used for animation
var frames = 0;

// loading in all my image assets
function preload() {
	filenames[0] = 'https://i.imgur.com/WFbRW0R.png' // grown daisy
	filenames[1] = 'https://i.imgur.com/KfHyjYc.png' // grown sunflower
	filenames[2] = 'https://i.imgur.com/f5Naph6.png' // tulip grown
	filenames[3] = 'https://i.imgur.com/RjLTKmz.png' // violet grown
	filenames[4] = 'https://i.imgur.com/v4QTgQ2.png' // watering can
	filenames[5] = 'https://i.imgur.com/Rj3iuaG.png' // watering can pouring
	filenames[6] = 'https://i.imgur.com/1emAAfx.png' // daisy seed
	filenames[7] = 'https://i.imgur.com/Sjj5ezu.png' // sunflower seed
	filenames[8] = 'https://i.imgur.com/1HzYXus.png' // tulip seed
	filenames[9] = 'https://i.imgur.com/cKFWiib.png' // violet seed
	filenames[10] = 'https://i.imgur.com/z2DQqJT.png' // seeds plant
	filenames[11] = 'https://i.imgur.com/NBEkiuR.png' // daisy sapling
	filenames[12] = 'https://i.imgur.com/FVmfFxU.png' // sunflower sapling
	filenames[13] = 'https://i.imgur.com/9tXiQKK.png' // tulip sapling
	filenames[14] = 'https://i.imgur.com/irNCdQr.png' // violet sapling
	filenames[15] = 'https://i.imgur.com/pvEMQE2.png' // shovel up
	filenames[16] = 'https://i.imgur.com/WJ2MWlw.png' // shovel down

	for (var i = 0; i < filenames.length; i++) {
		images[i] = loadImage(filenames[i]);
	}
}

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

function draw() {
	background(173, 214, 156);

	// flowerCount is used to calculate points
	flowerCount = 0

	for (var i = 0; i < flowers.length; i++) {

		// flowers stop being watered after about 10 seconds
		if ((frames - flowers[i].startingF > 600) & (flowers[i].watered)){
			flowers[i].watered = false;
			flowers[i].startingF = frames;
		}

		// if they are not watered for 10 seconds, they wilt
		else if ((frames - flowers[i].startingF > 600) & 
				(flowers[i].watered == false)) {
			flowers[i].wilted = true;
		}

		// these if statements are just delegating how long it takes a flower to grow
		if ((flowers[i].status == 'seed') & 
			(frames - flowers[i].statusF - flowers[i].wiltedFrames > 700) &&
			 (flowers[i].wilted == false)) {
			flowers[i].status = 'sapling';
			flowers[i].statusF = frames;
		}
		else if ((flowers[i].status == 'sapling') & 
			(frames - flowers[i].statusF - flowers[i].wiltedFrames > 1200) && 
			(flowers[i].wilted == false)) {
			flowers[i].status = 'grown';
			flowers[i].statusF = frames;
		}

		// only non-wilted flowers are considered for points
		if (flowers[i].wilted == false) {
			flowerCount++;
		}
		flowers[i].draw();
	}

	// points increase every half-second
	if (frames % 30 == 0) {
		points += flowerCount;
	}

	// menu and points display
	fill(87, 77, 221);
	rect(0, 0, 200, 60);
	fill(255);
	textSize(30);
	text('POINTS: ' + str(points), 0, 30);
	textSize(10);
	text('Press m to display the menu', 0, 50);
	fill(0);
	noStroke();

	// different images are shown on the mouse based on the different tools
	if (tool == 0) {
		image(images[6 + seedType], mouseX, mouseY - 40);
	}
	else if (tool == 1) {
		if (mouseIsPressed){
			image(images[5], mouseX, mouseY - 40);
		}
		else {
			image(images[4], mouseX, mouseY - 40);
		}
	}
	else if (tool == 2) {
		if (mouseIsPressed){
			image(images[16], mouseX, mouseY - 40);
		}
		else {
			image(images[15], mouseX, mouseY - 40);
		}
	}

	// menu text
	if (menu) {
		fill(87, 77, 221);
		rect(20, 20, 440, 440);
		fill(255);
		textSize(12);
		text('-Grow a cute garden and gain points! \n \n \
			-Use the left and right arrows to cycle through tools \n \n \
			-The up and down arrows cycle through different types of flowers! \n \n \
			-Blue circles mean that your plant is currently watered \n \n \
			-Brown circles mean that it has wilted and you need to water it again! \n \n \
			-Points only increase for non-wilted flowers \n \n \
			-Press m again to go back to the game!', 30, 130);
	}

	// the continuous counter increases every time draw is called, time events are based on this
	frames++;
}

function keyPressed() {

	// right and left arrow commands switch between tools
	if (keyCode == RIGHT_ARROW) {
		tool++;
		tool = tool % 3;
	}
	else if ((keyCode == LEFT_ARROW) & (tool > 0)) {
		tool--;
		tool = Math.abs(tool);
		tool = tool % 3;
	}
	else if ((keyCode == LEFT_ARROW) & (tool == 0)) {
		tool = 2;
	}

	// up and down arrows switch between flower types
	// this only occurs if the user is currently using the seed tool
	if ((tool == 0) & (keyCode == UP_ARROW)) {
		seedType++;
		seedType = seedType % SEEDTYPES.length;
	}
	else if ((tool ==0) & (keyCode == DOWN_ARROW) && (seedType > 0)) {
		seedType--;
		seedType = seedType % SEEDTYPES.length;
	}
	else if ((tool ==0) & (keyCode == DOWN_ARROW) && (seedType == 0)) {
		seedType = 3;
	}
	if ((key == 'm') & (menu == false)) {
		menu = true;
	}

	//pressing m opens the menu
	else if ((key == 'm') & (menu)) {
		menu = false;
	}
}

function mousePressed() {

	// clicking with the seed tool will plant a seed
	if (tool == 0) {
		newFlower = makeFlower(SEEDTYPES[seedType], mouseX, mouseY, seedType);
		flowers.push(newFlower);
	}

	// clicking with the watering can waters the flower
	if (tool == 1) {
		for(var i = 0; i < flowers.length; i++) {
			if ((dist(mouseX, mouseY, flowers[i].x, flowers[i].y) < 20) & 
				(flowers[i].wilted)) {
				flowers[i].wilted = false;
				flowers[i].wiltedFrames = 0;
				flowers[i].startingF = frames;
			}
			else if ((dist(mouseX, mouseY, flowers[i].x, flowers[i].y) < 20)) {
				flowers[i].watered = true;
				flowers[i].startingF = frames;
			}
		}
	}

	// clicking with the shovel digs up and removes the flower
	if (tool == 2) {
		for (var i = 0; i < flowers.length; i++) {
			if (dist(mouseX, mouseY, flowers[i].x, flowers[i].y) < 20) {
				flowers.splice(i, 1);
			}
		}
	}
}

// flower class
function makeFlower(type, x, y, typeNum) {
	flower = {
		type: type,
		x: x,
		y: y,
		status: 'seed',
		wilted: false,
		draw: drawFlower,
		watered: false,
		imageNum: typeNum,
		startingF: frames,
		statusF: frames,
		wiltedFrames: 0,
	}
	return flower
}


function drawFlower() {
	fill(255);

	// blue circle indicates flower has been watered
	// circle size decreases as time watered runs out
	if (this.watered) {
		stroke('blue');
		strokeWeight(.25);
		noFill();
		ellipse(this.x - 20, this.y - 20, 10, 10);
		var waterTime = map(frames - this.startingF, 600, 0, 0, 10);
		fill('blue');
		noStroke();
		ellipse(this.x - 20, this.y - 20, waterTime, waterTime);
	}

	// brown circles indicate a wilted flower
	if (this.wilted) {
		fill('brown')
		ellipse(this.x - 20, this.y - 20, 10, 10);
		this.wiltedFrames++;
	}

	// below if statements delegate which image to be drawn
	if (this.status == 'seed') {
		image(images[10], this.x - 20, this.y - 20);
	}
	else if (this.status == 'sapling') {
		image(images[11 + this.imageNum], this.x - 20, this.y - 20);
	}
	else if (this.status == 'grown') {
		image(images[this.imageNum], this.x - 20, this.y - 20);
	}
}

I had so much fun with this!!!!!!

The instructions are all viewable in-game by going to the menu. It basically involves clicking and selecting tools with the arrow keys.

I really like idyllic and peaceful kind of games so I thought making a gardening game would be fun! I had originally wanted to have random interactions with animals but it turned out to be too much to do in the time frame (maybe I’ll do it on my own).

The graphics are not the best as I didn’t really realize how many I would have to draw going into the project but I think at the least they get the point across.

I was really happy with my time-based animations for this project as I feel like we didn’t do too much with those this semester. Additionally I took advantage of objects to make all my flowers.

I hope you like the game!

Catherine Coyle – Looking Outwards 12

For my final project, I would like to make some kind of relaxing gardening mini game. Two of my favorite games that I’ve played are the Animal Crossing series and Stardew Valley which I’ll focus on for this looking outwards assignment.

Both of these are pretty well-known video games that have less of a ‘goal’ or storyline than a lot of games (Animal Crossing moreso than Stardew Valley in that respect), and instead are just peaceful ways to relax. Both of the games feature some kind of planting or gardening activity which is what inspired the idea for my project.

I like both of these games because they make you feel peaceful when you play them. The concepts and characters are all very friendly, and the games’ art is soft and welcoming. I don’t think much was overlooked in either games’ case. They have less story and mechanics than a lot of other games, but also they don’t need that because it would ruin the peaceful feeling

A screenshot from Stardew Valley which was developed by ConcernedApe and came out in 2016
A screenshot from Animal Crossing New Leaf of Nintendo’s ‘Animal Crossing’ series

(I am using my second grace day for this post)

Catherine Coyle – Project 12 – Proposal

For my final project I’d really like to make some kind of relaxing game. I think this would be a nice opportunity to make a game which I really want to do as well as make it look appealing visually. In this vein, I thought about making some kind of cute little gardening game. The player would be able to choose what seeds to plant and water them by clicking. There could be random events like weather or animals coming to visit. Different plants’ properties would be stored in objects. I think this idea is something I’d enjoy working on as well as something that I will hopefully be proud to show off when I’m done!

A concept of some initial ideas for the project

Catherine Coyle – Project 11 – Composition

use arrow keys to generate spirals

// Catherine Coyle
// ccoyle@andrew.cmu.edu
// Section C
// Project 11 - Composition

//var numFlowers = Number(prompt('how many flowers?'));
var numFlowers = 1;
var pastNumFlow = 1;
var firstFlower;
var flowers = [];


function setup() {
  // put setup code here
  createCanvas(480,480);
  //print(numFlowers);
  firstFlower = makeFlower();
  flowers.push(firstFlower);
}

function draw() {
	background(177, 237, 196);
	for(var i = 0; i < numFlowers; i++) {
		flowers[i].draw();
	}
	fill(56, 112, 90);
	textSize(20);
	text('# of Flowers:', width / 2 - 50, height - 50);
	noStroke();
	fill(32, 76, 72);
	textSize(25);
	text('←  ' + numFlowers + '  →', width / 2 - 40, height - 10);
}

function keyPressed() {
	if (keyCode == RIGHT_ARROW) {
		pastNumFlow = numFlowers;
		numFlowers++;
		newFlower = makeFlower();
		flowers.push(newFlower);
	}
	if ((keyCode == LEFT_ARROW) & (numFlowers > 1)) {
		pastNumFlow = numFlowers;
		numFlowers -= 1;
	}
}

function makeFlower() {
	var f = {
		x: random(width),
		y: random(height),
		c: color(random(255), random(255), random(255)),
		petals: random(30, 200),
		r: random(5, 50),
		ang: random(100, 360),
		draw: drawFlower,
	}
	return f;
}

function drawFlower() {
	currFlow = makeTurtle(this.x, this.y);
	currFlow.setColor(this.c);
	for(var i = 0; i < this.petals; i++) {
		currFlow.forward(this.r);
		currFlow.right(this.ang);
	}
}



function turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}
function turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;
var newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){
this.forward(-p);}function turtlePenDown(){this.penIsDown=true;}
function turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){
if(this.penIsDown){stroke(this.color);strokeWeight(this.weight);
line(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){
return sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){
var absAngle=degrees(atan2(y-this.y,x-this.x));
var angle=((absAngle-this.angle)+360)%360.0;return angle;}
function turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle< 180){
this.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}
function turtleSetWeight(w){this.weight=w;}function turtleFace(angle){
this.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,
angle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,
right:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,
penUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,
turnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,
setColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};
return turtle;}

I kind of had an idea for an abstract garden for this project. You use the arrow keys to control the amount of ‘flowers’ (randomized spirals) on the screen. I made an object to store the properties of all the spirals and then drew them with turtles. It’s really cool and interesting to see what kinds of patterns the program can come up with!

Here’s one example

Catherine Coyle – Looking Outwards 10

For this week’s looking outwards, I went through the provided list of women in code, and really enjoyed the SUPERHYPERCUBE project by Heather Kelley.

A trailer and demo for the SUPERHYPERCUBE game

The project is essentially a VR arcade kind of game. It’s really simple in its idea, but the visuals are interesting and the puzzles make you work your brain which I think is cool. VR is a cool technology on its own, and it is nice to see really high quality simple concepts implemented sometimes rather than the very detailed ones. Sometimes I feel like those fall into uncanny valley territory and can be less immersive even.

Heather Kelley primarily works in game design and digital arts and media. She is very influential in the field and was named one of the five most powerful women in gaming by Inc. magazine in 2013. I couldn’t find where she went to school or what she studied online, but I did find out that she works here at CMU! I also found out that she worked on the indie game FEZ which is actually a game that I’ve played and really enjoyed so I find that very cool.

(I’m using my first LO grace day for this)

Catherine Coyle – Project 10

sketch

// Catherine Coyle
// Section C
// ccoyle@andrew.cmu.edu
// Project 10 - generative landscape


var startingTrees = 10;
var trees = [];
var fog = [];
var fireflies = [];
var birds = [];
var frameC = 1;

function setup() {
    createCanvas(480, 300);
    for (var i = 0; i < startingTrees; i++) {
    	var newTree = makeTree(random(width));
    	// this little chunk of code minimizes the chances of trees overlapping each other
    	for (var j = 0; j < trees.length; j++) {
    		while (((newTree.x > trees[j].x) & (newTree.x < trees[j].x + (trees[j].proximity * 30))) ||
    				((newTree.x + (newTree.proximity * 30) > trees[j].x) && 
    				(newTree.x + (newTree.proximity * 30) < trees[j].x + (trees[j].proximity * 30)))) {
    					newTree = makeTree(random(width));
    		}
    	}
    	trees.push(newTree);
    }
    // generating all the fog clouds and fireflies to start
    for (var i = 0; i < 5; i++) {
    	var newCloud = makeCloud(random(width));
    	fog.push(newCloud);
    }
    for (var i = 0; i < 20; i++) {
    	var newFly = makeFirefly(random(width));
    	fireflies.push(newFly);
    }
}

function draw() {
	// moon and horizon line
	background(76, 93, 99);
	noStroke();
	fill(43, 61, 56);
	rect(0, 100, width, 200)
	fill(255, 253, 237);
	ellipse(width / 2, 0, 70, 70);
	// drawing all my objects each frame
	for (var i = 0; i < birds.length; i++) {
		birds[i].draw();
		birds[i].move();
	}
	for (var i = 0; i < trees.length; i++) {
		trees[i].draw();
		trees[i].move();
	}
	for (var i = 0; i < fireflies.length; i++) {
		fireflies[i].draw();
		fireflies[i].move();
	}
	for (var i = 0; i < fog.length; i++) {
		fog[i].draw();
		fog[i].move();
	}
	// occasionally adding new objects
	// making them dependent on frameC affects the distance apart they will be from each other
	if ((frameC % 30 == 0) & (random(1) < .5)) {
		newTree = makeTree(width);
		trees.push(newTree);
	}
	if ((frameC % 100 == 0) & (random(1) < .5)) {
		newCloud = makeCloud(width);
		fog.push(newCloud);
	}
	if ((frameC % 5 == 0) & (random(1) < .5)) {
		newFly = makeFirefly(width);
		fireflies.push(newFly);
	}
	// want the birds flying by to be kind of rare
	if (random(1) < .008) {
		newBird = makeBird();
		birds.push(newBird);
	}
	frameC++;
	// removing elements that have passed (so list doesnt get too long)
	removeOldTrees();
	removeOldClouds();
	removeOldFlies();
}

// most code below here is straightforward

// each element has its own object and unique properties

function makeTree(startingPt) {
	var tree = {
		x: startingPt,
		proximity: random(1/3, 1),
		draw: drawTree,
		move: moveTree
	}
	return tree;
}

function makeCloud(startingPt) {
	var cloud = {
		x: startingPt,
		visibility: random(1),
		cloudW: random(80, 300),
		elevation: random(50),
		draw: drawCloud,
		move: moveCloud,
	}
	return cloud;
}

function makeFirefly(startingPt) {
	var firefly = {
		x: startingPt,
		y: random(height),
		velX: random(-2, 1.5),
		velY: random(-2, 2),
		sizeF: random(10),
		draw: drawFirefly,
		move: moveFirefly
	}
	return firefly;
}

function makeBird() {
	var bird = {
		x: width,
		y: random(80),
		draw: drawBird,
		move: moveBird,
	}
	return bird;
}

function drawBird() {
	fill(0);
	triangle(this.x, this.y, this.x + 20, this.y - 10, this.x + 20, this.y + 10);
}

function moveBird() {
	this.x -= 5;
}

function drawFirefly() {
	fill(226, 220, 145, 60);
	ellipse(this.x, this.y, this.sizeF * 1.5, this.sizeF * 1.5);
	fill(226, 220, 145);
	ellipse(this.x, this.y, this.sizeF, this.sizeF);
}

function moveFirefly() {
	this.x -= 1.5;
	this.x += this.velX;
	this.y += this.velY;
}

function drawCloud() {
	fill(255, this.visibility * 100);
	rect(this.x, height - this.cloudW / 2 - this.elevation, this.cloudW, this.cloudW / 2);
}

function moveCloud() {
	this.x -= .5;
}

function drawTree() {
	fill(10 + 70 * this.proximity, 30, 55);
	rect(this.x, 0, 30 * this.proximity, height * this.proximity);
}

function moveTree() {
	this.x -= 1;
}


// these 'remove' functions work by looping through the objects
// and getting rid of whats offscreen
function removeOldTrees() {
	for (var i = 0; i < trees.length; i++) {
		if (trees[i].x + 30 * trees[i].proximity < 0) {
			trees.splice(i, 1);
		}
	}
}

function removeOldClouds() {
	for (var i = 0; i < fog.length; i++) {
		if (fog[i].x + fog[i].cloudW < 0) {
			fog.splice(i, 1);
		}
	}
}

function removeOldFlies() {
	for (var i = 0; i < fireflies.length; i++) {
		if ((fireflies[i].x + fireflies[i].sizeF / 2 < 0) ||
			(fireflies[i].y + fireflies[i].sizeF / 2 < 0) ||
			(fireflies[i].y + fireflies[i].sizeF / 2 > height)) {
			fireflies.splice(i, 1);
		}
	}
}

 

This project was really fun! I’m in the Halloween/fall mood so I wanted to do something kind of dark and decided to go with a forest landscape.

My first sketches on paper (not everything here was put into the final project)

The trees look simple but were probably the most complex part of the project. I wanted to give a feeling of depth so the further trees are smaller and darker in color. However, this made it look really bad when the trees were first initially generated because some would overlap and look really weird so I tried my best to avoid that in setup. The  fireflies were pretty easy to do but I think they might be my favorite part of the project because they’re just nice to look at.

Catherine Coyle Project 9

sketch

// Catherine Coyle
// ccoyle@andrew.cmu.edu
// section C
// project 9

var img;
var currColor;
var ix;
var iy;
var seenColors = [];

// basic image loading code

function preload() {
    var imgurl = 'https://i.imgur.com/2TSW1Hy.png';
    img = loadImage(imgurl)

}

function setup() {
   createCanvas(480, 480);
   background(0);
   img.loadPixels();
}

function draw() {
    // this basic pixel grabbing format was taken from the example on the website
    var px = random(width);
    var py = random(height);
    ix = constrain(floor(px), 0, width-1);
    iy = constrain(floor(py), 0, height-1);
    currColor = img.get(ix, iy);
    // will draw the shape/pixel with the right color
    stroke(currColor);
    drawShape(px, py);
}

// drawing the pixel at given location
function drawShape(x, y) {
    var donutSize = calcSize();
    strokeWeight(donutSize);
    noFill();
    ellipse(x, y, donutSize * 2, donutSize * 2);

}


// the size of the donuts is based on the frequency of
// pixels w the same color
function calcSize() {
      var currColorBr = floor(brightness(currColor));
      seenColors.push(currColorBr);
      return constrain(countElements(currColorBr), 0, 20);
}


// idk if theres a java function that counts elements but
// i couldnt find one when i looked so i wrote one
function countElements(element) {
    var c = 0;
    for(var i = 0; i < seenColors.length; i++) {
        if (seenColors[i] == element) {
            c++;
        }
    }
    // mod 10 to make them not get too big
    return c % 10;
}

I thought this was a cool project! I chose my close friend Melissa as the subject because I think this is a really pretty picture of her that I took over the summer. She really likes donuts so I decided to make the ‘pixels’ all donut shaped. It felt too simple just doing that though so I wanted to add another aspect to it. I decided to have the sizes of the donuts be based on the frequency of the brightness of the pixels. It took a while because I found out that javascript doesn’t really have dictionaries which was disappointing so I just stored all the information in a list and wrote functions to count the frequency.

 

I am happy with how it turned out in the end!

A possible unfinished outcome

 

Early design I was just figuring out how to make it work
Original picture of Melissa! I had to crop and resize the one used for the project

Catherine Coyle – Looking Outwards 8

Jane Friedoff’s full EYEO Presentation

This week I decided to write about Jane Friedhoff’s talk at the EYEO festival as I thought the summary of her work was interesting and I think game design is a really cool intersection of art and computing!

Jane Friedhoff studied sustainable development at Columbia University and later design and technology at The New School in New York. She seems still very young but has a lot of impressive experience with Google, the New York Times, and also founding the Code Liberation Foundation.

In her presentation, she talks about her ‘Riot Grrrl’ approach to making games. She describes these games as ‘power fantasies’ but not the usual ones found in games. Instead they revolve around making chaos and just running wild. Instead of making punk music, Friedhoff likes to make unpolished punk games. Some of the games she creates deal with tougher issues, but instead of being meant to educate the other side on why she is feeling this way, they are meant more for ‘catharsis’ and just expressing her feelings. For example in ‘Lost Wage Rampage’ two girls who find out that they’ve been paid significantly less than their male co-workers steal a car and rampage through a mall, taking back the money that they lost.

I think this is a perfect example of art in games as more than anything else, it is an effort to make you feel a certain way. Many games are more story based (which is still fun), but creating games based entirely around chaos and feelings is something new that I can admire.

As for her presentation style, she works with a standard PowerPoint presentation. However, she is great at using her voice to keep your attention and uses interesting visuals to help us follow along.

Altogether, I really admired learning about her and her work! You can read about her on her website here.

Catherine Coyle – Project 7 – Curves

catherine curves

// Catherine Coyle
// ccoyle@andrew.cmu.edu
// Section C
// Project 7  - Curves

// equations taken from http://mathworld.wolfram.com/Hypotrochoid.html

var n = 1;
var h = 2;
var t = 1;
var a;
var b;

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

function draw() {
    background(226, 237, 255);
    // number of 'rotations' is dependent on y
    n = map(mouseY, 0, height, .9, 1.1);
    // size of rotation circles is dependent on x
    h = map(mouseX, 0, width, 2, 4);
    // smaller helper functions below here
    a = aCalc();
    b = bCalc();
    drawHypotochroidShadow(t, a, b);
    drawHypotochroid(t, a, b);
}

// i broke a lot of the heavy math parts into smaller functions
// to make it more manageable
function aCalc() {
    return(2 * n * h / (n + 1));
}

function bCalc() {
    return(((n - 1) * h) / (n + 1));
}

function xPar(t, a, b) {
    var answer = (a - b) * cos(radians(t));
    var cosVal = ((a - b) / b) * t;
    answer = answer + h * cos(radians(cosVal));
    return answer;
}

function yPar(t, a, b) {
    var answer = (a - b) * sin(radians(t));
    var cosVal = ((a - b) / b) * t;
    answer = answer + h * sin(radians(cosVal));
    return answer
}

function drawHypotochroid(t, a, b) {
    stroke(193, 124, 124);
    noFill();
    // loops through entire curve and plot every point
    beginShape();
    for(var i = 0; i < width; i++){
        var x = map(xPar(i, a, b), -4, 4, 0, width);
        var y = map(yPar(i, a, b), -4, 4, 0, height);
        curveVertex(x, y);
    }
    endShape();
}

// same as above but with some offset just to look cool
function drawHypotochroidShadow(t, a, b) {
    stroke(66, 134, 244, 50);
    noFill();
    // loops through entire curve and plot every point
    beginShape();
    for(var i = 0; i < width; i++){
        var x = map(xPar(i, a, b), -4, 4, 0, width);
        var y = map(yPar(i, a, b), -4, 4, 0, height);
        curveVertex(x-4, y-4);
    }
    endShape();
}

This project was kind of hard to get started with but once I wrapped my head around it I found it very cool.

I probably spent a good hour on the mathworld website trying to settle on a curve, but found that a lot of them were too hard to implement. I decided to go with the hypotrochoid shape found here.

If you keep your mouse on the left end of the screen, the curve should stay within the canvas if you want to see an entire design. Otherwise, moving your mouse to the right will kind of ‘zoom in’ to the center of the curve.

It took a lot of experimenting and trial and error to make the program work right, but in the end it produced some nice results.

 

The really early stages of the program when I first started to connect vertices
An interesting design that I found in the program at the end.

Catherine Coyle – Looking Outwards – 07

Information visualization can make a huge difference in how viewers feel about certain data and how it comes across. For this week, I decided to do my looking outwards post on the Fitbit CES animations done by Rachel Binx. She was one of the designers that was recommended on our website and I like her work a lot.

Fitbit Animations from Rachel Binx on Vimeo.

Above is a preview of her animations for this project.

For this work, I assume that she was given heart-rate/Fitbit data to work from and made these clean looking animations to visualize it. I would assume that the algorithms behind it are basic because it is mostly displaying different charts and numbers, rather it is the art that accompanies it that makes the work admirable. She wrote the animations so that they feel very smooth and fit the ‘Fitbit’ general aesthetic which I admire a lot.