Quali metodi di simulazione fisica sono più adatti per delta veramente grandi (da ore a settimane)?
Inoltre, dovrei affrontare dei problemi combinando metodi diversi per tempi delta grandi e piccoli?
Quali metodi di simulazione fisica sono più adatti per delta veramente grandi (da ore a settimane)?
Inoltre, dovrei affrontare dei problemi combinando metodi diversi per tempi delta grandi e piccoli?
Risposte:
Probabilmente utilizzerai un'accelerazione costante per questi grandi intervalli di tempo (che potrebbero essere zero accelerazione). La derivata dell'accelerazione costante rispetto al tempo è 0. Ciò significa che non cambia rispetto al tempo, quindi non importa quanto sia grande il tuo tempo delta.
Questa piccola integrazione rispetto al tempo fornisce le equazioni di cui hai bisogno.
a = a
v = at + v0
s = .5at^2 + v0*t + s0
Dove: a = accelerazione, v = velocità, v0 = velocità iniziale, s = posizione, s0 = posizione iniziale, t = tempo
Usando questa strategia puoi usare intervalli di tempo da millisecondi a settimane se lo desideri. La combinazione di questi sarebbe curata nei parametri v0
e s0
dell'equazione.
Per gestire le collisioni dovrai implementare strategie simili a quelle utilizzate per piccoli oggetti ad alta velocità . Prima calcola la nuova posizione usando l'equazione sopra, quindi spostando tra la vecchia e la nuova posizione per tutti gli oggetti. Poiché uno di questi oggetti potrebbe essersi incrociato (minuti o giorni prima), questo può diventare molto complesso. È probabile che dal momento che hai tempi delta così grandi, si spera che tu abbia un sacco di tempo per elaborare queste potenziali collisioni.
Facciamo un esempio con la gravità.
Nella funzione seguente, supponiamo di avere variabili membro di classe per posizione e velocità. Dobbiamo aggiornarli a causa della forza di gravità ogni dt secondi.
void update( float dt )
{
acceleration = G * m / r^2;
velocity = velocity + acceleration * dt;
position = position + velocity * dt;
}
Man mano che dt
diventa sempre più piccola, la nostra simulazione diventa sempre più accurata (anche se se dt
diventa troppo piccola possiamo riscontrare errori di precisione quando si aggiungono numeri piccoli a numeri grandi).
Fondamentalmente, devi decidere il massimo che la dt
tua simulazione può gestire per ottenere risultati abbastanza buoni. E se quello dt
che arriva è troppo grande, basta semplicemente suddividere la simulazione in passaggi più piccoli, dove ogni passaggio è il massimo dt
consentito.
void update( float dt )
{
acceleration = G * m / r^2;
velocity = velocity + acceleration * dt;
position = position + velocity * dt;
}
// this is the function we call. The above function is a helper to this function.
void updateLargeDt( float dt )
{
const float timeStep = 0.1;
while( dt > timeStep )
{
update( timeStep );
dt -= timeStep ;
}
update( dt ); // update with whatever dt is left over from above
}
Quindi, con questa strategia, puoi semplicemente adattarti timeStep
a qualsiasi fedeltà ti serva (trasformalo in un secondo, minuto, ora o qualunque cosa sia necessaria per ottenere una rappresentazione accurata della fisica.
La maggior parte dei giochi tende a utilizzare il semplice metodo Euler di integrazione in avanti (ovvero, integrare la velocità nella posizione nel tempo e integrare l'accelerazione nella velocità). Sfortunatamente, il metodo Euler è adatto solo per scale temporali molto piccole e brevi tirature.
Esistono metodi più complessi che sono più precisi su scale temporali molto lunghe. Il più popolare e più facile da implementare è forse Runge-Kutte-4 . RK4 determina la posizione in futuro campionando quattro posizioni e velocità nel passato e interpolando. Tende ad essere molto più preciso del metodo Euler su scale temporali più lunghe, ma è più costoso dal punto di vista computazionale.
Ad esempio, se vuoi calcolare la fisica di un pianeta orbitante reale aggiornandolo ogni pochi giorni di tempo reale, il metodo Euler farà sparare il pianeta nello spazio dopo solo poche orbite a causa di errori numerici. RK4 generalmente manterrà il pianeta in orbita approssimativamente nella stessa forma molte migliaia di volte prima di accumulare troppi errori.
Tuttavia, implementare le collisioni in RK4 può essere molto impegnativo ...