/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.rFlagR8XScA/rev.1002
*
* authors:
*
*
*
* Alex Stempel
* Alex Spielman
*
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
//press j to pause sketch and then j again to have it continue
Particle[] bodies = new Particle[1000];
Gravity gravObj;
float area;
float incr;
float xpos;
float ypos;
float countJ;
void setup() {
size(800, 800);
countJ = 0;
area = width*height;
incr = 243000/15000;
xpos = 150;
ypos = 150;
gravObj = new Gravity();
for (int i = 0; i < bodies.length; i++) {
bodies[i] = (new Particle(xpos, ypos, 16));
if (xpos > (650-incr)) {
xpos = 150;
ypos += incr;
} else {
xpos += incr;
}
}
}
void draw() {
background(255);
gravObj.display();
for (int i = 0; i < bodies.length; i++) {
PVector force = gravObj.getForceVector(bodies[i]);
bodies[i].accelWithGravity(force);
bodies[i].update();
bodies[i].create();
}
}
void mousePressed() {
gravObj.setLocation();
}
void keyPressed() {
if (key == 'j') {
countJ++;
if (countJ%2 == 1) {
for (int i = 0; i < bodies.length; i++) {
bodies[i].storeVel(bodies[i]);
}
gravObj.keyPressD = true;
}
else if (countJ%2 == 0){
gravObj.keyPressD = false;
for (int i = 0; i < bodies.length; i++) {
bodies[i].setVel(bodies[i]);
}
}
}
}
class Gravity {
float mass;
float g;
PVector location;
public boolean keyPressD;
Gravity() {
location = new PVector(width/2, height/2);
mass = 20;
g = 1;
keyPressD = false;
}
PVector getForceVector(Particle p) {
if (keyPressD == true) {
return new PVector(0, 0);
}
float r12 = dist(location.x, location.y, p.getX(), p.getY());
r12 = constrain(r12, 30, 30);
PVector unit_r12 = (PVector.sub(location, p.location));
unit_r12.normalize();
float m1m2 = (p.mass)*mass;
PVector f12 = PVector.mult(unit_r12, (g*((m1m2)/pow(r12, 2))));
return f12;
}
void display() {
fill(0);
ellipse(location.x, location.y, mass*2, mass*2);
}
void setLocation() {
location.x = mouseX;
location.y = mouseY;
}
boolean above() {
if (abs(mouseX - location.x) <= 20 || abs(mouseX - location.y) >= 0) {
return true;
}
return false;
}
}
class Particle {
PVector location;
PVector velocity;
PVector storeV;
PVector acceleration;
float mass;
float storeM;
int colors;
Particle(float x, float y, float m) {
location = new PVector(x, y);
velocity = new PVector(0, 0);
acceleration = new PVector(0, 0);
mass = m;
// float red = random(155, 255);
// float blue = random(0, 100);
// float green = random(0, 10);
// colors = color(red, green, blue); // would it be more effictint to use color = r | g | b | a and << notation
x = x - 150;
y = y - 150;
int a = (int)(255);
int r = (int)(500 - x);
if (x > width/2 -150) {
r = (int)(x);
}
int b = (int)(500 - y);
if (y > height/2 -150) {
b = (int)(y);
}
int g = (int)random(0);
a = a << 24;
r = r << 16;
g = g << 8;
// Equivalent to "color argb = color(r, g, b, a) but faster?
colors = (a | r | g | b);
}
void accelWithGravity(PVector force) {
PVector accel = PVector.div(force, mass);
acceleration.add(accel);
}
void update() {
velocity.add(acceleration);
location.add(velocity);
acceleration.x = 0;
acceleration.y = 0;
}
void storeVel(Particle p) {
storeV = p.velocity;
velocity = new PVector(0, 0);
}
void setVel(Particle p) {
velocity = p.storeV;
}
void create() {
fill(colors);
noStroke();
ellipse(getX(), getY(), mass, mass);
}
float getX() {
return location.x;
}
float getY() {
return location.y;
}
}