Neden birikim üzerine entegre olmalısınız?


14

Ben DIY fiziği öğrenmek başladım ve ben en temel düzeyde entegrasyonu uygulanması hakkında soru (yani bu var değil bir Euler RK4 vs soru).

Karşılaştığım neredeyse her örnek integrate(), son güncellemeden bu yana zaman aşımını alan ve son güncellemeden bu yana hızlandırmayı (ve / veya hız ve / veya konum) güncelleyen bazı işlevlere sahip.

En basit biçimde: position += velocity * deltaTime

Ancak, bir işlevi değiştirerek kolayca elde edilebildiğinde neden bu şekilde biriktiğini anlamıyorum . Örneğin: getPosition = makeNewFunction()imzası olan bir şeyi döndürebilen Time -> Positionve bu işlevin iç işleyişi uygun matematiksel formülle üretilir.

Bu şekilde, birikim olmaz ... pozisyonun ne zaman alınması gerektiğine göre, o zamana kadar o fonksiyonu çağırır.

Acemi anlayışım, bunun birikimden kaynaklanan hataları da önleyeceğidir ... peki bu neden çalışmıyor, neyi kaçırıyorum?

(I FWIW did o da aynı anda birkaç şey deniyor olsa birlikte bu fikir-kavramının temel bir kanıt koymak o en temiz örnek değil bu yüzden: https://github.com/dakom/ball-bounce-frp )

DÜZENLEME 1: açıklamalarda belirtildiği gibi, ben olduğunu işaret etmek muhtemelen önemli değil henüz hızlanmayı değiştirerek veya pislik ve sürekli ivme daha yüksek dereceden entegrasyon gerektiren diğer şeylerle uğraşan öğrendik.

DÜZENLEME 2: Burada fikir bazı temel örnek kod ve sözde JavaScript sözdizimi - nota getKinematicPositionedilir kısmen uygulanan bu sadece Zaman yeni bir fonksiyon dönüyor böylece -> Pozisyon:

Ben burada duruyorum ama getVelocitysanırım başka bir şey olabilir ...

getKinematicPosition = initialVelocity => acceleration => time => 
  ((.5 *acceleration) * (time * time)) + (initialVelocity * time);

getPosition = getKinematicPosition ([0,0,0]) (GRAVITY);

onTick = totalTime => {
   position = getPosition (totalTime);
   onCollision = () => {
     getPosition = changeTheFunction(totalTime);
     //changeTheFunction uses totalTime to base updates from 0
     //it could use getKinematicPosition or something else entirely
   }
}

1
Eğer sabit bir hız / hızlanmaya sahip değilseniz fonksiyonunuz ne yapardı?
Linaith

Hiç bir fikrim yok! : D Sebep buysa - örneğin henüz hızlanmayı değiştiremedim, bunun cevap olarak nerede kırılacağına dair daha kapsamlı bir açıklamayı takdir ediyorum (aksi takdirde bu fonksiyonel yola inip çıkmaz bir noktaya vurabilirim) !)
davidkomer

6
Nesneniz sadece bir daire içinde dönüyorsa, o zaman emin olun ... oyuncunun ittiği bir kutu olduğunda ne olacak? GetPosition'ı çağırdığınızda (şimdi + 100), oyuncunun ne zaman itmeyi bırakacağını bilmek geleceği öngörüyor mu? GetPosition (şimdi-1000) dediğinizde geçmişi hatırlaması gerekiyor mu?
user253751

Yanıtlar:


34

... bu işlevin iç çalışmaları uygun matematiksel formülle üretilir ...

Bu, bazı sorun sınıfları için işe yarayacaktır ve aranacak anahtar ifade, kapalı formlu bir çözümdür. Örneğin, Kerbal Uzay Programında, yörüngedeki bir uzay aracının hareketi bu şekilde hesaplanır. Ne yazık ki, önemsiz olmayan sorunların çoğu (örneğin, bahsedilen uzay aracının atmosferik yeniden girmesi) bilinen bir kapalı form çözümüne sahip değildir. Böylece matematiksel olarak daha basit sayısal yaklaşımlara duyulan ihtiyaç (yani integrate()zamanla).


Ahh ... harika! Bir dakikanız varsa - bu fonksiyonel yaklaşımı hedeflemeyi ne düşünüyorsunuz ve nasıl çalıştıracağımı anlayamıyorsam (örneğin kapalı olmayan bir form sorunuyla uğraşıyorsam veya Bunu nasıl bir hale getireceğimi bilemiyorum)? Ben gibi o matematik 1 uyuyor beri fonksiyonları üretme fikri: 1 - ama her zaman kaçınılmaz bir çıkmaz çarptı edeceğiz eğer olmayabilir yetmeyecek o ...
davidkomer

8
@davidkomer Neden fonksiyon üretmeye devam etmek istiyorsun? Bunu çekebilirseniz, tüm yörüngeyi önceden hesaplayabilir ve kaydedebilirsiniz! Tabii ki, insanlar bunu zaten yapıyor: buna animasyon deniyor ve inceliklerden pay alıyor.
Joker_vD

İşlevler çalışma zamanı dinamiklerine göre değişir ... örneğin FRP top zıplamasına bakın
davidkomer

Aslında, rastgele hareket eden / kullanıcı tarafından kontrol edilen hareketli nesneler ile pong gibi bir şey olmak için bu örneği güncellemem gerekecek ...
davidkomer

10

Yaklaşımınızdaki sorun , nesnenizin bir geçmişinin olmamasıdır . Bir yöne hareket ederseniz konumu hesaplayabilirsiniz, ancak bir şeye çarpıp geri sıçrarsanız ne olur?
Bilinen son konumunuzdan birikirseniz, etkiyi halledebilir ve oradan devam edebilirsiniz. En baştan hesaplamaya çalışırsanız, etkiyi her seferinde yeniden hesaplamanız veya yeni başlangıç ​​konumu olarak ayarlamanız gerekir.

Örneğin bana bir yarış oyunu hatırlattı. (Pozisyonun fizik motoru tarafından kontrol edilip edilmeyeceğini bilmiyorum, ama açıklamanın harika olduğunu düşünüyorum)
Arabanızla giderseniz hızlanıp yavaşlayabilirsiniz. Arabanızın hız profilinin bugüne kadar nasıl göründüğünü bilmeden konumunuzu hesaplayamazsınız. Mesafe birikimi, başlangıçtan bugüne kadar her karede sahip olduğunuz hızı depolamaktan çok daha kolaydır.

Yasal Uyarı: Şimdiye kadar oyun fiziği yazmadım, sorunu tam da böyle görüyorum.

Düzenleme:
Bu diyagramda değerlerin zaman içinde nasıl değiştiğini görebilirsiniz.
kırmızı = hızlanma (hızlanmadan hızlanmaya kadar)
yeşil = hız (başlangıcından durdurmaya)
mavi = gittiğiniz yol.

Toplam hız, başlangıç ​​noktanızdan gerçek lojmanınıza olan ivmenin integralidir. (Çizgi ve eksen arasındaki alan)
Yol hızınızın ayrılmaz bir parçasıdır.
Hızlanmanız için değerleri biliyorsanız, diğer değerleri hesaplayabilirsiniz. Ama eğer yanılmıyorsam PC'lerde birikim ile hesaplanan integraller vardır. Ve tüm hızlanma değerlerinin depolanması çok daha fazla yük.
Ayrıca muhtemelen her kareyi hesaplamak için çok fazla.

hızlanma / hız / yol-zaman diyagramı

Biliyorum, boya becerilerim harika. ;)

Edit 2:
Bu örnek doğrusal hareket içindir. Geçiş yönü bunu daha da zorlaştırır.


"veya yeni başlangıç ​​konumu olarak ayarlayın." - evet, ama bununla ilgili bir sorun görmüyorum :) Re: araba örneği ... Bunun başarısız olduğunu sezgisel olarak anlamak için böyle daha karmaşık bir şeyle oynamaya başlamam gereken güçlü bir his alıyorum .. .
davidkomer

yeni bir pozisyon belirlemek muhtemelen sorun değil. Araba bölümünü düzenledim
Linaith

1
Bir araba oyununda hızlanmanın daha da karmaşık olacağını düşünüyorum. Muhtemelen sıçramalar ve ani artışlar olacaktır ve bu hıza bağlı olabilir. (Örneğin, otomobil en yüksek hıza yaklaştıkça ivme 0'a düşer.)
jpmc26

3
@davidkomer bir araba ile bile uğraşmayın (istemiyorsanız), temel bir platform yapacaktır. Super Mario Bros'ta mario.getPosition (Time) nasıl çalışır?
user253751

8

Ancak, bir işlevi değiştirerek kolayca elde edilebildiğinde neden bu şekilde biriktiğini anlamıyorum. Örneğin: Time -> Position imzası olan bir şey döndürebilen getPosition = makeNewFunction () yöntemi ve bu işlevin iç çalışması uygun matematiksel formülle oluşturulur.

Yapabilirsin!

Analitik veya kapalı bir form çözeltisi kullanılarak çağrılır . Zaman içinde biriken yuvarlama hataları mevcut olmadığından, daha doğru olma avantajı vardır.

Ancak, bu ve sadece böyle bir kapalı formu önceden biliyorsanız , çalışır . Oyunlar için, durum genellikle böyle değildir.

Oyuncu hareketi düzensizdir ve önceden hesaplanmış bazı fonksiyonlara konamaz. Oyuncu hızını ve yönünü oldukça sık değiştirebilir ve değiştirir.

NPC'ler potansiyel olarak kapalı form çözümlerini kullanabilirler ve aslında bazen kullanırlar. Bununla birlikte, bunun başka dezavantajları vardır. Basit bir yarış oyunu düşünün. Aracınız başka bir araçla her çarpıştığında, işlevinizi değiştirmeniz gerekir. Belki araba yeraltına bağlı olarak daha hızlı hareket eder. Daha sonra böyle bir kapalı form çözümü bulmak oldukça zor olacaktır. Aslında, böyle bir kapalı formun bulunmasının imkansız veya çok karmaşık olduğu, sadece mümkün olmadığı muhtemelen daha fazla vaka vardır.

Kapalı form çözümü kullanmanın harika bir örneği Kerbal Uzay Programı'dır. Roket yörüngede olduğu ve itme altında olmadığı anda KSP onu "raylara" koyabilir. Yörüngeler iki gövdeli sistemde önceden belirlenir ve periyodiktir. Roket daha fazla itme uygulamadığı sürece, roketin nerede olacağını zaten biliyorsunuz ve basitçe çağırabilirsiniz getPositionAtTime(t)(tam olarak adlandırılmamış, ancak fikri anlıyorsunuz).

Ancak pratikte, sadece adım adım entegrasyonu kullanmak genellikle çok daha pratiktir. Ancak, kapalı formlu bir çözümün bulunduğu ve hesaplanması kolay bir durum gördüğünüzde, bunun için gidin! Kullanmamak için hiçbir sebep yok .

Örneğin, karakteriniz bir topu hedefliyorsa, kapalı top çözümünü kullanarak topun tahmin edilen çarpma noktasını kolayca gösterebilirsiniz. Ve eğer oyununuz top topunun değişmesine izin vermiyorsa (örneğin rüzgar yok), top topunu hareket ettirmek için bile kullanabilirsiniz. Top topunuzun yoluna çıkan engellere özel dikkat etmeniz gerektiğini unutmayın.

Birçok benzer durum var. Yuvarlak tabanlı bir oyun inşa ediyorsanız, bir RTS oyunu oluştururken o zaman çok daha kapalı formda çözümler olabilir, çünkü tüm parametreleri önceden biliyorsunuz ve değişmediklerini kesin olarak söyleyebiliriz (hiçbir şey aniden hareket etmez) örneğin, bu yola).

Kademeli entegrasyonun sayısal yanlışlıklarıyla mücadele için teknikler olduğuna dikkat edin. Örneğin, biriken hatayı takip edebilir ve hatayı kontrol altında tutmak için düzeltici bir terim uygulayabilirsiniz, örneğin Kahan Summation


8

Sadece basit bir zıplayan top durumunda, kapalı form çözümleri bulmak kolaydır. Bununla birlikte, daha karmaşık sistemler bir Adi Diferansiyel Denklemin (ODE) çözülmesini gerektirir. En basit durumlar dışında tümünü işlemek için sayısal çözücüler gerekir.

Gerçekten iki sayısal ODE çözücü sınıfı vardır: açık ve kapalı. Açık çözücüler bir sonraki durumunuz için kapalı form yaklaşımı sağlarken, örtülü çözücüler bunun için bir denklem çözmeyi gerektirir. Zıplayan topunuz için tarif ettiğiniz şey, bilseniz de bilmeseniz de, örtük bir ODE çözücüdür!

Örtük çözücüler, çok daha büyük zaman adımlarını kullanabilme avantajına sahiptir. Zıplayan top algoritmanız için, zaman testiniz en azından bir sonraki çarpışmaya kadar olan süre kadar büyük olabilir (bu da işlevinizi değiştirir). Bu programınızın daha hızlı çalışmasını sağlayabilir. Bununla birlikte, genel olarak, ilgilendiğimiz ODE'lere her zaman iyi örtülü çözümler bulamıyoruz. Yapamadığımızda, açık entegrasyona geri dönüyoruz.

Açık entegrasyonla gördüğüm en büyük avantaj, gotcha'ların iyi bilinmesidir. 60'lardan herhangi bir ders kitabını açabilir ve belirli entegrasyon teknikleriyle ortaya çıkan küçük tuhaflıklar hakkında bilmeniz gereken her şeyi okuyabilirsiniz. Böylece, bir geliştirici bu becerileri bir kez öğrenir ve bir daha asla öğrenmeleri gerekmez. Örtük bir entegrasyon yapıyorsanız, her kullanım durumu biraz farklıdır ve biraz farklı gotcha'lar vardır. Öğrendiklerinizi bir görevden diğerine uygulamak biraz daha zor.


1

konum (t) = v (t) * t

sadece pos (0) = 0 ve v (t) = k ise çalışır

başlangıç ​​durumu ve tüm hız fonksiyonu hakkında bilgi sahibi olmadan pozisyonu zamanla ilişkilendiremezsiniz, bu nedenle denklem integralin bir yaklaşımıdır.

pos (t) = v (t) dt'nin 0'dan t'ye integrali

DÜZENLE _________

Yorum başına küçük bir kanıt var (poz (0) = 0 varsayarak)

v (t) = 4 olsun

eqn 1: konum (t) = 4 * t (doğru)

eqn 2: poz (t) = c + 4 * t, 0'dan t = 4 * t'ye (doğru)

v (t) = 2 * t olsun

eqn 1: konum (t) = 2 * t ^ 2 (yanlış)

eqn 2: poz (t) = c + t ^ 2 0'dan t = t ^ 2'ye (doğru)

Denkleminizin zaten sabit hızlanmayı etkilediğini eklemeliyim (yani denkleminiz eqn 2'dir, burada v (t) = v0 + a * t ve entegrasyon sınırları t0 ve t'dir), bu nedenle denkleminiz güncellediğiniz sürece çalışmalıdır. başlangıç ​​konumu, başlangıç ​​hızı ve hızlanma sabit kalır.

EDIT2 ________

Ayrıca, başlangıç ​​pozisyonu, ilk hız, ilk hızlanma ve sabit sarsıntı ile pozisyon hesaplayabileceğinizi de eklemeliyim. Başka bir deyişle, hız, sarsıntı, sonra gelen her şey, vb, vb. Türevlerine ayırarak konumu ve zamanı temsil eden eqn 2'ye dayalı bir işlev oluşturabilirsiniz, ancak sadece v (t) bu şekilde modellenebilir. Eğer v (t) sadece hız, ivme, sabit sarsıntı, vb. İle modellenemiyorsa, zıplayan, hava direnci, rüzgar vb. .


sabit. sadece v (t) 'nin zaman içinde
değişmemesi

Ben bununla oturup neden doğru çalışacağım ... şimdilik upvoting :) Bir şeylerin değişmesi durumunda soruya bir kod örneği yayınladım
davidkomer

sorun değil, daha iyi kelimelerle tekrar güncellendi :)
Kyy13
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.