Created
May 17, 2020 05:55
-
-
Save nathanielarking/f04e41387799499a09679587d9bfc483 to your computer and use it in GitHub Desktop.
Simply gravity simulation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Entity{ | |
boolean spawned = false; | |
boolean freeze = false; | |
PVector pos, vel, acc; | |
float mass, size; | |
int[] colour = new int[3]; | |
Entity(){ | |
pos = new PVector(); | |
vel = new PVector(); | |
acc = new PVector(0, 0); | |
mass = random(0.5, 6); | |
size = mass * 20; | |
for(int i = 0; i < 3; i++){ | |
colour[i] = int(random(50, 255)); | |
} | |
} | |
void randomize(){ | |
for(int i = 0; i < 3; i++){ | |
colour[i] = int(random(50, 255)); | |
} | |
} | |
void setMass(int m){ | |
mass = m; | |
size = mass * 20; | |
} | |
void updateEntity(){ | |
vel.add(acc); | |
pos.add(vel); | |
acc.mult(0); | |
} | |
void collideEntity(int mode){ | |
if(mode == 0){ | |
if(pos.x > (width - size/2)){ | |
pos.x = (width - size/2); | |
vel.x *= -1; | |
}else if(pos.x < (0 + size/2)){ | |
pos.x = (0 + size/2); | |
vel.x *= -1; | |
} | |
if(pos.y > (height - size/2)){ | |
pos.y = (height - size/2); | |
vel.y *= -1; | |
}else if(pos.y < (0 + size/2)){ | |
pos.y = (0 + size/2); | |
vel.y *= -1; | |
} | |
}else if (mode == 1){ | |
if(pos.x < 0) pos.x = width; | |
if(pos.x > width) pos.x = 0; | |
if(pos.y < 0) pos.y = height; | |
if(pos.y > height) pos.y = 0; | |
}else{ | |
if(pos.x < 0) spawned = false; | |
if(pos.x > width) spawned = false; | |
if(pos.y < 0) spawned = false; | |
if(pos.y > height) spawned = false; | |
} | |
} | |
void displayEntity(){ | |
stroke(255); | |
strokeWeight(2); | |
fill(colour[0], colour[1], colour[2]); | |
if(spawned) ellipse(pos.x, pos.y, size, size); | |
} | |
PVector attract(Entity a){ | |
if((spawned) && (!freeze) && (a.spawned) && (!a.freeze)){ | |
PVector force = PVector.sub(pos, a.pos); | |
float d = force.mag(); | |
d = constrain(d, 1, 25); | |
float str = (mass * a.mass * -G)/(d*d); | |
force.normalize(); | |
force.mult(str); | |
force.y *= -1; | |
return force; | |
}else{ | |
PVector force = new PVector(0, 0); | |
return force; | |
} | |
} | |
void applyForce(PVector force){ | |
if(!freeze){ | |
PVector f = PVector.div(force,mass); | |
f.y *= -1; | |
acc.add(f); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Press stores whether or not the mouse is being held | |
boolean press = false; | |
//Vectors to store mouse coordinates | |
PVector click = new PVector(); | |
PVector mouse = new PVector(mouseX, mouseY); | |
//Count stores which entity is next to be spawned our of our array of entities | |
int count = 0; | |
Entity[] objects = new Entity[100]; | |
float G = 10; | |
int mass = 3; | |
void setup(){ | |
size(1280, 720); | |
frameRate(45); | |
background(255); | |
strokeWeight(1); | |
stroke(0); | |
fill(100); | |
for(int i = 0; i < objects.length; i++) objects[i] = new Entity(); | |
} | |
void draw(){ | |
background(0); | |
String mstring = str(mass); | |
stroke(255); | |
fill(255); | |
text(mstring, 15, height - 15); | |
drawReset(); | |
checkPress(); | |
updateEntities(objects); | |
} | |
void drawReset(){ | |
stroke(255); | |
fill(255); | |
rect(width - 60, height - 30, 60, 30); | |
stroke(0); | |
fill(0); | |
text("RESET", width - 50, height - 10); | |
if(mousePressed && (((mouseX > width - 60) && (mouseX < width)) && ((mouseY > height - 30) && (mouseY < height)))){ | |
for(Entity o : objects){ | |
o.spawned = false; | |
count = 0; | |
} | |
} | |
} | |
void mouseWheel(MouseEvent event) { | |
float m = event.getCount(); | |
mass -= m; | |
if(mass < 1) mass = 1; | |
if(mass > 10) mass = 10; | |
} | |
void checkPress(){ | |
if(mousePressed){ | |
//This says: if the mouse is being pressed for the first time after being releasd | |
if(!press){ | |
//Update our click vector to the spot where the mouse is clicked | |
click.x = mouseX; | |
click.y = mouseY; | |
//Set the position of one of the objects to our cursor, reset the velocity & accelleration, randomize the shape and colour, and then enable displaying of the entity. Also freeze the entity so gravity doesn't affect it yet | |
objects[count].pos = click.get(); | |
objects[count].vel.mult(0); | |
objects[count].acc.mult(0); | |
objects[count].freeze = true; | |
objects[count].randomize(); | |
objects[count].setMass(mass); | |
objects[count].spawned = true; | |
//This informs the next draw loop that the mouse is now being held down | |
press = true; | |
//This says: if the mouse is currently being held | |
}else{ | |
//Update our mouse vector to current cursor position | |
mouse.x = mouseX; | |
mouse.y = mouseY; | |
//Define a new vector that is the line from our original click spot to our current mouse position | |
PVector traj = mouse.sub(click); | |
//Draw a line from our original click position along our trajectory vector to our current mouse position, weighted based on the traj length | |
stroke(255); | |
strokeWeight(traj.mag() * 0.01); | |
line(click.x, click.y, (click.x + traj.x), (click.y + traj.y)); | |
objects[count].setMass(mass); | |
} | |
//This says: if the mouse is not pressed but on the previous frame it was | |
}else if(press){ | |
//Update mouse vector | |
mouse.x = mouseX; | |
mouse.y = mouseY; | |
//Update traj vector | |
PVector traj = mouse.sub(click); | |
//Set velocity of entity based on the traj vector, reversing it and tying it to mass. Then unfreeze | |
objects[count].vel = traj.get(); | |
objects[count].vel.mult(-0.1 / objects[count].mass); | |
objects[count].freeze = false; | |
//This resets our press variable for the next time the mouse is pressed, incrementing the object counter and wrapping it to 0 to keep within the bounds of our array | |
press = false; | |
count++; | |
if(count == objects.length) count = 0; | |
} | |
} | |
void updateEntities(Entity[] objects){ | |
for(int i = 0; i < objects.length; i++){ | |
//Apply attraction | |
for(int a = 0; a < objects.length; a++){ | |
if(a != i){ | |
objects[i].applyForce(objects[i].attract(objects[a])); | |
} | |
} | |
//Update objects | |
objects[i].displayEntity(); | |
objects[i].collideEntity(3a); | |
objects[i].updateEntity(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment