Heute Morgen hatte ich das Gefühl, ein nutzloses Programm zu schreiben, und ich endete mit dieser extremely minimal astronomic simulator in processing. MCVE-Version des Codes am Ende des Beitrags angehängt.Meine Planeten gingen verrückt - eine Java-bezogene Ausgabe
Dann habe ich einige Planeten hinzugefügt, lehne mich zurück und machte mich bereit, einige Planeten zu beobachten, die umeinander kreisen. Es stellte sich jedoch heraus, dass es ein Problem war.
Das Problem ist, zwei ursprünglich statische Planeten, die einander zu nahe kommen, neigen dazu, sich gegenseitig auf super ultra hohe Geschwindigkeit zu schleudern und sie werden beide für immer aus dem Bildschirm verschwinden. Dies ist offensichtlich gegen das Prinzip der Dynamik. Planeten tun das nicht. Ich fange an zu bezweifeln, dass etwas mit meiner Newton'schen Gesetzesimplementierung nicht stimmt. Aber manchmal funktionieren die Planeten gut, vorausgesetzt, sie halten eine "sichere" Distanz.
Wenn Sie in dieses Problem schauen wollen, habe ich zwei Setups für Sie sorgfältig aufgenommen. Die erste, fügt zwei Planeten hinzu und ist schön stabil. (Sie können dies tun, indem Sie jede Zeile auskommentieren, die 'Drei' enthält.) Sie können die zweite Zeile testen, indem Sie einfach den Standardcode eingeben. Hier werden Planeten verrückt.
Dieses Problem scheint wie ein Mysterium, dass stammt aus einer Computer-Domäne, die ich nie erforscht habe (ich bin ein Noob obwohl). Wegen meiner Haare würde ich es sehr schätzen, wenn jemand es erklären könnte.
Start of code:
PVector planetOneLocation = new PVector(300, 200);
PVector planetOneSpeed = new PVector(0, -.1);
float planetOneMass = 1;
PVector planetTwoLocation = new PVector(100, 200);
PVector planetTwoSpeed = new PVector(0, .1);
float planetTwoMass = 1;
PVector planetThreeLocation = new PVector(200, 200);
PVector planetThreeSpeed = new PVector(0, 0);
float planetThreeMass = 10;
float g = 5;
void setup() {
size(500, 500);
}
void draw() {
updatePlanetOne();
updatePlanetTwo();
updatePlanetThree();
planetOneLocation.add(planetOneSpeed);
planetTwoLocation.add(planetTwoSpeed);
planetThreeLocation.add(planetThreeSpeed);
background(0);
ellipse(planetOneLocation.x, planetOneLocation.y, 10*planetOneMass, 10*planetOneMass);
ellipse(planetTwoLocation.x, planetTwoLocation.y, 10*planetTwoMass, 10*planetTwoMass);
ellipse(planetThreeLocation.x, planetThreeLocation.y, 10*planetThreeMass, 10*planetThreeMass);
}
void updatePlanetOne() {
PVector accDir = PVector.sub(planetTwoLocation, planetOneLocation);
float a = g * planetTwoMass/(accDir.mag() * accDir.mag());
accDir.normalize();
PVector acceleration = accDir.mult(a);
planetOneSpeed.add(acceleration);
accDir = PVector.sub(planetThreeLocation, planetOneLocation);
a = g * planetThreeMass/(accDir.mag() * accDir.mag());
accDir.normalize();
acceleration = accDir.mult(a);
planetOneSpeed.add(acceleration);
}
void updatePlanetTwo() {
PVector accDir = PVector.sub(planetOneLocation, planetTwoLocation);
float a = g * planetOneMass/(accDir.mag() * accDir.mag());
accDir.normalize();
PVector acceleration = accDir.mult(a);
planetTwoSpeed.add(acceleration);
accDir = PVector.sub(planetThreeLocation, planetTwoLocation);
a = g * planetThreeMass/(accDir.mag() * accDir.mag());
accDir.normalize();
acceleration = accDir.mult(a);
planetTwoSpeed.add(acceleration);
}
void updatePlanetThree() {
PVector accDir = PVector.sub(planetOneLocation, planetThreeLocation);
float a = g * planetOneMass/(accDir.mag() * accDir.mag());
accDir.normalize();
PVector acceleration = accDir.mult(a);
planetThreeSpeed.add(acceleration);
accDir = PVector.sub(planetTwoLocation, planetThreeLocation);
a = g * planetTwoMass/(accDir.mag() * accDir.mag());
accDir.normalize();
acceleration = accDir.mult(a);
planetThreeSpeed.add(acceleration);
}
-Update: Nach einiger Mühe wechsle ich Variablen schweben zu verdoppeln. Aber meine Planeten hüpfen immer noch aus dem Bildschirm. Ich denke neben dem Double/Float-Problem gibt es tatsächlich einige Probleme mit der Auflösung. Ich habe keinen Zeitschritt definiert, der insbesondere bei hoher Geschwindigkeit zu einem ungenauen Verhalten beiträgt.
Update 2: Die Einrichtung des Zeitschritts hilft sehr. Einige Setups, die ohne Zeitschritt verrückt geworden sind, funktionieren jetzt gut. Aber solange es die Möglichkeit gibt, dass das Zentrum von zwei Planeten extrem nah ist, besteht die Möglichkeit, dass das System wieder in den Hintergrund tritt. Um dies zu lösen, wird ein besserer Integrator benötigt.
Updata 3: Als Antwort auf @ Kevin-Workman portierte ich hier seinen schönen Code, um den ursprünglichen Projektcode zu ersetzen. Derselbe dritte Planet im ursprünglichen Post wird hinzugefügt und die entsprechende Newton-Mathematik wird aktualisiert. Widersprüchlich zu seinen Tests sieht es auch dann aus, wenn mv.add(p.speed.mult(p.mass));
auskommentiert ist, der dritte Planet immer noch verrückt wird (Da ich jetzt den Demo-Code auf eine Minimal-Version geändert habe, gibt es keine solche Zeile mehr). Ich denke, der von mult()
eingeführte Fehler trägt zwar dazu bei, aber konkret spielt auch der instabile Integrator eine große Rolle.
Bitte den entsprechenden Code in die Frage selbst stellen. Niemand möchte Code durch einen Link verfolgen. – computerfreaker
Okay. Code ist beigefügt: D – shi
Sie sind sicher, dass dies Java ist? Ich bezweifle das ... –