2016-01-09 3 views
5

Ich versuche, eine Simulation eines Sonnensystems in opengl mit C zu bauen. Ich kann nicht herausfinden, wie man den Code für die Berechnung der Richtung der Kraft auf a Planet von einem anderen. Das, was ich habe bisher:berechnen Richtung der Anziehungskraft zwischen Planeten

void attraction(planet self, planet other, float *direction) 
{ 
    float d = vecDistance(self.p, other.p); 

    //calc the force of attraction 
    float f = G * ((self.mass * other.mass)/(pow(d, 2))); 

    //calc the direction of the force 
    float vectorDist[3]; 
    vecSub(self.p, other.p, vectorDist); 

    direction[0] = f*vectorDist[0]/d; 
    direction[1] = f*vectorDist[1]/d; 
    direction[2] = f*vectorDist[2]/d; 
} 



float vecDistance(float *pV1, float *pV2) 
{ 
    float fLen=0.0f; 

    if(pV1 && pV2) 
    { 
     float av[3]; 

     vecSub(pV2, pV1, av); 
     fLen=vecLength(av); 
    } 

    return fLen; 
} 


void vecSub(float *pV0, float *pV1, float *pVRes) 
{ 
    if(pV0 && pV1 && pVRes) 
    { 
     pVRes[0]=pV0[0]-pV1[0]; 
     pVRes[1]=pV0[1]-pV1[1]; 
     pVRes[2]=pV0[2]-pV1[2]; 
    } 
} 
+1

Die Berechnung der Stärke der Kraft sieht richtig aus. Ich weiß nichts über den Vektor. 'Return fx, fy, fz;' wird nicht funktionieren. 'attraction' gibt einen float zurück, nicht 3. Wo ist' vecLength' definiert und warum definieren Sie 'av' mit einer Länge von 4 statt 3? –

+0

Ich habe meinen Code geändert, aber das Problem besteht immer noch. mein Testplanet erscheint nicht auf dem Bildschirm – user3476732

+0

mein Fehler kann sonst wo aber nur nicht sicher über meine Berechnung für die Richtung – user3476732

Antwort

6

Es ist schwer, ohne Eingabedaten zu kennen, aber ich denke, Sie laufen in Gleitkommaüberlauf, weil die Werte, die Sie mit arbeiten, sind zu groß.

Zum Beispiel, wenn Sie Ihre Einheiten im SI-Einheitensystem sind, dann gilt:

venus.mass = 4.87e+24; // kg 
earth.mass = 5.98e+24; // kg 

und der Zähler in der Gleichung wird:

self.mass * other.mass == 2.91047e+49; 

einfache Genauigkeit floating-point numbers nicht 3.4e als größer sein kann +38, so wird das Massenprodukt als Unendlichkeit behandelt.

Natürlich heben sich die hohen Exponenten etwas auf, weil die Abstände auch groß sind (in der Größenordnung von 1e + 10) und die Gravitationskonstante klein ist, aber wenn das obige Produkt ein Zwischenergebnis ist, alle abhängigen Ergebnisse sind auch falsch. (Die -1.0#IND bedeutet indefinte und entspricht NaN, keine Zahl, eine ungültige Gleitkommazahl.)

Es gibt mehrere Möglichkeiten, dieses Problem zu beheben:

  • Werte verwenden, die sein können im Gleitkommaregime sicher quadriert. Zum Beispiel, wenn Sie die Massen mit der Masse der Masse normalisieren, erhalten Sie Zahlen um 1.0, die für Berechnungen sicher sein sollten. Ebenso kann eine gute Einheit für Entfernungen die astronomical unit sein.

  • Ordnen Sie den Ausdruck neu an, damit kein Überlauf von intermediären Ausdrücken auftritt. Zum Beispiel schreiben Sie statt (m1 * m2)/(d*d)(m1/d) * (m2/d).

  • Verwenden Sie double anstelle von Float. Das maximal darstellbare double ist ca. 1.8e + 308. Beachten Sie, dass dieses Problem nicht mit duoble verschwindet, es gibt Ihnen nur mehr Spielraum für den Betrieb. Für Ihr Beispiel sollten Sie jedoch gut sein.

Verwandte Themen