Altıgen bir tıklama kutusunu tanıma


17

Ben soluk altıgenler içeren bir oyun üzerinde çalışıyorum .

Şu anda, kullandığım altıgen bir resmim var (tüm kenarlar aynı uzunlukta ... 50 piksele 50 piksellik bir resme sığıyor).

Biraz C # için yeni ve gerçekten XNA için yeni, ama nokta ve açıları dayalı bir kıvrımlı if deyimi yapmak yerine çağırabileceğiniz kolay bir yöntem var mı?


Onaltılık tıklama algılamayı uygulayan gamedev.stackexchange.com/questions/6382/… adresine bakın .
Tim Holt

4
Tamamen Googled "gasp hexagons" gibiydim, "ne tür bir altıgen bu ?!" Sanırım yavaş bir gün geçiriyorum.
MichaelHouse

2
Hmm, altıgen yerine soluk soluğa tıklarsanız ne olur?
Tim Holt

1
İhtiyaçlarınıza bağlı olarak, basit bir daire sadece bir tıklama alanı için yapardı. Aksi takdirde, sargı toplamı veya toplam gibi çokgen tekniğinde bir nokta kullanmanız gerekecektir.
PhilCK

Onaltılık harita keyfi olarak döndürülmedikçe, çokgen üzerindeki nokta MAJOR aşırı doludur. 1000x1000 altıgenlik bir harita ile ne yaparsınız? Her birini kontrol etmek istiyor musunuz? RE: Çevreler, çalışmayacaklar. Üç onaltılık kavşak köşesinin yakınında, üst üste binen üç daireniz olacaktır. Tamamen altıgenler içinde yer alan daha küçük daireler, yasal tıklamaların herhangi bir dairede olmayacağı boşluklara sahip olacaktır.
Tim Holt

Yanıtlar:


18

Altıgen, köşeleri kırpılmış bir dikdörtgendir. Bunu yaptım ve Medeniyet serisinin bunu ortogonal haritalarla böyle yaptığını duydum, beyaz boşluklu (ortogonal veya altıgen) ve kırmızı, yeşil, mavi ve sarı bir bitmap oluşturmak köşe. (Ya da hangi renkleri istersen.)

Altıgen: Altıgen maskeveyaresim açıklamasını buraya girin

Dikey: resim açıklamasını buraya girin

Ardından, imlecin hangi dikdörtgenin üzerinde olduğunu belirleyin ve bu konumda pikselin rengini test edin. Beyazsa, o alanın üzerinde geziyorlar. Diğer renkler bir ofsetle eşleştirilir ve bunun yerine bu altıgenin üzerine gelirler. Bu şekilde etkilidir, az geometri gerektirir ve keyfi olarak yorulan herhangi bir alan için kullanılabilir.


Sadece bir not: Altıgen 6 eşit uzunlukta kenara sahiptir. Sunulan görüntülerin hiçbiri aslında altıgen içermiyor. Bunun yerine, 6 taraflı çokgenler içerirler. Bunun dışında bu yöntem işe yarıyor. Bununla birlikte, daha büyük altıgenler için altıgen sınırlarını hesaplamaktan daha yavaştır, ancak bu yöntem daha büyük altıgenler için daha fazla alan gerektirir (piksel doğruluğu başına tutmak istiyorsanız). Küçük altıgenler için (ve donanıma bağlı olarak), bu yöntem muhtemelen sınırları hesaplamaktan daha hızlıdır.
Olhovsky

9
Bir altıgen herhangi bir 6 taraflı çokgendir. Düşündüğünüz şey bir eşkenar altıgen (aslında, muhtemelen bir tür eşkenar ve eşkenar altıgen olan normal bir altıgen düşünüyorsunuz )
Random832

Cevabınızın kötü olduğunu söylemediğimi lütfen unutmayın. Bence bu iyi bir cevap ve yeri olan bir çözüm. Bununla birlikte, herhangi bir modern platformda altıgen sınırlarını hesaplamak için, altıgen sınırlarını hesaplamak için bu yöntemi seçmeyeceğim, çünkü sınırların hesaplanması bunu yapmak için çok daha genişletilebilir bir yol. Örneğin, altıgen boyutunu değiştirmek istediğinizi varsayalım - şimdi görüntüyü yeniden oluşturmak zorunda mısınız? Bir piksel mükemmel altıgen maske üretmek bir acıdır. Burada bir tane üretmemiş olmanız, bunun bir kanıtıdır bence.
Olhovsky

2
@Olhovsky - Burada mükemmel bir altıgen maske üretmedim çünkü işteyken birkaç dakikalık aralarımda bir topluluk hizmeti olarak soruları cevaplıyorum ve aslında bir video oyunu yazmıyorum. OP daha az matematikle bir çözüm arıyordu ve bunun düzgün olduğunu düşündüm, bu yüzden paylaşacağımı düşündüm, çünkü bu kesinlikle kendi başıma düşünmeyeceğim bir şeydi .
dlras2

18

Altıgen çarpma testi yapan bir XNA yöntemi yoktur.

Bu makalede, sınama yapan bir işlevin nasıl yazılacağı açıklanır ve bu işlev size sağlanır:

Bir Noktanın Altıgen İçinde Olup Olmadığı Nasıl Kontrol Edilir

İşte bu makaleden bir özet: altıgen tıklama kutusu

Ve testi yapan işlev şu şekilde gider:

  1. Altıgenin etrafındaki sınırlayıcı kutuyu, kesişmiyorsa erkenden test edin.
  2. Noktayı yukarıda gösterildiği gibi yerel bir çeyreğe dönüştürün.
  3. isInsideYerel kadran için aşağıdaki testi yapın .

public function isInside(pos:Vec2Const):Boolean
{
    const q2x:Number = Math.abs(pos.x - _center.x);       
    const q2y:Number = Math.abs(pos.y - _center.y);
    if (q2x > _hori || q2y > _vert*2) 
        return false;
    return 2 * _vert * _hori - _vert * q2x - _hori * q2y >= 0;
}

Tüm ayrıntılar için makaleye bakın.


İşte bazı yararlı diğer kaynaklar:


1

Burada herhangi bir çokgen içindeki tıklamaları tespit etmek için kullanılabilecek bir yöntem var:

public bool PointInPolygon( Vector2 p, Vector2[] poly )
    {
        Vector2 p1, p2;
        bool inside = false;

        if( poly.Length < 3 )
        {
            return inside;
        }

        Vector2 oldPoint = new Vector2( poly[poly.Length - 1].X, poly[poly.Length - 1].Y );

        for( int i = 0; i < poly.Length; i++ )
        {
            Vector2 newPoint = new Vector2( poly[i].X, poly[i].Y );

            if( newPoint.X > oldPoint.X )
            {
                p1 = oldPoint;
                p2 = newPoint;
            }
            else
            {
                p1 = newPoint;
                p2 = oldPoint;
            }

            if( ( newPoint.X < p.X ) == ( p.X <= oldPoint.X )
                && ( (long)p.Y - (long)p1.Y ) * (long)( p2.X - p1.X )
                 < ( (long)p2.Y - (long)p1.Y ) * (long)( p.X - p1.X ) )
            {
                inside = !inside;
            }

            oldPoint = newPoint;
        }

        return inside;
    }

Altıgenin köşelerini bir vector2 dizisinde (poli) ve tıklatılan konumu (p) yönteme vermeniz gerekir.

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.