mirror of
https://github.com/opelly27/Java-N-Body-Simulation.git
synced 2026-05-20 00:28:46 +00:00
183 lines
6.4 KiB
Java
183 lines
6.4 KiB
Java
import java.awt.image.*;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import javax.imageio.ImageIO;
|
|
import java.awt.Graphics2D;
|
|
|
|
// ffmpeg -framerate 60 -i %00d.png -c:v -vf format=yuv420p libx264 output.mp4
|
|
// ffmpeg -framerate 60 -start_number 1 -i %00d.png -pix_fmt yuv420p out.mp4
|
|
|
|
// TODO Add filled circle render method
|
|
|
|
// TODO Find good timeslice for annimation
|
|
|
|
|
|
|
|
public class Space {
|
|
|
|
Body[] bodies; // List of body objects that make up the simulation
|
|
double height; // The height of the spacial region being simulated
|
|
double width; // The width of the spacial region being simulated
|
|
double timeslice; // The time in sections between each tick of the simulation
|
|
|
|
public Space(Body[] bodies, int height, int width, double timeslice){
|
|
|
|
this.bodies = bodies;
|
|
this.height = height;
|
|
this.width = width;
|
|
this.timeslice = timeslice;
|
|
}
|
|
|
|
public void updateForces(){
|
|
|
|
//double runningTotal = 0;
|
|
for(int i = 0; i < this.bodies.length; i ++){
|
|
this.bodies[i].calcNetForce(this.bodies);
|
|
}
|
|
}
|
|
|
|
public void updateVelocities(){
|
|
for(int i = 0; i < this.bodies.length; i ++){
|
|
this.bodies[i].updateVelocity(this.timeslice);
|
|
}
|
|
}
|
|
|
|
public void updatePositions(){
|
|
for(int i = 0; i < this.bodies.length; i ++){
|
|
this.bodies[i].updatePosition(this.timeslice);
|
|
}
|
|
}
|
|
|
|
public void draw(){
|
|
|
|
Canvas canvas = new Canvas( (int) this.height, (int) this.width, 255,255,255,255);
|
|
for(int i = 0; i < this.bodies.length; i ++){
|
|
// switch(i){
|
|
// case 0: canvas.drawSquare(5, (int) this.bodies[i].getXpos(), (int) this.bodies[i].getYpos(), 0, 0, 0, 255);
|
|
// case 1: canvas.drawSquare(5, (int) this.bodies[i].getXpos(), (int) this.bodies[i].getYpos(), 255, 0, 0, 255);
|
|
// case 2: canvas.drawSquare(5, (int) this.bodies[i].getXpos(), (int) this.bodies[i].getYpos(), 0, 0, 255, 255);
|
|
// case 3: canvas.drawSquare(5, (int) this.bodies[i].getXpos(), (int) this.bodies[i].getYpos(), 0, 255, 0, 255);
|
|
// }
|
|
canvas.drawSquare(5, (int) this.bodies[i].getXpos(), (int) this.bodies[i].getYpos(), 0, 0, 0, 255);
|
|
|
|
}
|
|
canvas.display();
|
|
}
|
|
|
|
public void save(int frameNumber){
|
|
|
|
Canvas canvas = new Canvas( (int) this.height, (int) this.width, 255,255,255,255);
|
|
for(int i = 0; i < this.bodies.length; i ++){
|
|
if(i ==0){
|
|
canvas.drawCircle(20, (int) this.bodies[i].getXpos(), (int) this.bodies[i].getYpos(), 255, 255, 255, 255);
|
|
}
|
|
else{
|
|
int r = this.bodies[i].getR();
|
|
int g = this.bodies[i].getG();
|
|
int b = this.bodies[i].getB();
|
|
int x = (int) (this.bodies[i].getXpos());
|
|
int y = (int) (this.bodies[i].getYpos());
|
|
canvas.drawSquare(10,x, y, r, g, b, 255);
|
|
}
|
|
}
|
|
|
|
File f = null;
|
|
try{
|
|
String frameNumberStr = String.valueOf(frameNumber);
|
|
frameNumberStr = frameNumberStr + ".png";
|
|
f = new File("frames/" + frameNumberStr);
|
|
ImageIO.write(canvas.image, "png", f);
|
|
}catch(IOException e){
|
|
System.out.println("Error: " + e);
|
|
}
|
|
}
|
|
|
|
public static void main(String args[]){
|
|
|
|
Body[] bodies = new Body[5];
|
|
bodies[0] = new Body(20000000, 960, 540, 0, 0);
|
|
bodies[1] = new Body(2, 960, 520, .5, -.3);
|
|
bodies[2] = new Body(2, 960, 240, -.5, .03);
|
|
bodies[3] = new Body(2, 200, 540, .2, .5);
|
|
bodies[4] = new Body(2, 750, 540, .1, -.5);
|
|
|
|
// bodies[5] = new Body(2, 700, 540, 0, -.5);
|
|
// bodies[6] = new Body(2, 640, 540, 0, -.5);
|
|
// bodies[7] = new Body(2, 800, 540, 0, -.5);
|
|
// bodies[8] = new Body(2, 100, 540, 0, -.5);
|
|
// bodies[9] = new Body(2, 50, 540, 0, -.5);
|
|
// bodies[10] = new Body(2, 960, 100, -.5, 0);
|
|
// bodies[11] = new Body(2, 960, 300, -.5, 0);
|
|
// bodies[12] = new Body(2, 960, 800, -.5, 0);
|
|
// bodies[13] = new Body(2, 960, 600, -.5, 0);
|
|
|
|
|
|
|
|
// for(int i = 1; i < 1000; i ++){
|
|
|
|
// bodies[i] = new Body(2, Math.random() * 1080, Math.random() * 720, Math.random() -.5, Math.random() -.5);
|
|
|
|
// }
|
|
|
|
Space space = new Space(bodies, 1920, 1080, 1);
|
|
int counter = 0;
|
|
for(int i = 0; i < 50000000; i ++){
|
|
space.updateForces();
|
|
space.updateVelocities();
|
|
space.updatePositions();
|
|
//System.out.println(space);
|
|
space.save(i);
|
|
//space.save(counter);
|
|
//System.out.println(counter);
|
|
counter ++;
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
String returnString = String.format("Width: " + this.width + " Height: " + this.height + "\n\n\n");
|
|
for(int i = 0; i < this.bodies.length; i ++){
|
|
int b = i +1;
|
|
returnString += String.format("Body #" + b + "\n\n");
|
|
returnString += String.format("Position: X = " + this.bodies[i].getXpos() + " ");
|
|
returnString += String.format("Position: Y = " + this.bodies[i].getYpos() + "\n");
|
|
returnString += String.format("Velosity: X = " + this.bodies[i].getXvelo() + " ");
|
|
returnString += String.format("Velosity: Y = " + this.bodies[i].getYvelo() + "\n\n");
|
|
|
|
}
|
|
|
|
return returnString;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
// public BufferedImage generateImage(){
|
|
|
|
// BufferedImage img = new BufferedImage((int)this.height, (int)this.width, BufferedImage.TYPE_INT_ARGB);
|
|
|
|
// for(int y = 0; y < this.height; y ++){
|
|
// for (int x = 0; x < this.width; x ++){
|
|
// for (int body = 0; body < this.bodies.length; body ++){
|
|
// if((int)this.bodies[body].getXpos() == x){
|
|
// if((int) this.bodies[body].getYpos() == y){
|
|
// int a = 255;
|
|
// int r = 0;
|
|
// int g = 0;
|
|
// int b = 0;
|
|
|
|
// int p = (a<<24) | (r<<16) | (g<<8) | b;
|
|
|
|
// img.setRGB(x, y, p);
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// return img;
|
|
// }
|