Maks. İle bir hedefe giden bir kurşun yolunu hesaplamak için kullanılan algoritma. 2 ricochets


21

Zayıf başlık için özür dilerim ama daha iyi ifade edemezdim.

Nintendo'nun (evet!) WiiPlay adlı WiiPlay adlı bu muhteşem oyunu . İçinde 9 mini oyun var ve favorim Tanklar! . Bu, kendinizi mahvetmeden COM düşman tanklarını imha etmekle ilgilidir. İşte bir seviyenin ekran görüntüsü:

görüntü tanımını buraya girin

Tankları imha etmenin bir yolu kurşun atmaktır. Bu kireç yeşili düşman tankı, iki kez seken (duvarlara ve bloklara) yüksek hızlı mermiler atan ateş var. Şu an bulunduğu yerde kalırsa oyuncu tankının nasıl anında tahrip olabileceğini görebilirsiniz, çünkü merkezdeki kireç tankı görüntüye çizdiğim yeşil yolu izleyen bir mermiyi ateşleyebilir.

Ben amatör bir programcı olarak, ben de tanktaki kireci tankının hangi yöne ateş etmemiz gerektiğini nasıl belirleyeceğini merak ediyordum.

Kendim düşündüm ama olası bir algoritma ile gelmedi. Birine ilham vermeleri durumunda sonuçlarımı açıklayacağım. Sadece benim açıklama sırasında basitlik için, bir farz duvarı olmak kurşun sekerek hangi karşı herhangi bir yüzey . Böylece blokların izole edilmiş bir dikdörtgeni dört duvar oluşturur.

Mermi ricochet'lerinin her zaman bir paralelkenarın bir tarafında ya da bir paralelkenarın zıt noktalarına dönüştüğü 2 noktanın sonucuna vardım. Ateş eden düşman tankı ve hedeflediği oyuncu tankı mutlaka diğer 2 köşeden ibaret değil, kesinlikle paralelkenarın dört kenarından birine bağlanan çizgiler üzerinde uzanır. Paralelkenarın oluşturulabileceği 4 olası yolun bir örneği:

görüntü tanımını buraya girin

HOR-VER , merminin önce yatay bir duvara çarptıktan sonra dikey bir duvara çarptığı anlamına gelir.

Sonra sıkışıp kaldım. Düşman tankını ve oyuncu tankını harita üzerinde birbirine bağlayan bir çizgi etrafında hareket etmeyi düşündüm, herhangi bir duvarla herhangi iki vuruşlu bir paralelkenar oluşturup oluşturmadığını görmek için, ancak bu her zaman işe yaramaz çünkü düşman tankı ve oyuncu tankı değil mutlaka paralelkenarın köşeleriyle çakışmalıdır.

Ayrıca, algoritmanın genel akışından emin değilim. Algoritma aşağıdaki 2 yapıdan birini alır mı, yoksa ikisinin de yanlışı olabilir miyim?

  • Olası yolları belirlemeye devam edin ve her zaman en iyisini (en kısa, en karanlık, en kaçınılmaz olan veya kaçınılmaz ölçütlere dayalı birleştirilmiş ve ağırlıklı bir değerlendirme olabilir) işaretleyin ve gerisini unutun. Tüm hesaplamalardan sonra kalan, alınacak en iyisidir.
  • İlk önce mermi ile ulaşılabilen tüm duvarları belirleyiniz (merminin bu duvarların her birine ulaşmak için başka herhangi bir duvara yaslanmaya ihtiyacı yoktur), sonra bu duvarların her birindeki ulaşılabilir tüm aralıkları belirlemek (bazen uzak bir noktaya ulaşmak imkansızdır). eğer başka bir duvar yanınızda durursa, sekmesiz bir duvar), daha sonra yine bir sekmeyle ulaşılabilir tüm duvarları ve bu duvarlarda erişilebilen tüm aralıkları tekrar belirleyin. Bu 4 işlem, ışın izlemeye benzer şekilde yapılabilir. Her işlem sırasında, oyuncu tankına herhangi bir ışın çarptıysa, o ışığa göre kurşun yolunu bulun.

Benim düşünceme göre, bu algoritmayı anlamak zor çünkü:

  • bir mermi herhangi bir yöne ateşlenebilir; ve
  • Herhangi bir duvarda sonsuz sayıda nokta vardır, matematikte olduğu gibi, bir çizgide sonsuz sayıda nokta vardır.

Ama Nintendo insanları yine de başardı, yani ... fikri olan var mı?


Sadece kontrol etmek için, bunun nasıl yapılabileceğini soruyorsunuz, Nintendo'nun gerçekten yapmayı nasıl seçtiğini değil mi?
Ixrec

@lxrec haklısınız, sadece yapabilecekleri şekilde değil , yapmanın olası bir yoluyla ilgileniyorsunuz .
merhaba tüm

Oyunun bir çözüm bulmasına gerek yok. Ateş etmek için düğmeye bastığınızda, oyun zaten karşılaştığınız konumunuzu ve yönünüzü bilir, o zaman sadece bu bilgiyi kullanır. Yörüngeyi izleyecektir ve düşman tankını yolunda bulursa, aksi takdirde hayır atarsınız.
Mandrill,

2
“Sonsuz” birçok açı olsa da, onları kolayca birkaç denklik sınıfına düşürebilirsiniz. Nicky Case'in Görme ve Işık poligonları arasında gölgeler yaratmanın harika bir demosu - ışık ışınlarından ziyade mermi yolları kullanmanız ve ışınlarınızın iki kez yansıtılması dışında, tamamen sizin sorununuz. Yansımanın AI için önemli olmadığını unutmayın - yansıma sadece görüş hattını uzatır, ancak bu aynı nesnenin birden fazla açıdan görülebileceği anlamına gelir.
amon

@ Mandrill, korkarım sorumu anlamadınız. Düşman tankının, oyuncu tankına çarpan bir kurşun yolu nasıl tasarlayabildiğini soruyordum.
merhaba tüm

Yanıtlar:


9

Doğrudan bir görüş açısı göz önüne alındığında, sorun açıkça önemsizdir. Ancak, biz yansıma ile uğraşıyoruz. Sahnenin hangi kısımlarının görülebildiğini doğru bir şekilde bulmak, bir ışın izleyicinin parçası olarak yansıma uygularken zordur, çünkü bu bazı açıklıkları kaçırabilir. İki umut verici açı arasındaki "ikili arama" da mümkün değil: yansımalar nedeniyle, gerçekte görünür alan sürekli değildir, bu nedenle “sezgisel” “eğer A'nın sağında ve B'nin solunda ise, bir hedef olmalı” A ve B arasındaki çözüme izin verilmez ve “yaratıcı” çözümleri özleyeceğiz. Bunun yerine, izleyiciyi sanal bir konumdan yeniden çalıştırarak yansımayı uygulamanızı tavsiye ederim - ateş tankımızın aynaya bakıldığında olduğu gibi görünüyor :

target |obstacle
   X   |
    \  |  X real position
     \   /
      \ /
   ----------- mirror surface
        \
         \
          X virtual position

Bunun avantajı, yansıtılmış ışının şimdi sanal konumdan kaynaklanan düz bir çizgi olmasıdır. Tekniği aşağıdaki çizimde göstermeye çalıştım:

köşelerde çekim

X atış pozisyonunu (X) hedefi işaretler. Renkli alanlar görülebilir.

  1. Doğrudan görüş hattı: hedef görünmez. Ancak, (1) ve (2) yüzeylerine vurabiliriz.

  2. Bir yansıması. Engellerin içinde iki sanal atış pozisyonu var. Alttaki pozisyon LOS'u hedefe yönlendirir, bu nedenle ilk ateşleme çözümümüz vardır: kurşun yolu, hedef ve alt ayna yüzeyi arasındaki ışın ve ışın aynası çarpışma noktası ile gerçek atış pozisyonu arasındaki kısımdır.

  3. İki yansıma: İlk yansımadaki üst sanal konum, ayna yüzeyinde alt engelin bir kısmını görebilir. İki yansıma izin verildiğinden, bu pozisyonu alt engele yansıtabiliriz. Pozisyonlar (I) gerçek pozisyon, (II) sanal pozisyonun ilk yansımadan ve (III) sanal pozisyonun ikinci yansımadan işaretlenmiştir.

    (III) den, LOS'u hedefe (X) yönlendirdik, bu yüzden başka bir ateşleme çözümü bulduk. Madde işareti, ikinci ayna çarpışma noktasına kadar X – III çizgisi boyunca, sonra ayna çarpışma noktaları arasındaki III --- II çizgisi boyunca ve son olarak, birinci ayna çarpışma noktasından gerçek I konumuna kadar olan II --- I çizgisi boyuncadır.

    Aslında, ilk yansımadaki düşük sanal konum da üst engele yansıtılabilir, ancak bu doğrudan bir çözüme yol açmaz.

Engellerin hangi kısımlarının göründüğünü (ve dolayısıyla mermiyi yansıtmak için kullanılabildiğini) öğrendikten sonra, derinlemesine ilk arama yoluyla yansıtma yapmak kolay görünür. Uygun ayna yüzeylerini bulmak için, Nicky Case'in Görme ve Işığında belirtilen teknikler kullanılabilir: 360 vektör denemek yerine - açıklıkları kaçırabilir ve aynı zamanda ziyan olur - sadece engellerin kenarlarına ışınlar fırlatırız.


"Sadece engellerin kenarlarına ışın fırlatmanın" nasıl çalıştığını anlamıyorum. Duvarların sonuna doğru ve bir çözüm bulana kadar yavaş yavaş içeriye doğru ışınları fırlatmaya başlamak mı istiyorsunuz? Öyleyse, bu kuralla çözümün daha hızlı bulunabileceğini biliyorum.
merhaba tüm

Bazı değerlendirmelerden sonra, bunun en iyi cevap olduğunu düşünüyorum, çünkü açıkçası, daha önce en iyi olarak işaretlendiğim matematiksel cevapla, doğrudan tek zıplayan ve zıplamayan çözümlerle doğrudan ilgilenemez.
merhaba tüm

Bu harika! Oyununuzda çok fazla talep etmeden seviyenizi yansıtılmış bir şekilde gösterme konusunda herhangi bir tavsiye
retrovius

7

2 duvar yansıması için Karl Bielefeldt fikrini genişletmek:görüntü tanımını buraya girin

A ve B verilmiştir (tanklar). Önce A'nın görebileceği tüm duvarları ve B'nin görebileceği tüm duvarları listelemelisiniz. Sonra ilk duvarın ilk listedeki ve ikinci duvarın birinci duvardan farklı olduğu ve ikinci listede olduğu çiftler yaparsınız. Bu testi tüm olası duvar çiftleri için yapmanız gerekir (adayları yok etmenin bir yolunu bulamazsanız). Belirli bir duvar çifti için R ve S'yi bulduktan sonra kontrol edin.

1) A'nın R'nin doğrudan vizyonu varsa

2) R, duvara 1 aitse (duvar sadece bir çizgidir, tüm çizgi yoktur)

3) R'nin S'ye doğrudan erişimi varsa

4) S, duvar2'ye aitse (duvar sadece bir çizgidir, tüm çizgi yoktur)

5) S'nin B'ye doğrudan erişimi varsa

R ve S'yi bulmak için : wall1'i bildiğinizden, wall1'e teğet hat denklemini belirleyebilirsiniz, R R'den wall 1'e teğet çizgiye ait olduğundan, R'nin 2 koordinatı arasında bir ilişki vardır (bir dereceye kadar serbestlik derecesiyle sonuçlanır). R) S'ye benzer şekilde (bu nokta wall2 hattına girdiğinden beri S koordinatları arasında bir ilişki vardır). Öyleyse şimdi 2 serbestlik dereceniz var ve bir çözüm bulmak için 2 bağımsız bağımsız denkleminiz olmalıdır. Bir denklem:

(AA')/(RA')=(SS')/(RS')

diğer denklem:

(BB')/(SB')=(RR')/(SR')

Yukarıdaki denklemlerde A, A ', B, B' değerlerinin bilindiğini veya doğrudan hesaplanabileceğini not edin. R 've S', R ve S koordinatlarının ve duvar denklemlerinin fonksiyonudur. Ben matematiği bitirmedim, bu yüzden denklemlerin nasıl görüneceğini bilemiyorum.


Bu harika bir matematiksel yaklaşım. Fakat algoritma aynı anda denklemleri çözmek için çok fazla hesaplama zamanı gerektirir, sanırım? Mesafelerle ilgili çok sayıda karekök ve üstelik vardır.
merhaba tüm

3

Ricochet'i bırakan açının giren açı ile aynı olması gerektiğinden faydalanabilirsiniz. Y koordinatlı bir yatay duvar ve koordinatlı ciki sabit tank (a,b)ve (d,e)aşağıdaki denklemi sağlayan sadece bir açı vardır.

denklem diyagramı

Sadece xhedef almanız gereken duvar boyunca mesafeyi bulmak için çözün . İki duvar aynı şekilde çalışır. Sadece iki denklemin ve iki bilinmeyenin var.


1

Işınların nasıl yönlendirileceğini gösteren düzgün diyagramlarınız var, bu yüzden yansıtıcı yüzeylerin nasıl belirleneceğine dair detayları bırakacağım.

İlk yüzey A , ikincisi B'ye çarpması gereken yüzeyi diyelim .

A konumunda çekim yaparak B'nin (görünür) kenarlarına vurmaya çalışın . Başka bir deyişle, eğer ayna-bitmiş A'ya bakarsanız B uçlarının yansımalarını göreceğiniz noktaları belirleyin . Bunu yapmak kolay olmalı, ele almanız gereken tek bir yansıtma noktanız var.

Şimdi B'nin (görünür) kenarlarına çarpan iki ışın biliyorsunuz . Onlara kenar ışınları diyelim. Yansımaları B üzerinden hesaplayın ; Hedefinin ötesinde bir yerlere gitmeliler. Sen belirleyebilir eğer hedef yatıyor arasında bir ışın solundaki ama tersi diğer sağında veya yardımcısı için, olan onlara. Bu, düz çizginin genel denklemini kullanarak yapmak için çok önemlidir .

Hedef kenar ışınları arasında değilse, açıkça herhangi bir ara ışınla vuramazsınız; başka bir çift yüzey seç.

Hedef , ışınların arasındaysa, ikili aramayı kullanarak ara vuruş ışınını arayın. Kenar ışınlarına karşılık gelen iki ateşleme açınız var, çarpma açınız onların arasında yatıyor. Hedefinizin açısal noktadan görüldüğü gibi açısal çapının aşırı küçük olmaması şartıyla, bir isabet ışını yönünü bulana kadar birkaç yinelemeye ihtiyacınız olacak.

İşte bir resim:

ışınlar

Burada iki kenar ışınları kırmızı ve mavi olarak gösterilmiştir. Görünüşe göre, kırmızı olandan daha küçük bir açıda yayılan bir ışını bulabilirsiniz, ancak kırmızı olandan daha büyük olanı açarak bu ışının yeşil hedefe çarpmasını sağlar.


Hayır, mutlaka değil! Kırmızı ve mavi mermi yolları arasında herhangi bir yerde yatan ekstra bir engel varsa, diyagramınızı düşünün. Kırmızı ve mavi açılar arasında bir açıyla bir mermi atarsanız, oyuncu tankına daha yakın bir vuruş yapabilir, ancak bazı mermiler arasında yatan rastgele bir engelden kaçabileceği için tamamen kaybedebilirsiniz. Lütfen bu olasılık hakkında tartıştığı yerde @ amon'un cevabına bakınız.
merhaba tüm

@ Amon'un yanıtı oylandı; Düz çizgi yansıtma fikrini seviyorum. Ayrıca, algoritmanın isabet yolunun bu basitleştirilmiş şekilde bulduktan sonra fiilen geçirilebilir olduğunu kontrol etmesi gerektiğini düşünüyorum. Daha da ilginç olanı, hedefin yalnızca kısmen tıkalı olduğu (muhtemelen iki görünür bölgeye bile ayrılmış) bir olasılıktır. Amon'un metodu onu kullanmaya daha uygun.
9000

-3

Öncelikle, ışığın kırılması hakkında konuştuğunuzda fizik dersinde hatırlıyor musunuz? Sorununuz bu ilkeleri kullanarak çözülebilir. Geliş açısı, yansıma açısına eşittir. Bu yüzden, düşman tankın ilk sıçrama için mümkün olan her açı boyunca koşması gerekir, böylece ikinci sıçrama oyuncuya çarpabilir. Işın izleme fikrine de devam et. Şimdi, oyuncu hareket halindeyken bu karmaşıklaşıyor ancak bir algoritmaya başlamanız için yeterince iyi bir fikir olmalı


1
Yansıma prensiplerini anlıyorum. @ Amon'un yorumuna cevabımı görebilirsiniz. Oyuncu hareketinin dikkate alınması gerektiği konusunda haklısınız, ancak değerlendirmeye dayanarak birden fazla olası yol arasından en iyisini seçmek için bir kriter olarak bırakılabileceğini düşünüyorum. Bununla birlikte, bu dikkate alınmayabilir çünkü bu, madde işareti yolunun mesafesiyle ilişkilidir; yani , yol ne kadar uzun olursa, oyuncu, madde işareti hedefe ulaşmadan o kadar fazla hareket edebilir.
merhaba tüm
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.