Planetenlaufbahn berechnen

lano

Well-Known Member
c-b Experte
#1
Moin.

Ich hab ein Wuerfel. 100x100x100
in der Mitte sitzt eine Sonne.
Jetzt hab ich einen Planeten der im radius 10 um die Sonne kreist.
Jetzt frag ich mich wie ich die Position nach Uhrzeit berechnen kann.
Am 1.1.1970 0:00 oder so war der Planet bei 50x50x60
Er braucht um die Sonne 24h. Wie kann ich bestimmen wo der Planet heute ist?
Viel wichtiger aber, wie kreist er denn? flach rechts links um die Sonne oder oben unten?
Wie geb ich denn sowas an ?
 

German

Well-Known Member
c-b Experte
#2
Wie kann ich bestimmen wo der Planet heute ist?
Gar nicht. Es gibt immer noch unendlich viele Möglichkeiten wie der Planet zu diesem Punkt gekommen ist. Selbst wenn du die Bahn kennst weißt du noch nicht in welche Richtung er sich bewegt. Du brauchst einen Richtungsvektor 90° zum Radius zu deinem Punkt. Alternativ zumindest irgendeinen weiteren Punkt (für die Bahn) mit Zeitangabe (für die Richtung) der dem ersten Punkt nicht genau gegenüberliegen darf, sonst wird das wieder nix mit der Richtung.
 

dominikb

Well-Known Member
#4
Viel wichtiger aber, wie kreist er denn? flach rechts links um die Sonne oder oben unten?
Wie geb ich denn sowas an ?
Das kannst du mit der Bahnneigung angeben. Wenn du die Position nur anhand der Umlaufdauer und des Richtungsvektors ermitteln möchtest, müsste es sich eigentlich um eine Kreisbahn mit der Exzentrizität 0 handeln, weil sich der Planet sonst mit nicht-konstanter Geschwindigkeit bewegt hat (siehe 2. Keplersches Gesetz).
 

lano

Well-Known Member
c-b Experte
#5
Du brauchst einen Richtungsvektor 90° zum Radius zu deinem Punkt.
Kapier ich immer noch nicht.

Oh, so technisch. MAl sehn ob ich das nachvollziehen kann.

Ahh, das ist doll. Das reicht.

Wenn du die Position nur anhand der Umlaufdauer und des Richtungsvektors ermitteln möchtest, müsste es sich eigentlich um eine Kreisbahn mit der Exzentrizität 0 handeln, weil sich der Planet sonst mit nicht-konstanter Geschwindigkeit bewegt hat (siehe 2. Keplersches Gesetz).
Ja sind alles ganz Umlaufbahn berechnungsfreundliche Planeten :D
 

German

Well-Known Member
c-b Experte
#6
Naja, die Bahnneigung sagt noch nix über die Richtung aus. Aber erst mal kleine Brötchen backen ...

kreisbahn.png
Ist halt einer der einfachsten Fälle der mit deiner Vorgabe übereinstimmt. Bahn ist parallel zur x-z-Ebene. Die 3600 sind Sekunden pro Tag. Das t demzufolge auch in Sekunden. Das Datum kürzt sich wegen der 24h Umlaufzeit komplett raus. Bleibt die Uhrzeit.
EDIT: Ich hab Tinte gesoffen. Alles was ich über 3600 geschrieben habe, sind natürlich 86400.

Wie auch immer, in C rechnest du vermutlich mit time_t. Die time() Funktion gibt dir die Anzahl Sekunden seit 1.1.70. Diese Zahl mod Umlaufzeit, ergibt t und fertig. Immer schön bei UTC bleiben, nicht dass dein Planet im März und Oktober Sprünge macht, wie der kleine Zeiger der Uhr.

Für geneigte Bahnen ist das im Grunde auch nicht anders, die Berechnungen sind halt etwas komplizierter. Müsste ich mich selbst erst reinlesen.
http://wwwex.physik.uni-ulm.de/lehre/krm-2008-2009/node13.html
 
Zuletzt bearbeitet:

lord_haffi

Well-Known Member
c-b Experte
#7
Für geneigte Bahnen ist das im Grunde auch nicht anders, die Berechnungen sind halt etwas komplizierter
Ach, wo denkst du hin. Den Computer kannst du auch den parallelen Fall rechnen lassen und hinterher nur 'ne Transformation (z.B. Rotation) der Koordinaten drauf rechnen.

Also zur Physik: Erstmal kannst du es nur analytisch lösen, wenn du nur 2 Körper hast. In dem Fall einfach die Keplerschen Gesetze nehmen, die lösen die Differentialgleichungen für das 2-Körper-Problem.
Ab 3 Körpern wird's tricky, da kannst du nur noch numerisch rangehen. Am genauesten ist, du stellst die Bewegungsgleichungen auf und löst die DGLs z.B. mit dem Runge-Kutta-Verfahren (in 4. Ordnung ist schon völlig ausreichend, 2. Ordnung liefert auch schon gute Ergebnisse). Etwas performanter aber ungenauer ist das Euler-Verfahren. Natürlich kann man auch über die Newton'sche Mechanik gehen.

Java:
package newtoniangravity.simulation;

import java.util.concurrent.ArrayBlockingQueue;

/**
*
* @author lord_haffi
*/
public class Simulator implements Runnable{
    public final ArrayBlockingQueue<MassPoint[]> frameCache;
    private MassPoint[] lastFrame;
    private final World world;
    // *************
    //Sets the time-intervall between two "frames" of the masses in the world
    private int t;
    //Time of last adding to the queue
    //private long lastAddTime = -1;
    private boolean interrupt = false;
   
    public Simulator(int queueCap, int time, World world){
        frameCache = new ArrayBlockingQueue<>(queueCap);
        this.world = world;
        this.t = time;
        lastFrame = world.massPointsStart.toArray(lastFrame);
    }
    public MassPoint[] calcNewFrame(){
        double curForceFac;
        MassPoint[] nextFrame = new MassPoint[lastFrame.length];
       
        for(int i=0; i<lastFrame.length; i++){
            MassPoint massI = lastFrame[i];
           
            for(int j=i+1; j<lastFrame.length; j++){
                MassPoint massJ = lastFrame[j];
                double[] del = massI.differVectorAndDistance(massJ);
                curForceFac = world.gravConst*massI.mass()*massJ.mass()/Math.pow(del[del.length-1], 3);
               
                for(int n=0; n<world.dim; n++){
                    if(j==1){
                        nextFrame[i] = new MassPoint(massI.mass(), world.dim);
                        nextFrame[i].r()[n] = massI.r()[n]+massI.v()[n]*t-curForceFac*del[n]/massI.mass()/2*t*t;
                        nextFrame[i].v()[n] = massI.v()[n]-curForceFac*del[n]/massI.mass()*t;
                    }else{
                        nextFrame[i].r()[n] -= curForceFac*del[n]/massI.mass()/2*t*t;
                        nextFrame[i].v()[n] -= curForceFac*del[n]/massI.mass()*t;
                    }
                    if(i==0){
                        nextFrame[j] = new MassPoint(massJ.mass(), world.dim);
                        nextFrame[j].r()[n] = massJ.r()[n]+massJ.v()[n]*t+curForceFac*del[n]/massJ.mass()/2*t*t;
                        nextFrame[j].v()[n] = massJ.v()[n]+curForceFac*del[n]/massJ.mass()*t;
                    }else{
                        nextFrame[j].r()[n] += curForceFac*del[n]/massJ.mass()/2*t*t;
                        nextFrame[j].v()[n] += curForceFac*del[n]/massJ.mass()*t;
                    }
                }
            }
           
        }
        return nextFrame;
    }

    @Override
    public void run() {
        while(!interrupt){
            try {
                lastFrame = calcNewFrame();
                frameCache.put(lastFrame);
                //lastAddTime = System.currentTimeMillis();
            } catch (InterruptedException ex) {
                ex.printStackTrace();
                interrupt = true;
            }
        }
    }
    public void interrupt(){
        interrupt = true;
    }
}
Java:
package newtoniangravity.simulation;

/**
*
* @author lord_haffi
*/
public class MassPoint {
    private double mass;
    //The location of the mass: {x, y, z}
    private double[] r;
    //The velocity of the mass: {vx, vy, vz}
    private double[] v;
    public final int dim;
   
    public MassPoint(double mass, double x, double y, double z, double vx, double vy, double vz){
        if(mass <= 0)
            throw new IllegalArgumentException("Mass has to be greater than 0.");
        this.mass = mass;
        this.dim = 3;
        this.r = new double[]{x, y, z};
        this.v = new double[]{vx, vy, vz};
    }
    public MassPoint(double mass, double[] r, double[] v){
        if(mass <= 0)
            throw new IllegalArgumentException("Mass has to be greater than 0.");
        this.mass = mass;
        if(r.length != v.length)
            throw new IllegalArgumentException("The dimensions of the r- and v-vector are not equal.");
        this.r = r;
        this.v = v;
        this.dim = r.length;
    }
    public MassPoint(double mass, int dim){
        this(mass, new double[dim], new double[dim]);
    }
   
    public double[] r(){
        return r;
    }
    public double[] v(){
        return v;
    }
    public double mass(){
        return mass;
    }
   
    public void setMass(double m){
        if(m > 0)
            this.mass = m;
        else
            throw new IllegalArgumentException("Mass has to be greater than 0.");
    }
   
    public double[] differVectorAndDistance(MassPoint m){
        if(dim != m.dim)
            throw new IllegalArgumentException("The mass points have different dimensions");
        double[] ret = new double[dim+1];
        double dist = 0;
        for(int n=0; n<dim; n++){
            ret[n] = r[n]-m.r[n];
            dist += ret[n]*ret[n];
        }
        ret[ret.length-1] = Math.sqrt(dist);
        return ret;
    }
    /**
     * Creates a deep-copy of this MassPoint.
     */
    @Override
    public Object clone(){
        /*double[] clonedR = new double[r.length], clonedV = new double[v.length];
        for(int i=0; i<r.length; i++){
            clonedR[i] = (double)r[i].clone();
            clonedV[i] = (double)v[i].clone();
        }*/
        return new MassPoint(mass, r, v);
    }
}
Java:
package newtoniangravity.simulation;

import java.util.Vector;

/**
*
* @author lord_haffi
*/
public class World {
    public static final double DEFAULT_GRAV_CONST = 6.67408E-11;
    //start-configuration
    public final Vector<MassPoint> massPointsStart/*, massPoints*/;
    public final double gravConst;
    public final int dim;
   
    public World(){
        this(3, World.DEFAULT_GRAV_CONST, 3);
    }
    public World(int massCap){
        this(massCap, World.DEFAULT_GRAV_CONST, 3);
    }
    public World(int massCap, double gravConst, int dimension){
        massPointsStart = new Vector<MassPoint>(massCap){
            @Override
            public boolean add(MassPoint m){
                return m.dim != dim ? false : super.add(m);
            }
        };
        //massPoints = new Vector(start.capacity());
        //int dim = start.firstElement().r().length;
        this.dim = dimension;
        /*for(MassPoint mass : start){
            massPoints.add((MassPoint)mass.clone());
        }*/
        this.gravConst = gravConst;
    }
   
    /*public Vector<MassPoint> masses(){
        return massPoints;
    }*/
}
Vielleicht kannst du damit ja was anfangen...
 

lano

Well-Known Member
c-b Experte
#8
Immer schön bei UTC bleiben, nicht dass dein Planet im März und Oktober Sprünge macht, wie der kleine Zeiger der Uhr.
Waere was fuer, die Dimension die es nicht gibt.

Aber erst mal kleine Brötchen backen ...
Cool. genau so eins wollt ich mir auch malen. Da hab ich das besser vor Augen. Kann mir da bei gelegenheit mal einer erklaeren wie man mit gimp nen kreis malt?

Müsste ich mich selbst erst reinlesen.
Der Link sieht gut aus. Hab erst gedacht ist chinesisch, weil so viel untereinander steht...
Ich guck mal was sich da machen laesst.
 
Oben