Hareketli bir daire ile süpürülmüş 2D ızgara hücreleri nasıl bulunur?


9

2D hücrelere dayalı bir oyun yapıyorum, bazı hücreler geçebilir, bazıları değil. Dinamik nesneler ızgaradan bağımsız olarak sürekli hareket edebilir, ancak geçilemez hücrelerle çarpışmaları gerekir.

Işığın kesiştiği tüm hücreleri veren bir ışını ızgaraya karşı izlemek için bir algoritma yazdım. Ancak, gerçek nesne nokta boyutunda değildir; Şu anda onları daire olarak temsil ediyorum. Ama hareketli bir çemberin izini sürmek için etkili bir algoritma bulamıyorum. İşte ihtiyacım olan bir resim: resim açıklamasını buraya girin

Sayılar, dairenin ızgara hücreleriyle hangi sırada çarpıştığını gösterir. Bu çarpışmaları bulmak için algoritmayı bilen var mı? Tercihen C # 'de.

Güncelleme Daire tek bir ızgara hücresinden daha büyük olabilir .


mmh neden 3 4 ÖNCE çarpışıyor?
FxIII

@FxIII Resimdeki daireyi hareket ettirdim ve 4'ten önce 3'e çarptı. Sadece zar zor, ama yine de daha önce.
Nevermind

Yanıtlar:


6

Çiziminizin biraz yanıltıcı olduğunu düşünüyorum çünkü daire üzerindeki noktadan hareket yönünüze teğet vuruşlar seçmeyi tercih ediyorsunuz. Dairenizin ÜST ve SOL noktaları bir kenara değdiğinde ızgara kenarlarınızdaki çarpışmaların olduğunu görebiliyorum.

Let daki merkezi olabilir ve r yarıçapı böylece P' = Cı- + ( R , 0) ve P" nin = C + (0, r).

Eğer D senin yön vektörü (versor) 'dir Eğer iki satır vardır:

R '= D · t + P' ,

R "= D · t + P"

Bu çizgilerin denklem çizgileri ile kesişimini bulmanız yeterlidir:

ızgaranızın kenarları olan y = i ve y = i !

Solüsyon Sen bulacaksınız. Basitçe x veya R y bileşeni' ve R" düşünmek zorundayız çünkü kolay t her insersection için s değeri ve thoose için puan t tarafından ler, sadece sıralama bu noktada t ve sizin yapılır.

Kesişim noktasını biliyorsanız hangi hücrenin vurulduğunu kolayca söyleyebileceğinizi düşünüyorum.

Bu r <1 ise (hücre genişliği ve yüksekliği) işe yarar .

Diğer durumlarda da sadece P ' ve P hakkında biraz düşünerek çalışıyor . " Yönü nedeniyle TOP ve SOL seçiyoruz, ALT ve SAĞ ters yönde düşünülmelidir, nedenini anlıyorsunuz.

Şimdi şu resme bakın: büyük daire

Daire tek bir hücreden daha büyük ve çiziminizle aynı yöne gittiğini düşünüyoruz. P1 dokunacak ilk nokta, P2 ikinci, P3 işe yaramaz çünkü alt yarıda. Yapmanız gereken, daha önce gördüğümüz gibi P1 ve P2'den ışınlar dökmek ve dikey çizgiler için aynısını yapmaktır.

Genel olarak, ışınlarınızı ateşlediğiniz yerden TOP ve SOL olanlarla birlikte başka başlangıç ​​noktalarınız olacak, daireniz ne kadar büyükse, o kadar fazla ışın dökülecektir.

Dürüst olmak gerekirse, bazı geometrik ışınlar yaparak tüm ışınları vurmaktan kaçınabilirsiniz, ancak bu şeyleri anlamakta zorlanabilir.


Evet, P yukarı düşünce' ve P" noktasına kendim fakat daire tek bir hücre daha büyük olduğunda ne yapacağını çözemedim. Ek puan gerçekten mantıklı (ve tabii ki sadece ışınları eklemem gerekiyor arasındaki P' ve P ")
Nevermind

Hesaplamaları basitleştiren geometrik değerlendirmeler yapılabilir, ancak uygulamayı kullanmak sizi deneyimle aynı sonuçlara götürebilir.
FxIII

Yatay ve dikey ızgara çizgilerini ayrı ayrı test etmeniz gerektiği açık mı?
FxIII

Çemberin ne zaman bir ızgara tepe noktasını kapladığını da kontrol etmeniz gerektiğini düşünüyorum, çünkü daire köşesinde çapraz olarak bitişik hücre ile çarpışacak, ancak mutlaka önce ona değen dairenin üst / sol / alt / en sağ noktası olmayacak (ve çarpışmayı çok erken tespit edersiniz.) Örnek: sorudaki örnek diyagramda 3,4,5 kareler. Sırayla vurulurlar (3 sonra 4 sonra 5), ​​ancak algoritmanız 4 ve 5'i aynı anda algılar.
finnw

@finnw aynı anda sadece ilmek tam olarak açıortay yönünde hareket ederse dokunurlar.
FxIII

1

Işın çarpışma algoritmanızı kullanmak istiyorsanız, her dairede sekiz nokta (45 derecelik artışlarla, kare ızgarayla hizalanmış) seçebilir ve karşılık gelen noktalar arasındaki ışın çarpışmasını kullanabilirsiniz (örn. üst üste daire). Tüm bu ışın çarpışmalarının birleşmesi, kesişen tüm hücre kümesidir.

Muhtemelen bunu biraz geliştirebilirsiniz - örneğin çizgi parçasını bir dairenin merkezinden diğerinin ortasına kadar kullanarak, ancak her iki tarafta dairenin yarıçapıyla ve paralel çizgi parçalarını kullanarak her iki tarafında daireler.


8 ışın muhtemelen tüm kavşakları garanti eder, ancak onları doğru sırada vermezler. Ve çarpışmalar için düzene ihtiyacım var, sadece bir hücre listesi değil.
Nevermind

Işın çarpışma algoritmanızı her çarpışma için bir t değeri tutmak üzere artırın. Hücrelerin birleşimini elde ettiğinizde, doğru siparişi almak için t-değerini sıralayabilirsiniz.
TreDubZedd

Fakat farklı ışınların t-değerini nasıl karşılaştırabilirim ?
Nevermind

Her zaman aynı çevreden geliyorsanız, kavşak noktalarınız o daireden olan uzaklıklar olacaktır. Daha önce gördüğünüz bir hücreye geldiğinizde, mevcut çarpışmanın t değeri bir öncekinden daha küçükse, onu kullanın ... aksi takdirde, kesişimi atın (orijinali koruyun).
TreDubZedd

1
Dairenin yanlarında harekete dik olan sadece iki ışınla kurtulabilirsiniz, o zaman hangi karoların ışınlara çarptığını görebilir ve geri kalanını merkezlerinin iki ışın arasına düşüp düşmediğini görmek için kontrol edebilirsiniz. Kaçırması gereken tek şey, başlangıç ​​veya bitiş çemberinde çarpışan şeyler olacaktır, ancak bu sadece iki daire ve kolayca ele alınabilir. Sekiz ışından biraz daha yavaş olabilir, emin değilim; ancak sayıyı dairenin boyutuna göre ölçeklendirmeniz gerekmez.
Lunin

1

Bunun mükemmel bir benzetme olduğunu söylemiyorum, ama Bresenham'ın çizgi algoritmasını düşünebilirsiniz . Bu algoritmanın veya uzantılarından birinin değiştirilmesi, özellikle de diğer yayın ve yorumların bazılarıyla eşleştirmeniz durumunda yardımcı olabilir. Tipik olarak, bu algoritma siparişle ilgili değildir, ancak bunu oldukça önemsiz bir şekilde ekleyebileceğinizi düşünürüm.


Ben de bunu düşünüyordum, ama bence bu doğru algoritma değil. Bresenham sadece bir piksel seçiyor, hepsine ihtiyacı var. Ve bresenham'ı sadece bir pikselden oluşan daireye uyarlamak zor olurdu.
zacharmarz

Kullandığım ışın izleyici aslında Bresenham algoritmasına dayanan tür-sorta. Ben ince bir çizgiden "şişman" bir, özellikle daire süpürme genelleme sorun var.
Nevermind
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.