Fizik motorunda “patlayan” veya titreyen nesneleri nasıl düzeltirim?


11

Sadece hızı değiştirmek veya bir dürtü uygulamak yerine, çakışan cisimlerin pozisyonunu (şimdilik sadece daireler) doğrudan düzelterek çarpışmaları çözen basit bir fizik motorum var. Hız, yalnızca etkiler zaten çözüldükten sonra veya entegrasyon bölümü sırasında değiştirilir.

Nesnelerin yığınlarında üst nesnelerin çok fazla baskı uyguladığı (bu örtük olarak var, algoritmada hiçbir basınç modellemesi yok) yığının altındaki nesneler üzerinde sorun yaşadım, bu da onları zeminlerden itiyor, vb.

Nesneleri y koordinatlarına göre sıralayarak bunu düzeltmek istedim, böylece çarpışmalar aşağıdan yukarıya doğru çözüldü. Ama şimdi, motor aslında hareketsiz olması gereken nesneler için garip haşhaş davranışı gösteriyor (gif'e bakın)

resim açıklamasını buraya girin

Sadece kaynak kodunu vermeden - bu ne olabilir?


5
Sonuçta, bu doğrusal bir denklem sistemini yinelemeli bir şekilde (veya kısıtlamalarınıza / koşullarınıza / vb. Bağlı olarak doğrusal olmayan bir sistem) çözmeye benzer. Her iki durumda da, bu eserleri görüyorsunuz çünkü sayısal olarak görmek için doğru olan şey: birleşme sürecinin ara durumları. Bundan kaçınmak oldukça zordur ve çok sayıda kötü hack anlamına gelebilir (her neyse, bu gerçek hayatta, moleküler düzeyde gerçekleşir ve gerçek hayatta bir şeye en iyi benzemek için sahip olduğunuz şey budur :)). Dürtü tabanlı dinamikler için çözümlerini görmek için box2d'yi incelemek muhtemelen iyidir.
teodron

@TravisG Sorunu nasıl çözdünüz? Çok basit bir fizik motoru uygulamaya çalışırken benzer bir soruna bakıyorum.
cheesus

1
@cheeesus Üzerinde çalıştığımdan bu yana bir süre geçti, ama daha küçük zaman aralıklarında daha fazla yineleme kullandığımı düşünüyorum.
TravisG

Yanıtlar:


5

Konum düzeltmeyi kullanırken bulduğum bir çözüm, birkaç yinelemeye sahip olmak ve her yinelemede gücü değiştirmek.

doPhysics();

int num_iterations = 5;
for(int iteration=0; iteration<num_iterations; ++iteration)
{
    float strength = float(iteration+1)/num_iterations;
    correctPositions(strength);
}

Dolayısıyla, ilk yineleme 1 / num_iterations gücüne ve son 1 1 gücüne sahiptir. Bu, simülasyonlarımı sabit bir kuvvete sahip aynı sayıda yinelemeyi kullanmaktan daha pürüzsüz ve daha kararlı hale getirir.


2
Güzel bir çözüm, ama neden işe yarıyor?
Gustavo Maciel

5

Sorununuz, bedenleriniz için "dinlenme" durumuna sahip olmamanızdır. Herhangi bir fizik sistemi, kinetik, termal ve benzeri gibi bir miktar enerjiye sahiptir. Gerçekte, katı nesne biraz deforme olur ve ölçülemese de bazı kinetik enerjiyi ısıya dönüştürür. Ayrıca, gerçekte tamamen sağlam bir nesne diye bir şeyin olmadığını da belirtmek gerekir. Elmas gibi yoğun malzemeler bile atomlar arasında boşluk bırakarak atomik yapıya esnetilmesini ve kinetik enerjiyi emmesini sağlar.

Bunu alakalı hale getirmek için, istirahat cisimleri, yürürlükteki tek kuvvetlerin "normal kuvvet" olduğu, yani cisimlerin birbirinden yüzmesini engelleyen kuvvet olduğu bir durumdadır. Bu normal kuvvetin büyüklüğü, nesnelerin yoğunluğu ve birbirlerine ne kadar nüfuz ettikleri ile orantılıdır.

Fizik motorları bu değere "eğim" adını verir.

İşte püf noktası: Eğimi hesaplayın ve cisimlerin konumunu düzeltin ve iki cismin göreceli hızına bağlı olarak normal kuvveti uygulayın. vücutların kendilerinin güncellenmesi sırasında, her bir vücudun kinetik enerjisini hesaplayın. Minimum değerin altındaysa, vücuda yeterli büyüklükte bir kuvvet uygulanana kadar uyutun. (genellikle minimum değerin iki katı).


0

Neden onlara "yapışkan" bir yüzey eklemiyorlar ve yavaş yavaş dinlenme pozisyonuna yapışıyorlar ve başka bir nesne ona vurduğunda içine biraz enerji aktarıyor, ancak yapışkan yüzey bu enerjinin bir kısmını kaybetmesine ve durmasına neden olacak dinlenme pozisyonunda. gif'in sürtünmesi yokmuş gibi görünüyor.

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.