Söz konusu yazılımın evrimini anlatırken, toplam kinetik enerjinin sabit kaldığı esnek çarpışma varsayımını kullanacağız. Momentumun korunumu da en temel mekanik kuralı...
Tek boyutlu çarpışma
Eşit kütleli iki top doğru bir hat üstünde çarpışırsa iki topun hızı yer değiştirir. Bilardo masasından bir örnek verelim: Hareketsiz duran bir topa tam ortasından çarpan ikinci top durur ve ilk top aynı hızla harekete geçer. Şimdi bu sonuca denklemlerden ulaşalım:
v1 ve v2 topların ilk hızını göstersin. Tek boyutlu hızları modellemek için işaretli sayılar (tek boyutlu vektör) yeterli. Hız pozitif ise top eksen yönünde sağa doğru, negatif ise ters yönde sola doğru hareket ediyor.
Toplam momentum ve enerjinin sabit kaldığı tek çözüm
v'1 = v2 ve v'2 = v1 olarak bulunur.
Yani her top diğerinin ilk hızını alıyor.
Kütleler eşit değilse, işlemler biraz daha uzun sürer ve şu sonuca ulaşılır:
Aynı sonuç şöyle yazılınca hem sağlaması daha kolay olur, hem de genel formülün özel hali olarak okunabilir:
v'1 = v1 + m2 k Δv
v'2 = v2 − m1 k Δv
k = 2/(m1 + m2), Δv = (v2 − v1)
Yani, iki top arasındaki hız farkı, diğer topun kütlesi ile orantılı olarak paylaştırılır. Hafif top daha çok hız kazanır. Okuyucu bu çözümün toplam momentum ve enerjiyi değiştirmediğini kolayca sağlayabilir.
İki boyut, eşit kütleler
Daha ilginç çarpışmaları anlamak için ikinci ve üçüncü boyuta geçmek lazım. Vektör yaklaşımı kullanırsak boyut sayısı hiç önemli değil, aynı formüller geçerli. Önce iki eşit kütle ile başlayalım.
İki top dokunduğu anda merkezleri birleştirelim. Hız değişimi sadece bu doğrultuda (Δx) gerçekleşir. Buna dik olan hızlar asla değişmez. O halde ilk hızın Δx vektörüne paralel bileşeni (izdüşümü) diğer topa geçecek, dik bileşen ise ilk topta kalacaktır:
Hareketli resimdeki en önemli kare, ilk hızı ve iki bileşenini gösteriyor:
İzdüşüm hesabı lineer cebirin en temel konularından biridir:
ax = (<a, x>/<x, x>) x
(a vektörünün x üstüne izdüşümü)
Çarpışma problemine uygulayınca, iki topun hızlarının Δx üstüne izdüşümlerinin farkından şu sonuca varılır:
v'1 = v1 + P Δx
v'2 = v2 − P Δx
P = <Δv, Δx>/<Δx, Δx>
Δv = (v2 − v1), Δx = (x2 − x1)
Okuyucu bu olağanüstü basit formülü sağlamalı ve üstünde düşünmelidir. Trigonometri kullanmadan, nasıl olur da iki ve üç boyutta sonuca ulaşır? Formülün büyüsü iki vektörün iç çarpımında gizli olabilir mi?
Önemli not: Vektörlerle çalışırken kinetik enerji koordinatlarla değil, yine iç çarpımla hesaplanır. Elbette koordinat hesabıyla aynı sonuçlar bulunur, ama çok daha zor olur.
|v'1|² = |v1|² + 2P <v1, Δx> + P² |Δx|²
Genel çözüm
Çok boyutlu genel çözüm formülünü 2. referanstan alalım:
Karmaşık görünen bu çözüm şöyle yazılınca epeyce basitleşir:
v'1 = v1 + m2 k P Δx
v'2 = v2 − m1 k P Δx
k = 2/(m1 + m2), P = <Δv, Δx>/<Δx, Δx>
Δv = (v2 − v1), Δx = (x2 − x1)
Vektör yerine skalar (P = Δv/Δx) kullanırsak, bu genel formül tek boyuta indirgenir. Eşit kütleler haline indirgemek için, m ve k değerlerini silmek yeterli, çünkü mk = 1.
Yazılımın ana hatları
Çarpışan iki top b2 ve b1 olsun. Topların yeri, hızı, kütlesi:
x2 = b2.pos, x1 = b1.pos v2 = b2.vel, v1 = b1.vel m2 = b2.size, m1 = b1.size
Çarpışma sonrası hızların hesabı şöyle yapılır:
let dx = b2.pos.minus(b1.pos) // x2-x1 let dv = b2.vel.minus(b1.vel) // v2-v1 let m = b1.size + b2.size // m1+m2 let kP = (2/m)*dv.inner(dx)/dx.inner(dx) b1.vel.add(+kP*b2.size, dx) b2.vel.add(-kP*b1.size, dx)
Bu formülü uygulamadan önce, iki topun tam dokunduğuna emin olmak gerekir. Benzetim sırasında zaman sürekli akmadığı için, çarpışmayı fark ettiğimizde iki top birbirinin içine girmiş olabilir. Dokunma zamanını hesaplayıp tam o andaki koordinatları kullanmak gerekiyor.
let a = dv.inner(dv) // |Δv|² if (a < 0.0001) continue //same velocity let b = dv.inner(dx)/a // <Δv,Δx>/<Δv,Δv> let c = (dx.inner(dx) - m*m)/a //solve t² + 2b*t + c = 0 if (b*b < c) continue //no real solution if (1+2*b+c > 0) continue //solution t>1 let tt = (-b-Math.sqrt(b*b-c)) b1.update(tt); b2.update(tt)
Uygulamadaki en önemli zorluk, topların sayısı artınca ortaya çıkıyor. Aynı zaman aralığında bir top iki topa birden çarparsa, iki çarpışmayı zaman sırasında ayrı ayrı ele almak gerekiyor. Aynı aralıkta ikiden fazla çarpışma olursa basit formüller hata veriyor ve süreksiz bir hareket gözleniyor. Top sayısının girildiği kutunun rengi (beyazdan sarı ve kırmızıya) bu durumun işareti: Temel varsayımın ihlali nedeniyle benzetim doğru çalışmıyor. Top sayısını azaltmak gerekecek. (Formülün ilginç bir sonucu olarak, toplam enerjinin bu halde bile korunduğunu gözledik)
Doğrulama (validation)
Her benzetim çalışmasının doğrulanması gerekir. (Ref: Osman Balcı) Bu yazılımda iki doğrulama aracı kullandım:
1. Toplam enerji on binlerce çarpışma sonunda aynı kalıyor, o halde esnek çarpışmalar doğru modellenmiş (Dev Tools'da total() yazarak bunu görebilirsiniz)
2. Görsel doğrulama. Programın ilk sürümünde ilginç hatalar gözledik:
* toplar birbirine kenetlenip dönüyordu
* görünen topların sayısı zamanla azalıyordu
* ekranın kenarlarına takılıp kalan toplar vardı
Bunların hepsi yukarıda anlatılan hassas zaman hesabı ile düzeltildi
Referans
1. Mozilla eğitim sayfalarında uygulamanın temelini buldum (bu modelde toplar birbirinin içinden geçerken sadece renk değiştiriyor, hızları aynı kalıyor)
2. Genel anlatım ve çözüm formülü Wikipedia'da:
https://en.wikipedia.org/wiki/Elastic_collision
3. Esnek çarpışmaları vektörlerle modelleyen bir makale ve Bouncescope uygulaması:
http://www.vobarian.com/collisions/
4. Yazılım sayfası:
https://maeyler.github.io/JS/canvas/colliding