Duvar Çarpışmasının Sonuç Açısını Belirleme


14

Sabit bir yatay veya dikey duvara doğru bir yönde hareket eden bir cisim var. Nesnenin sıçraması gereken açıyı nasıl hesaplayabilirim? Nesne duvara keyfi bir açıyla yaklaşabilir.

Yanıtlar:


18

Duvarın normal vektörünü biliyorsanız ve nesne için gelen bir yönünüz varsa, istediğiniz şey bir vektörün düzlem boyunca yansımasıdır .

Eğer n bir normalize vektör olup, v ise , gelen yönü, o zaman ne istediğiniz olduğu - (2 ( n · v ) n - v ). Eksi işareti, bir nesnenin hızı tersine çevrileceği için yansıma formülünün aslında yönü tersine çevirmediğini açıklar.

Bu cevap bir açı değil, vektör matematiği açısından verilir, çünkü bir açı kullanmak için açık bir nedeniniz yoksa bu genellikle tercih edilir. Açılardan bahsetmeniz gerekiyorsa, yansıma açısının insidans açısına eşit olduğunu unutmayın. Açı normalden ölçülürse, giden açı gelen açının olumsuzlamasıdır; açı duvardan ölçülürse, gelen açının tamamlayıcısıdır.


Harika bir açıklama. Benim için harika çalıştı! Teşekkürler!
DRiFTy

13

Bir 2D veya 3D oyun olduğunu belirtmediniz. Ancak bu bir 2D oyun ve duvarlarınızın yatay veya dikey olması garanti ediliyorsa ve sadece nesneyi onlardan atlamak istiyorsanız, yansımalarla uğraşmaktan çok daha kolay bir yol var.

Dikey bir duvara çarparken nesnenin hızının X bileşenini veya yatay bir duvara çarparken nesnenin hızının Y bileşenini basitçe ortadan kaldırın. Misal:

if( /* hit vertical wall */ )
{
    object.velocity.x *= -1;
}
if( /* hit horizontal wall */ )
{
    object.velocity.y *= -1;
}

Ancak, açıyı bilmeyi gerçekten önemsiyorsanız, genel olarak, yansıma açısı, insidans açısı ile aynıdır. Bu açı, duvarın normaline göre ölçülür. İşte bunu netleştirmesi gereken bir resim:

resim açıklamasını buraya girin

Bunu rastgele duvarlar için ele almanız gerektiğinde, bir vektörü nasıl yansıtacağınıza bakmanız gerekir. Duvarın normal ve insidans vektörünü alan ve yansıyan vektörü sizin için döndüren küçük bir formül. İşte XNA'nın kullandığı formül:

public static Vector3 Reflect(Vector3 vector, Vector3 normal)
{
    return vector - 2 * Vector3.Dot(vector, normal) * normal;
}

2D için şunları yapabilirsiniz:

public static Vector2 Reflect(Vector2 vector, Vector2 normal)
{
    return vector - 2 * Vector2.Dot(vector, normal) * normal;
}

Üzgünüm, bu bir 2D oyun. Bunu açıya göre tutmak istiyorum çünkü söylediğin gibi herhangi bir duvarı kullanabilmek istiyorum. Teşekkürler!
DRiFTy

2D'yi de kapsayacak şekilde düzenledim. Aslında, sadece 2D vektörler, aynı işlemler ve formüller ile aynı
Gustavo Maciel

2B oyundaki bir duvar açılı olabilir, bu yüzden ifade if it's a 2D game and your walls are guaranteed to be horizontal or verticaldoğru değildir. Cevabın ikinci kısmı doğru uygulamayı onaylıyor. IMHO, parçaların sırası tersine çevrilmeli, önce genel çözüm ve enfazda sunulurken, sağ açılı çözüm istisnai durum için basitleştirme olarak sunulmaktadır.
XenoRo

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.