svitoora – 04 Gravity 2.0

Gravity

//
// Supawat Vitoorapakorn
// Svitoora@andrew.cmu.edu
// Section E
//
// Gravity 2.0 is a point mass dynamic drawing inspired
// from physics, nature, and falling off a skateboard.
// f = G (m1*m2)/d^2
// f = G sum(m)/(d from avg)^2


// World Model Setup /////////////////////////////////////
var max_curves = 4; //Limit amount of drawings

var w = 300;
var h = 400;
var t = 1; // time variable
var g = 12; // gravity

var ball;
var balls = []; // Local Objects
var ballz = []; // Global Object
var ball_size = w * .010 // Default object size

var max_count = 35;
var auto_every = 40;
var auto_create = 125;
var max_line = 1000; // Prevents crash


// Control ///////////////////////////////////////////////

// Creates new object in system given (x,y)
function ball_create(x, y) {
	this.x = x;
	this.y = y;
	this.vx = 0;
	this.vy = 0;
	this.r = ball_size;
	this.m = 1;
	this.ALPHA = 255
}

function mousePressed() {
	ballz.push([]);
	// print("Added Yo");
}

// Add new object and delete oldest object
function mouseDragged() {
	if (t % 10) {
		ballz[ballz.length - 1].push(new ball_create(mouseX, mouseY));
	}
	if (ballz[ballz.length - 1].length >= max_count) {
		ballz[ballz.length - 1].splice(0, 1)
	}
}

// World /////////////////////////////////////////////////


// Maintain global mass of system
function sum_mass(balls) {
	sum_m = 0;
	for (i in balls) {
		sum_m += balls[i].m;
	}
	return sum_m;
}

// Determines the system's average position X
function average_posX(balls) {
	if (balls.length == 0) {
		return w / 2;
	};
	var sum_x = 0;
	for (i in balls) {
		sum_x += balls[i].x;
	}
	avg = sum_x / balls.length
	return avg;
}

// Determines the system's average position Y
function average_posY(balls) {
	if (balls.length == 0) {
		return h / 2;
	};
	var sum_y = 0;
	for (i in balls) {
		sum_y += balls[i].y;
	}
	avg = sum_y / balls.length;
	return avg
}

// Apply gravity for all objects in the system
function gravity(balls) {
	var avg_x = average_posX(balls);
	var avg_y = average_posY(balls);
	var speed = .005 //0-1 Multuplier for controlling velocity of attratction
	for (i in balls) {
		d = dist(balls[i].x, balls[i].y, avg_x, avg_y);
		ds = map(d, 0, w / 2, 1, 0); // used to simulate d^2

		// Gravity X
		if (balls[i].x > avg_x) {
			balls[i].x *= 1 - (g * (balls.length * speed));
		} else {
			balls[i].x *= 1 + (g * (balls.length * speed + ds));
		}

		// Gravity Y
		if (balls[i].y > avg_y) {
			balls[i].y *= 1 - (g * (balls.length * speed))
		} else {
			balls[i].y *= 1 + (g * (balls.length * speed + ds));
		}
	}
}

// Add object to system in the middle; // Used at setup()
function add_ball(balls) {
	balls.push(new ball_create(w / 2, h / 2));
}



// Connects all the object in the system via a line
function draw_line(balls) {
	lines = 0
	opacity = 255 * .1

	if (lines < max_line) {
		for (i in balls) {
			var x_1 = balls[i].x;
			var y_1 = balls[i].y;
			for (i in balls) {
				var x_2 = balls[i].x;
				var y_2 = balls[i].y;
				stroke(255, 255, 255, opacity);
				line(x_1, y_1, x_2, y_2);
				lines += 1;
			}
		}
	}
}

// SETUP
function setup() {
	createCanvas(w, h);
	g = .0025;
	background(50);
	balls.length = 0; // Kill all objects in system
}

// Refreshes the systems with new objects
// Removes old objects and add new objects
function auto_refresh(balls, t) {
	// Starts refreshing system at 5 objects
	// every auto_every interval.
	if (t % auto_every == 0 & balls.length > 5) {
		balls.splice(0, 1);
	}
	X = constrain(mouseX, 1, w);
	Y = constrain(mouseY, 1, h)
	if (t % auto_every == 0) {
		balls.push(new ball_create(X, Y));
	}

	// Resets the system to 8 objects once every 500 ms
	// This prevents overload; Array starts at [0]
	if (t % 500 == 0 & balls.length > 8) {
		balls.length = 7;
	}
}

// Draw ////////////////////////////////////////////////////

// Draw all objects in systems mapped by distance from avg
function draw_balls(BALLS) {
	// print("BALLS.length" + BALLS.length)
	for (i in BALLS) {

		var avg_x = average_posX(BALLS);
		var avg_y = average_posY(BALLS);

		var d = dist(BALLS[i].x, BALLS[i].y, avg_x, avg_y);
		var SIZE = map(d, 0, w / 2, -2, 3) //max to min
		print(i + " : " + SIZE)

		noStroke();
		fill(255, 255, 255, 255 * .5);
		ellipse(BALLS[i].x, BALLS[i].y,
			BALLS[i].r * (2 * SIZE),
			BALLS[i].r * (2 * SIZE));
	}
}

function local_gravity(ballz) {
	for (i in ballz) {
		if (ballz[i].length > 1) {
			gravity(ballz[i]);
		}
	}
}

function DIE(BALLS) {
	BALLS.splice(0, 1);
}

function death_ballz(ballz) {
	var populated = 0;
	for (i in ballz) {
		if (ballz[i].length != 0) {
			populated++;
		}
	}
	if (populated > max_curves) {
		DIE(ballz[0]);
	}
}


function refresh_ballz(ballz) {
	if (ballz.length > 4) {
		for (i in ballz) {
			if (ballz[i].length == 0) {
				ballz.splice(i, i + 1);
				ballz.push([]);

			}
		}
	}
}


function draw_ballz(ballz) {
	for (i in ballz) {
		draw_balls(ballz[i]);
	}
}

function draw_lines(balls) {
	for (i in ballz) {
		draw_line(ballz[i]);

	}
}

// Creates Trail
function guider1() {
	stroke(255, 255, 255, 255 * .75)
	line(mouseX, mouseY, pmouseX, pmouseY)
}

// Prompt user to drag via random generation
function guider2() {
	ran1 = random(4, 12);
	if (t % auto_create == 0) {
		ballz.push([])
		ballz[ballz.length - 1].push(new ball_create(mouseX, mouseY));
		ballz[ballz.length - 1].push(new ball_create(pmouseX, pmouseY));
		for (var i = 0; i < ran1; i++) {
			ballz[ballz.length - 1].push(new ball_create(mouseX * random(.75,
				1.25), mouseY * random(.75, 1.25)));
		}
	}
}

// Execute /////////////////////////////////////////////////
function draw() {
	background(50);
	noStroke();
	// Update World
	t = t + 1;
	local_gravity(ballz);
	death_ballz(ballz);
	refresh_ballz(ballz);
	// LOL();

	// // Draw World
	draw_lines(ballz);
	guider1();
	guider2();
	// draw_ballz(ballz);	// For Some reason this doesn't work
	// Maybe it ran out of memory allocation


}

Click and drag to draw shapes. Try writing your name. I struggle with array in arrays. Eventually figured I figured it out.

Leave a Reply