2010-03-04 6 views
8

Je fais un jeu où il n'y a qu'un certain espace où le joueur peut se déplacer. Je veux représenter cet espace avec un polygone quelconque. La principale question que je voudrais poser est de savoir si elle contient un point donné. (Comme rect.intersect())Est-ce que XNA a un polygone, comme Rectangle?

Est-ce que XNA a un moyen de le faire?

Répondre

8

Non (Non et y compris la version 3 au moins)

XNA a des volumes limite comme ou tronconiques boîtes mais il n'a aucune notion de polygones.

Une manière simple, rapide et efficace d'effectuer un point dans un polygone avec XNA peut être trouvée here. J'ai récemment mis en œuvre ceci et c'était excellent.

Vous connaissez le point de votre objet, tout ce que vous devez faire est de créer un polygone entourant cet objet - l'utilisation de vecteurs serait la méthode la meilleure et la plus simple. Ensuite, effectuez le point dans la vérification de polygone.

Voici l'exemple de code de ma mise en œuvre. La classe de points par défaut dans XNA est utilisée. Le polygone est une classe simple qui contient une collection de vecteurs constituant le polygone.

/// <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; 
} 

La classe Polgyon est très basique, sous forme semi pseudo:

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

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

La classe polygone pourrait très facilement simplement stocker une collection de vecteurs, mais j'introduit une classe de ligne lignes ont été nécessaires ailleurs .

+0

Ce code est basé sur cet article, sauf qu'il utilise C#. De plus, il a été modifié fortement. Je devrais ajouter, pour comprendre ce code. Google * "Point en Polygone" * avec diffusion de rayons. Cela va expliquer la théorie plus. Wikipédia a un bon article à ce sujet aussi. – Finglas

+0

Puis-je voir le code de votre classe de polygone? Il semble difficile de croire que XNA manque de cela. –

+0

J'ai passé beaucoup de temps ces dernières semaines à écrire mon propre point dans les fonctions polygones. Tester les meilleures méthodes et ainsi de suite. La méthode de lancer de rayon semble non seulement la meilleure, mais la plus belle à mettre en œuvre. Quant à XNA qui manque de cette fonctionnalité, oui, cela peut sembler un peu difficile à croire, mais la plupart des frameworks manquent de tout point de détection de polygone. – Finglas

1

Modified la boucle foreach pour ce qui suit pour traiter toutes les formes de polygone:

 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; 
         } 
        } 
     } 
Questions connexes