2010-03-04 5 views
8

Sto facendo una partita dove c'è solo un certo spazio in cui il giocatore può muoversi. Voglio rappresentare questo spazio con un poligono di qualche tipo. La domanda principale che vorrei porre è se contiene un punto specifico. (Mi piace rect.intersect())XNA ha un poligono, come il rettangolo?

XNA ha qualche modo per farlo?

risposta

8

No. (Non e compresa la versione 3 almeno)

XNA è delimitazione volumi come tronchi di cono o scatole ma non ha alcuna nozione di poligoni.

È possibile trovare un modo semplice, rapido ed efficace per eseguire punti in poligono con XNA here. L'ho implementato di recente ed è stato eccellente.

Conoscendo il punto del tuo oggetto, tutto ciò che devi fare è creare un poligono che circonda questo oggetto - usare i vettori sarebbe il metodo migliore e più semplice. Quindi eseguire il punto nel controllo poligono.

Ecco il codice di esempio della mia implementazione. Viene utilizzata la classe punto predefinita in XNA. Polygon è una classe semplice che contiene una raccolta di vettori che costituiscono il poligono.

/// <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 è molto semplice, in forma pseudo semi:

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

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

La classe poligono potrebbe facilmente solo memorizzare un insieme di vettori, ma ha introdotto una classe line come linee erano tenuti altrove .

+0

Questo codice è basato su tale articolo, tranne che utilizza C#. Inoltre è stato modificato pesantemente. Dovrei aggiungere, per capire questo codice. Google * "Punto in poligono" * con ray casting. Questo spiegherà di più la teoria. Wikipedia ha anche un bell'articolo su questo. – Finglas

+0

Posso vedere il codice per la tua classe poligonale? Sembra difficile credere che XNA manchi di questo. –

+0

Nelle ultime settimane ho passato molto tempo a scrivere il mio punto sulle funzioni del poligono. Test dei metodi migliori e così via. Il metodo di fusione ray sembra non solo il migliore, ma anche il più bello da implementare. Per quanto riguarda XNA privo di questa funzionalità, sì, può sembrare un po 'difficile da credere, ma la maggior parte dei framework non ha alcun tipo di rilevamento del poligono. – Finglas

1

modificato il ciclo foreach al seguente per gestire tutte le forme poligonali:

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