2010-03-04 14 views
8

Tworzę grę, w której jest tylko określone miejsce, w którym gracz może się poruszać. Chcę reprezentować tę przestrzeń za pomocą pewnego rodzaju wielokąta. Głównym pytaniem, które chciałbym zadać, jest to, czy zawiera on dany punkt. (Podobnie jak rect.intersect())Czy XNA ma wielokąt, podobnie jak prostokąt?

Czy XNA ma jakikolwiek sposób to zrobić?

Odpowiedz

8

nr (nie w górę i w tym co najmniej w wersji 3)

XNA ma ograniczające objętości, takich jak frustum lub pudełka ale nie ma pojęcia wielokątów.

Prosty, szybki i skuteczny sposób wykonywania punktu w wielokącie za pomocą XNA można znaleźć here. Niedawno zaimplementowałem to i było świetnie.

Znasz cel swojego obiektu, wszystko co musisz zrobić, to stworzyć wielokąt otaczający ten obiekt - użycie wektorów byłoby najlepszą i najłatwiejszą metodą. Następnie wykonaj punkt w sprawdzaniu wielokątów.

Oto przykładowy kod mojej implementacji. Używana jest domyślna klasa punktowa w XNA. Polygon jest prostą klasą zawierającą zbiór wektorów tworzących wielokąt.

/// <summary> 
/// Point in polygon check. 
/// </summary> 
/// <param name="point">The point.</param> 
/// <param name="polygon">The polygon.</param> 
/// <returns>True if point is inside, false otherwise.</returns> 
/// <see cref="http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/"/> 
public bool PointInPolygon(Point point, Polygon polygon) { 

     bool inside = false; 

     foreach (var side in polygon.Lines) { 
      if (point.Y > Math.Min(side.Start.Y, side.End.Y)) 
       if (point.Y <= Math.Max(side.Start.Y, side.End.Y)) 
        if (point.X <= Math.Max(side.Start.X, side.End.X)) { 
         float xIntersection = side.Start.X + ((point.Y - side.Start.Y)/(side.End.Y - side.Start.Y)) * (side.End.X - side.Start.X); 
         if (point.X <= xIntersection) 
          inside = !inside; 

     } 

     return inside; 
} 

Klasa Polgyon jest bardzo prosty, w pół postaci pseudo:

class Polygon 
{ 
    public List<Line> Lines { get; set; } 
} 

public class Line 
{ 
    public Vector2 Start; 
    public Vector2 End; 
} 

Klasa wielokąta mogłyby bardzo łatwo po prostu przechowywać zbiór wektorów, ale wprowadzono klasę wiersza jako linie były wymagane gdzie indziej .

+0

Kod ten opiera się na tym przepisie, oprócz tego, że używa C#. Dodatkowo został mocno zmodyfikowany. Powinienem dodać, aby zrozumieć ten kod. Google * "Wskaż w wielokąt" * za pomocą ray-castingu. To wyjaśni tę teorię bardziej. Wikipedia ma również fajny artykuł na ten temat. – Finglas

+0

Czy mogę zobaczyć kod twojej klasy wielokątów? Trudno uwierzyć, że XNA jej nie ma. –

+0

Spędziłem dużo czasu w ciągu ostatnich kilku tygodni pisania własnego punktu w funkcjach wielokąta. Testowanie najlepszych metod i tak dalej. Metoda rzucania promienia wydaje się nie tylko najlepsza, ale najmilsza do wdrożenia. Jeśli chodzi o XNA bez tej funkcji, to może się wydawać, że trudno w to uwierzyć, ale większość frameworków nie ma żadnego punktu w wykrywaniu wielokątów. – Finglas

1

zmodyfikowano foreach następującym do obsługi każdego kształtu wielokąt

 foreach (var side in Lines) { 
      if (point.Y > Math.Min(side.Start.Y, side.End.Y)) 
       if (point.Y <= Math.Max(side.Start.Y, side.End.Y)) 
        if (point.X <= Math.Max(side.Start.X, side.End.X)) { 
         if (side.Start.Y != side.End.Y) { 
          float xIntersection = (point.Y - side.Start.Y) * (side.End.X - side.Start.X)/(side.End.Y - side.Start.Y) + side.Start.X; 
          if (side.Start.X == side.End.X || point.X <= xIntersection) 
           result = !result; 
         } 
        } 
     } 
Powiązane problemy