im trying to programm a 3d gravity simulation, but the preview of the flight path of a selected Planet isnt working. I have marked the section in the code where this preview is calculated. Thx
Code:
class Planet extends Body3D {
boolean emmitsLight = false;
String name = null;
Planet(PVector pos_, float m_) {
this.pos = pos_;
this.m = m_;
}
Planet(PVector pos_, float m_, boolean emmitsLight_) {
this.pos = pos_;
this.m = m_;
emmitsLight = emmitsLight_;
}
Planet(PVector pos_, float m_, boolean emmitsLight_, String name_) {
this.pos = pos_;
this.m = m_;
emmitsLight = emmitsLight_;
name = name_;
}
Planet(PVector pos_, PVector vel_, float m_, boolean selected_) {
pos = pos_;
vel = vel_;
m = m_;
selected = selected_;
}
void emmitLight() {
if (emmitsLight) {
pointLight(255, 200, 200, pos.x, pos.y, pos.z);
}
}
void show() {
pushMatrix();
noStroke();
fill(255);
translate(pos.x, pos.y, pos.z);
sphereDetail(60);
if (!selected) {
if (!emmitsLight) {
sphere(this.m / 1.3);
} else {
beginShape();
PShape globe = createShape(SPHERE, this.m / 1.3);
globe.setTexture(sunTexture);
shape(globe);
endShape();
}
} else {
fill(255, 255, 0);
sphere(this.m / 1.3);
}
popMatrix();
if (this.selected) {
this.renderPath(planets, 100);
}
stroke(255, 255, 255, 30);
strokeWeight(2);
line(vel.x * 50 + pos.x, vel.y * 50 + pos.y, vel.z * 50 + pos.z, pos.x, pos.y, pos.z);
pushMatrix();
if (name != null && name != "" && dist(this.pos.x, this.pos.y, this.pos.z, camPos.x, camPos.y, camPos.z) < 3000) {
PVector textDir = this.pos.copy().sub(camPos).normalize().mult(-this.m * 1.5);
float textA = (textDir.rotate(PI / 2).heading());
textDir = textDir.add(this.pos);
translate(textDir.x, textDir.y, textDir.z);
rotateY(textA);
textAlign(CENTER, CENTER);
textSize(map(dist(this.pos.x, this.pos.y, this.pos.z, camPos.x, camPos.y, camPos.z), 0, 100, 1, 10));
text(name, 0, 0, 0);
}
popMatrix();
}
boolean isCollidingSphere(Planet p) {
return dist(this.pos.x, this.pos.y, this.pos.z, p.pos.x, p.pos.y, p.pos.z) < (this.m / 1.3 + p.m / 1.3);
}
void renderPath(ArrayList<Planet> planetsGravity, int amnt) { //Here!!!
Planet mainPlanet = this;
Planet mainPlanetAfterCopy = planetsGravity.get(0);
ArrayList<Planet> pGravity = copyPlanetArray(planetsGravity);
ArrayList<PVector> mainPlanetPath = new ArrayList<PVector>();
for (Planet p : pGravity) {
if (p.selected) {
mainPlanetAfterCopy = p;
break;
}
}
if (planetsGravity.contains(mainPlanet)) {
for (int i = 0; i < amnt; i++) {
for (Planet p : pGravity) {
p.update();
}
mainPlanetPath.add(mainPlanetAfterCopy.pos);
for (Planet b1 : pGravity) {
for (Planet b2 : pGravity) {
if (b1 != b2) {
float r = dist(b1.pos.x, b1.pos.y, b1.pos.z, b2.pos.x, b2.pos.y, b2.pos.z);
PVector p1 = new PVector(b2.pos.x, b2.pos.y, b2.pos.z);
p1 = p1.sub(b1.pos);
float a = G * ((b1.m * b2.m) / (r * r));
b1.applyForce(p1.mult(a).mult(1));
}
}
}
}
}
stroke(255);
strokeWeight(5);
for (PVector pVec : mainPlanetPath) {
point(pVec.x, pVec.y, pVec.z);
}
}
Planet copy() {
return new Planet(this.pos.copy(), this.vel.copy(), this.m, this.selected);
}
}
ArrayList<Planet> copyPlanetArray(ArrayList<Planet> p_in) {
ArrayList<Planet> pReturn = new ArrayList<Planet>(p_in.size());
for (Planet pReturn_ : p_in) {
pReturn.add(pReturn_.copy());
}
return pReturn;
}
There is also a body 3d class and the main program:
class Body3D {
boolean selected = false;
PVector pos;
PVector vel = new PVector(0, 0, 0);
PVector acc = new PVector(0, 0, 0);
float m;
void applyForce(PVector acc_) {
acc = acc.add(acc_);
}
void update() {
vel = vel.add(acc.div(m));
acc = new PVector(0, 0, 0);
pos = pos.add(vel);
if(this.selected && focusedOnPlanet){
camPos.add(vel);
camDir.add(vel);
}
}
}
ArrayList<Planet> planets = new ArrayList<Planet>();
ArrayList<Planet> Removeplanets = new ArrayList<Planet>();
PVector camPos = new PVector(0, 0, 0);
PVector camDir = new PVector(0, 0, 0);
float aYZ = 0;
float aXZ;
PImage sunTexture;
float PlanetSize;
float Scroll;
boolean PlanetBeingCreated = false;
float distCreatePlanet = 100;
boolean paused = false;
boolean focusedOnPlanet = false;
float G = 1;
int OverlayX;
int OverlayY;
color green = color(0, 255, 0);
/*
Controls
--------------
c: Creates a Planet. Use scroll wheel to change size.
C: Creates a Planet. Use scroll wheel to change size (faster).
p: pause.
Right click: Select a Planet infront of you. Right click in the void to unselect.
d: Deletes selected planet.
f: Clears the planets velocity.
v: Focus on the selected planet.
a: Apply a force in the direction you are looking to selected planet.
A: Apply a force in the direction you are looking to selected planet (faster).
w / s: Move.
W / S: Move (faster).
Left click and drag: Look around.
--------------
*/
void setup() {
size(1200, 1000, P3D);
//fullScreen(P3D);
perspective(PI / 2, float(width) / float(height), 0.1, 1000000);
aXZ = height / 2;
planets.add(new Planet(new PVector(-100, 0, 0), 50, true, "sun"));
planets.add(new Planet(new PVector(100, 100, 500), 50));
planets.add(new Planet(new PVector(200, 400, 300), 80));
sunTexture = loadImage("sun.jpg");
OverlayX = width / 2;
OverlayY = height / 2;
}
void draw() {
background(0);
if (aXZ > height) {
aXZ = height;
} else if (aXZ < 0) {
aXZ = 0;
}
float angle = map (aYZ, 0, width, -PI, TWO_PI);
float camDirX = 700 * cos(angle) + camPos.x;
float camDirY = map(aXZ, 0, height, -1333, 1333) + camPos.y;
float camDirZ = 700 * sin(angle) + camPos.z;
camDir = new PVector(camDirX, camDirY, camDirZ);
camera(camPos.x, camPos.y, camPos.z, camDir.x, camDir.y, camDir.z, 0, 1, 0);
for (Planet p : planets) {
p.emmitLight();
}
ambientLight(100, 100, 100);
for (Planet p : planets) {
p.show();
}
if (!paused) {
for (Planet p : planets) {
p.update();
}
}
if (!paused) {
for (Planet b1 : planets) {
for (Planet b2 : planets) {
if (b1 != b2) {
float r = dist(b1.pos.x, b1.pos.y, b1.pos.z, b2.pos.x, b2.pos.y, b2.pos.z);
PVector p1 = new PVector(b2.pos.x, b2.pos.y, b2.pos.z);
p1 = p1.sub(b1.pos);
float a = G * ((b1.m * b2.m) / (r * r));
b1.applyForce(p1.mult(a).mult(1));
}
}
}
}
if (PlanetBeingCreated) {
if (key == 'c') {
PlanetSize += Scroll;
} else if (key == 'C') {
PlanetSize += Scroll * 10;
}
if (PlanetSize < 1) {
PlanetSize = 1;
}
float SpherePreviewSize = PlanetSize / 1.3;
distCreatePlanet = SpherePreviewSize + 100;
PVector SpherePreviewPos = camDir.copy().sub(camPos).normalize().mult(distCreatePlanet).add(camPos.copy());
pushMatrix();
noStroke();
fill(255);
translate(SpherePreviewPos.x, SpherePreviewPos.y, SpherePreviewPos.z);
sphere(SpherePreviewSize);
popMatrix();
}
Scroll = 0;
loadPixels();
pixels[OverlayY * width + OverlayX] = green;
pixels[(OverlayY + 1) * width + OverlayX] = green;
pixels[(OverlayY - 1) * width + OverlayX] = green;
pixels[OverlayY * width + (OverlayX + 1)] = green;
pixels[OverlayY * width + (OverlayX - 1)] = green;
updatePixels();
//Movement
if (keyPressed) {
if (key == 'W') {
camPos = camPos.add(camDir.copy().sub(camPos).normalize().mult(100));
camDir = camDir.add(camDir.copy().sub(camPos).normalize().mult(100));
} else if (key == 'S') {
camPos = camPos.add(camDir.copy().sub(camPos).normalize().mult(-100));
camDir = camDir.add(camDir.copy().sub(camPos).normalize().mult(-100));
} else if (key == 'w') {
camPos = camPos.add(camDir.copy().sub(camPos).normalize());
camDir = camDir.add(camDir.copy().sub(camPos).normalize());
} else if (key == 's') {
camPos = camPos.add(camDir.copy().sub(camPos).normalize().mult(-1));
camDir = camDir.add(camDir.copy().sub(camPos).normalize().mult(-1));
} else if (key == 'a') {
for (Planet p : planets) {
if (p.selected) {
PVector ForceApply = camDir.copy().sub(camPos).normalize().mult(0.5);
p.vel = p.vel.add(ForceApply);
}
}
} else if (key == 'A') {
for (Planet p : planets) {
if (p.selected) {
PVector ForceApply = camDir.copy().sub(camPos).normalize().mult(2.5);
p.vel = p.vel.add(ForceApply);
}
}
}
}
for (Planet p : Removeplanets) {
planets.remove(p);
}
Removeplanets = new ArrayList<Planet>();
}
void mouseDragged() {
if (mouseButton == LEFT) {
float dx = mouseX - pmouseX;
float dy = mouseY - pmouseY;
aXZ += dy / 1;
aYZ += dx / 1;
}
}
void keyPressed() {
if (key == 'c' || key == 'C') {
PlanetSize = 30;
PlanetBeingCreated = true;
} else if (key == 'p') {
paused = paused? false : true;
} else if (key == 'd') {
for (Planet p : planets) {
if (p.selected) {
Removeplanets.add(p);
}
}
} else if (key == 'f') {
for (Planet p : planets) {
if (p.selected) {
p.vel = new PVector(0, 0);
}
}
} else if (key == 'v') {
focusedOnPlanet = focusedOnPlanet? false : true;
}
}
void mousePressed() {
if (mouseButton == RIGHT) {
focusedOnPlanet = false;
for (Planet p : planets) {
p.selected = false;
}
PVector selectPos = camPos.copy();
boolean selectComplete = false;
for (int i = 0; (i < 100); i += 1) {
selectPos = selectPos.add(camDir.copy().sub(camPos).normalize().mult(10));
for (Planet p : planets) {
if (dist(selectPos.x, selectPos.y, selectPos.z, p.pos.x, p.pos.y, p.pos.z) < (p.m / 1.3)) {
p.selected = true;
selectComplete = true;
}
}
if (selectComplete) {
break;
}
}
}
}
void keyReleased() {
if (key == 'c') {
PVector CreatePlanetPos = camDir.copy().sub(camPos).normalize().mult(distCreatePlanet).add(camPos.copy());
planets.add(new Planet(CreatePlanetPos, PlanetSize));
PlanetBeingCreated = false;
PlanetSize = 30;
}
keyPressed = false;
}
void mouseWheel(MouseEvent event) {
Scroll = event.getCount();
}
right now the flight path renders as a single point even tough it should be many.
The array that holds the information for the points contains 100 PVectors all of which end up having the same value.