Hangi fizik simülasyon yöntemleri gerçekten büyük delta zamanı (saatler ila haftalar) için en uygun?
Buna ek olarak, büyük ve küçük delta zamanları için farklı yöntemleri birleştirirken herhangi bir sorunla karşılaşır mıyım?
Hangi fizik simülasyon yöntemleri gerçekten büyük delta zamanı (saatler ila haftalar) için en uygun?
Buna ek olarak, büyük ve küçük delta zamanları için farklı yöntemleri birleştirirken herhangi bir sorunla karşılaşır mıyım?
Yanıtlar:
Muhtemelen bu büyük zaman aralıkları için sabit hızlanma kullanacaksınız (sıfır hızlanma olabilir). Zamana göre sabit ivmenin türevi 0'dır. Bu, zamana göre değişmediği için delta zamanınızın ne kadar büyük olduğu önemli değildir.
Zamanla ilgili bu küçük entegrasyon ihtiyacınız olan denklemleri sağlar.
a = a
v = at + v0
s = .5at^2 + v0*t + s0
Burada: a = hızlanma, v = hız, v0 = başlangıç hızı, s = konum, s0 = başlangıç konumu, t = zaman
Bu stratejiyi kullanarak, isterseniz milisaniyeden haftalara kadar süreleri kullanabilirsiniz. Onları birleştirmek v0
ves0
denklemin parametreleri parametreleri ile .
Çarpışmaları ele almak için yüksek hızlı küçük nesneler için kullanılan stratejilere benzer stratejiler uygulamanız gerekir . Önce yukarıdaki denklemi kullanarak yeni pozisyonu hesaplayın, sonra tüm nesneler için eski ve yeni pozisyon arasında süpürün. Bu nesnelerden herhangi biri birbiriyle kesişebileceğinden (dakikalar veya günler önce), bu çok karmaşık hale gelebilir. Bu kadar büyük delta zamanınız olduğundan, umarım bu potansiyel çarpışmaları işlemek için bolca zamanınız olacaktır.
Yerçekimi ile bir örnek verelim.
Aşağıdaki işlevde, konum ve hız için sınıf üyesi değişkenlerimiz olduğunu varsayın. Her dt saniyede bir yerçekimi kuvveti nedeniyle bunları güncellememiz gerekir.
void update( float dt )
{
acceleration = G * m / r^2;
velocity = velocity + acceleration * dt;
position = position + velocity * dt;
}
Gibi dt
daha küçük ve küçülür, bizim simülasyon (daha doğru alırsa rağmendt
çok küçük alır sayıda minik numaraları eklerken o zaman hassas hatalarla olabilir).
Temel olarak, dt
yeterince iyi sonuçlar almak için simülasyonunuzun kullanabileceği maksimum değere karar vermelisiniz . Ve eğer dt
gelen çok büyükse, simülasyonu daha küçük adımlara ayırın, burada her adım dt
izin verdiğiniz maksimum değerdir.
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
}
Yani bu stratejiyle, timeStep
ihtiyacınız olan her hangi bir sadakati ayarlayabilir (fiziğin doğru bir temsilini elde etmek için bir saniye, dakika, saat veya ne gerekiyorsa yapın).
Çoğu oyun basit Euler kullanma eğilimindedir ileri entegrasyon yöntemini (yani, hızı zaman içinde pozisyona entegre eder ve ivmeyi hıza entegre eder). Ne yazık ki, Euler yöntemi sadece çok küçük zaman ölçekleri ve kısa koşular için uygundur.
Çok uzun zaman ölçeklerinde daha doğru olan daha karmaşık yöntemler vardır. Uygulamanın en popüler ve en kolay yolu belki de Runge-Kutte-4'tür . RK4, geçmişte dört pozisyonu ve hızı örnekleyerek ve enterpolasyon yaparak gelecekteki pozisyonu belirler. Daha uzun zaman ölçeklerinde Euler yönteminden çok daha doğru olma eğilimindedir, ancak daha hesaplama açısından pahalıdır.
Örneğin, gerçek zamanlı bir kaç günde bir güncellenen gerçek bir yörünge gezegenin fiziğini hesaplamak istiyorsanız, Euler yöntemi, sayısal hatalar nedeniyle gezegenin sadece birkaç yörüngeden sonra uzaya fırlamasına neden olacaktır. RK4, çok fazla hata biriktirmeden önce gezegeni binlerce kez kabaca aynı şekilde yörüngede tutacaktır.
Ancak, RK4'e çarpışmalar uygulamak çok zor olabilir ...