dikdörtgenlerin hangi taraflarla çarpıştığını da belirleyen basit bir 2D dikdörtgen çarpışma algoritması?


16

Başlangıçta iyi çalışan dikdörtgen kavşak uygulamayı denedim. Bununla birlikte, hız, ivme ve yön vektörleri gibi fizik sistemini uygulamam gerektiğinde, dikdörtgenlerin hangi tarafının çarpıştığını belirlemenin bir yolunu bulmalıydım. Şimdi, benim sistemimde, döndürülmüş bir dikdörtgen yok, bu yüzden bu sorunu basitleştirdi. Ancak, hangi dikdörtgen tarafın çarpıştığını belirlemenin kolay bir yolunu bulamadım. Daha önce bir kez bu sorunla uğraştım ama sefil başarısız oldu.

Geçmişte yaptığım şey, her bir paralel dikdörtgen kenar arasındaki mesafeyi belirlemek ve mesafenin 0'a yakın (başlangıçta tanımlanmış bir mesafe aralığı kullan) veya 0 olup olmadığını kontrol etmektir. Ancak, kayan nokta aritmetiği için bu kararsız olduğunu kanıtlar bilinmeyen zaman kaybı. Bazen, dikdörtgenler, tanımlanan aralığı karşılamadan önce birbirleriyle kesişir.

Öte yandan, her iki taraf için her bir dikdörtgen olan birden çok dikdörtgen oluşturmayı düşünüyordum. Bununla birlikte, tekrar düşündükten sonra, mesafe aralığı kontrolüyle paralel bir tarafa sahip olmakla aynı şey olacaktır, sadece bu mesafe aralığı her mini dikdörtgenin genişliğidir.

Bu nedenle, bu soruna herhangi bir öneriniz var mı?


Kesikli veya sürekli konum güncellemeleri mi kullanıyorsunuz? (Eğer her karede bir kez hızlanma ederek hız güncellenmesi ve ardından konumu hesaplanırken, veya konumunu tahmin için bir işlev kullanırken)
Casey Kuball

Yanıtlar:


24

Cevabım uyarlanan "Hangi Tarafı Hit mı?" :

Yeni bir dikdörtgen olan B ve A'nın Minkowski toplamını hesaplamanızı ve A dikdörtgeninin merkezinin o yeni dikdörtgene ( çarpışmanın olup olmadığını bilmek için ) ve köşegenlerine ( çarpışmanın nerede olduğunu bilmek) oluyor):

float w = 0.5 * (A.width() + B.width());
float h = 0.5 * (A.height() + B.height());
float dx = A.centerX() - B.centerX();
float dy = A.centerY() - B.centerY();

if (abs(dx) <= w && abs(dy) <= h)
{
    /* collision! */
    float wy = w * dy;
    float hx = h * dx;

    if (wy > hx)
        if (wy > -hx)
            /* collision at the top */
        else
            /* on the left */
    else
        if (wy > -hx)
            /* on the right */
        else
            /* at the bottom */
}

1
Bu 'üst' ve 'alt' koordinat sisteminize göreli olarak eklemek istiyorum. Örneğin oyunumda, (0,0) sol üstte, bu yüzden örneğinizden ters çevrildi. Sadece akılda tutulması gereken bir şey.
Neikos

harika bir çözüm, ihtiyaçlarım için çok iyi çalıştı.
Opiatefuchs

1
Dx 0 veya dy 0 veya her ikisi ile bazı aksaklıklar var mı? Nedenini söyleyeyim ... eğer dx = 0 && dy == 0 ise, bu her iki dikdörtgen de aynı orijintedir, algoritma varsayılan olarak alttan döner? bunlardan biri 0 ise, doğru sonuç beklenir. Yani, bence, bu algoritma, belirsiz ve dib değil olması gereken dx == 0 && dy == 0 durumu dışında doğrudur. Yani, dikkat ve teşekkürler.
Prasanth

1
Şimdi, dx == dy, w == h ... sonra da ne olacağını merak ediyordum, kod aslında belirsiz olduğunda sonucun bir tarafı olduğuna karar verir .. bir karenin merkezinin olduğu şekilde kesişen iki kareyi düşünün başka bir karenin köşesi ve diğer karenin merkezi ilk karenin köşesinde. Burada, taraf belirsiz olmalı - sağ veya alt değil. Her ikiside?!
Prasanth
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.