2016-01-09 17 views
5

Sto provando a costruire una simulazione di un sistema solare in opengl usando C. Non riesco a capire come scrivere il codice per calcolare la direzione della forza esercitata su un pianeta da un altro. Questo quello che ho finora:calcolare la direzione della forza di attrazione tra i pianeti

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

Il calcolo della grandezza della forza sembra corretto. Non so del vettore. 'return fx, fy, fz;' non funzionerà. 'attraction' restituisce un float, non 3. Dove è definito' vecLength' e perché stai definendo 'av' con una lunghezza di 4 invece di 3? –

+0

ho modificato il mio codice ma il problema persiste ancora. il mio pianeta test non appare sullo schermo – user3476732

+0

il mio errore potrebbe trovarsi altrove, ma non sono sicuro del mio calcolo per la direzione – user3476732

risposta

6

E 'difficile sapere senza dati di input, ma credo che si esegue in virgola mobile di overflow, in quanto i valori si opera con sono troppo grandi.

Ad esempio se le unità sono nel sistema di unità SI, allora:

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

e il numeratore nell'equazione diventa:

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

precisione singola floating-point numbers non può essere superiore a 3.4E +38, quindi il prodotto di massa viene trattato come infinito.

Ovviamente gli alti esponenti si annullano a vicenda, poiché le distanze sono anche grandi (dell'ordine di 1e + 10) e la costante gravitazionale è piccola, ma se il prodotto sopra è un risultato intemediario, tutti i risultati dipendenti sono anche sbagliati. (Il -1.0#IND significa indefinte corrisponde a NaN, non un numero, un numero a virgola mobile non valido.)

Esistono diversi modi per risolvere questo:

  • Usa valori che possono essere perfettamente al sicuro nel regime a virgola mobile. Ad esempio, se normalizzi le masse con la massa della terra, ottieni dei numeri intorno a 1,0, su cui dovresti fare dei calcoli sicuri. Allo stesso modo, una buona unità per le distanze potrebbe essere il astronomical unit.

  • Riorganizzare l'espressione in modo da non ottenere l'overflow delle espressioni intermedie. Ad esempio invece di (m1 * m2)/(d*d), scrivere (m1/d) * (m2/d).

  • Utilizzare double anziché float. Il massimo rappresentabile double è di ca. 1.8E + 308. Nota che questo problema non va via con duoble, ti dà solo più spazio per funzionare. Per il tuo esempio, dovresti essere buono, però.