SORU
6 Aralık 2008, CUMARTESİ


Topu topu Çarpışma Algılama ve İşleme

Yığın Taşması toplumun yardımıyla basit ama eğlenceli güzel bir fizik simülatörü yazdım.

alt text

Tıklatın ve Fare topu başlatmak için sürükleyin. Etrafında dönen ve sonunda üzerinde durur "". kat

Eklemek istiyorum bir sonraki büyük özelliği top çarpışma için Top. Topun hareketi x ve y hız vektörü ayrılır. Yerçekimi (y vektörü her adım küçük azaltma), sürtünme var (her iki vektörün bir duvar ile her çarpışma küçük bir azalma var. Topları gerçekten etrafında şaşırtıcı derecede gerçekçi bir şekilde hareket ettirin.

Benim sorum iki bölümden oluşuyor sanırım

  1. Top çarpışma topu ortaya çıkarmanın en iyi yöntemi nedir?
    Sadece her topun üzerinde dolaşır ve eğer yarıçap ile çakışıyor diye her gelen topu kontrol eden(n^2) Ey bir döngü var mı?
  2. Denklemler I çarpışmalar topu topu işlemek için ne kullanıyorsunuz? Fizik 101
    Nasıl iki top hızına etkisi x/y vektörleri mu? İki top kafasını ortaya çıkan yönü nedir? Nasıl her top için bu başvurabilirim?

alt text

Bu çarpışma algılama işleme "duvar" ve elde edilen vektör değişiklikleri kolaydı ama topu topu ile daha fazla komplikasyon görüyorum çarpışmalar. Duvarlar ile ben sadece uygun x-olumsuz ya da doğru yöne gideceğini vektör ve y vardı. Topları bu şekilde olduğunu sanmıyorum.

Şimdi de tüm topları aynı kitle şimdi, ama gelecekte bu değişebilir mükemmel elastik çarpışma için sorun yok için basitlik. hemen bazı açıklamalar:

Birisi, şimdiye kadar yaptığım simülatörü ile oynamak istiyor6* *kaynak yükledim(EDİT: güncelleştirilmiş kaynak bakınız).


Edit: yararlı . bulduğum Kaynaklar

Vektörler ile 2d Top fiziği: 2-Dimensional Collisions Without Trigonometry.pdf
2d Top çarpışma algılama örnek: Adding Collision Detection


Başarı!

Top çarpışma algılama ve tepki harika çalışıyor!

İlgili kod:

Çarpışma Algılama:

for (int i = 0; i < ballCount; i  )  
{  
    for (int j = i   1; j < ballCount; j  )  
    {  
        if (balls[i].colliding(balls[j]))  
        {
            balls[i].resolveCollision(balls[j]);
        }
    }
}

Bu top ama atlamak her gereksiz bakarsa eğer top 1 top çarpan olmadığını kontrol etmek varsa (2 top 2 top 1 ile çarpıştığında olmadığını kontrol etmek gerekmez. çarpışmalarını kontrol eder Ayrıca, kendisi ile çarpışmaları için kontrol etme) atlar.

Sonra, top benim sınıfımda benim çarpışması var() ve resolveCollision() yöntemleri:

public boolean colliding(Ball ball)
{
    float xd = position.getX() - ball.position.getX();
    float yd = position.getY() - ball.position.getY();

    float sumRadius = getRadius()   ball.getRadius();
    float sqrRadius = sumRadius * sumRadius;

    float distSqr = (xd * xd)   (yd * yd);

    if (distSqr <= sqrRadius)
    {
        return true;
    }

    return false;
}

public void resolveCollision(Ball ball)
{
    // get the mtd
    Vector2d delta = (position.subtract(ball.position));
    float d = delta.getLength();
    // minimum translation distance to push balls apart after intersecting
    Vector2d mtd = delta.multiply(((getRadius()   ball.getRadius())-d)/d); 


    // resolve intersection --
    // inverse mass quantities
    float im1 = 1 / getMass(); 
    float im2 = 1 / ball.getMass();

    // push-pull them apart based off their mass
    position = position.add(mtd.multiply(im1 / (im1   im2)));
    ball.position = ball.position.subtract(mtd.multiply(im2 / (im1   im2)));

    // impact speed
    Vector2d v = (this.velocity.subtract(ball.velocity));
    float vn = v.dot(mtd.normalize());

    // sphere intersecting but moving away from each other already
    if (vn > 0.0f) return;

    // collision impulse
    float i = (-(1.0f   Constants.restitution) * vn) / (im1   im2);
    Vector2d impulse = mtd.multiply(i);

    // change in momentum
    this.velocity = this.velocity.add(impulse.multiply(im1));
    ball.velocity = ball.velocity.subtract(impulse.multiply(im2));

}

Kaynak Kod: Complete source for ball to ball collider.
İkili: Compiled binary in case you just want to try bouncing some balls around.

Eğer herkes bu temel fizik nasıl geliştirmek için bazı öneriler varsa simülatörü haber ver! Henüz ekleyeceğim tek şey topları daha gerçekçi rulo böylece açısal momentum. Başka bir öneriniz var mı? Bir Yorum bırak!

CEVAP
6 Aralık 2008, CUMARTESİ


İki topun çarpışması olup olmadığını tespit etmek için, onların merkezleri arasındaki mesafe iki kat daha az yarıçapı olup olmadığını kontrol edin. Topları arasında mükemmel elastik bir çarpışma yapmak için tek çarpışma yönde hız bileşeni hakkında endişelenmenize gerek yok. Diğer bileşeni (çarpışma teğet) her iki topları için aynı kalacak. Bir birim vektör ve her bir top, bu yönde oluşturarak çarpışma bileşenleri, topları hız vektörü ile nokta ürünü alarak alabilirsiniz. O zaman mükemmel elastik çarpışma 1D bir denklem içine bu bileşenler takabilirsiniz.

Wikipedia çok iyi summary of the whole process. Herhangi bir kitle topları için, yeni hız denklemleri v1 ve v2 olan çarpışmadan sonra hızları ve u1, u2 den önce () kullanarak hesaplanabilir:

v_{1} = \frac{u_{1}(m_{1}-m_{2}) 2m_{2}u_{2}}{m_{1} m_{2}}

v_{2} = \frac{u_{2}(m_{2}-m_{1}) 2m_{1}u_{1}}{m_{1} m_{2}}

Eğer topları aynı kitle varsa o zaman hızları sadece değiştirdi. Benzer bir şey yok: işte yazdığım bazı kodlar

void Simulation::collide(Storage::Iterator a, Storage::Iterator b)
{
    // Check whether there actually was a collision
    if (a == b)
        return;

    Vector collision = a.position() - b.position();
    double distance = collision.length();
    if (distance == 0.0) {              // hack to avoid div by zero
        collision = Vector(1.0, 0.0);
        distance = 1.0;
    }
    if (distance > 1.0)
        return;

    // Get the components of the velocity vectors which are parallel to the collision.
    // The perpendicular component remains the same for both fish
    collision = collision / distance;
    double aci = a.velocity().dot(collision);
    double bci = b.velocity().dot(collision);

    // Solve for the new velocities using the 1-dimensional elastic collision equations.
    // Turns out it's really simple when the masses are the same.
    double acf = bci;
    double bcf = aci;

    // Replace the collision velocity components with the new ones
    a.velocity()  = (acf - aci) * collision;
    b.velocity()  = (bcf - bci) * collision;
}

Verimlilik için, Ryan Fox haklı olarak, bölgenin Yukarı ayıran bölümlere, her bölüm içinde çarpışma algılama yapıyor düşünmelisiniz. Topları bu kod çok daha karmaşık hale getirebilir, böylece bir bölüm sınırları diğer topları ile çarpışır, unutmayın. Verimliliği muhtemelen birkaç yüz topları rağmen kadar önemi yok. Bonus puan için, farklı bir çekirdek her bir bölüm çalıştırın, ya da her bölüm içinde çarpışmalar işleme bölebilirsiniz.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • AutoklubZAPRESIC

    AutoklubZAPR

    17 Mayıs 2011
  • Caroline Martin

    Caroline Mar

    19 EYLÜL 2008
  • Rachel Talbott

    Rachel Talbo

    26 Ocak 2011