2013-03-10 20 views
8

Esiste un modo in Libgdx per verificare una collisione tra un poligono e un cerchio?Collisione tra cerchio e poligono con Libgdx

Ho visto la classe Intersector ma ho trovato solo il test di collisione per Cerchio e Rettangolo. Che ne dici di qualsiasi altro poligono?

Se ho bisogno di farlo manualmente, qual è il modo migliore per farlo usando Libgdx?

risposta

10

Quindi, sono riuscito a creare un metodo di test di collisione tra un cerchio e un poligono. Almeno, funziona per me.

Ecco il codice:

public boolean overlaps(Polygon polygon, Circle circle) { 
    float []vertices=polygon.getTransformedVertices(); 
    Vector2 center=new Vector2(circle.x, circle.y); 
    float squareRadius=circle.radius*circle.radius; 
    for (int i=0;i<vertices.length;i+=2){ 
     if (i==0){ 
      if (Intersector.intersectSegmentCircle(new Vector2(vertices[vertices.length-2], vertices[vertices.length-1]), new Vector2(vertices[i], vertices[i+1]), center, squareRadius)) 
       return true; 
     } else { 
      if (Intersector.intersectSegmentCircle(new Vector2(vertices[i-2], vertices[i-1]), new Vector2(vertices[i], vertices[i+1]), center, squareRadius)) 
       return true; 
     } 
    } 
    return false; 
} 
+0

Sarà questo lavoro codice con PolyLine invece di poligono? – Vetalll

+0

Spiacente, non so da quando ho fatto questa domanda/risposta a 2 anni fa =/ –

+0

Ho controllato questo codice. Sì, questo è un codice funzionante per entrambe le varianti. Polygon e PolyLine – Vetalll

9

Purtroppo non ho abbastanza fama di commentare in modo da sto aggiungendo questo come un'altra risposta invece ...

risposta eccellente

di Cristiano lavora per controllare che il il cerchio si sovrappone a uno dei segmenti di linea del poligono, ma non controlla il caso più insolito in cui il cerchio è completamente contenuto all'interno del poligono, cosa che potrebbe accadere se un piccolo cerchio in rapido movimento entra in collisione con un grande poligono.

ho repasted codice di Cristiano sotto con una piccola modifica per risolvere il problema ...

public static boolean overlaps(Polygon polygon, Circle circle) { 
    float []vertices=polygon.getTransformedVertices(); 
    Vector2 center=new Vector2(circle.x, circle.y); 
    float squareRadius=circle.radius*circle.radius; 
    for (int i=0;i<vertices.length;i+=2){ 
     if (i==0){ 
      if (Intersector.intersectSegmentCircle(new Vector2(vertices[vertices.length - 2], vertices[vertices.length - 1]), new Vector2(vertices[i], vertices[i + 1]), center, squareRadius)) 
       return true; 
     } else { 
      if (Intersector.intersectSegmentCircle(new Vector2(vertices[i-2], vertices[i-1]), new Vector2(vertices[i], vertices[i+1]), center, squareRadius)) 
       return true; 
     } 
    } 
    return polygon.contains(circle.x, circle.y); 
} 
+0

Ah, ok, nel momento in cui ho solo dovuto controllare le collisioni fuori così, non lo sapevo. Grazie per l'aggiornamento;) –

+0

Questo deve entrare in libgdx. –

+0

Assicurati solo di non creare nuovi vettori all'interno del metodo, altrimenti la memoria utilizzata si gonfierà rapidamente. Usa qualcosa come 'tmpVector2.set (x, y)' al posto di 'new Vector2 (x, y)' (dove 'tmpVector2' è un campo). –

0

... e di follow-up sulla risposta eccellente di Phil Anderson, ecco la mia versione che evita semplicemente la creazione di nuovi Vector2s ogni controllo e invece ri-utilizza istanze statiche di Vector2.

public class PolygonUtil { 

static final Vector2 center = new Vector2(); 
static final Vector2 vec1 = new Vector2(); 
static final Vector2 vec2 = new Vector2(); 

public static boolean overlaps(Polygon polygon, Circle circle) { 
    float []vertices=polygon.getTransformedVertices(); 
    center.set(circle.x, circle.y); 
    float squareRadius=circle.radius*circle.radius; 
    for (int i=0;i<vertices.length;i+=2){ 
     if (i==0){ 
      if (Intersector.intersectSegmentCircle(vec1.set(vertices[vertices.length - 2], vertices[vertices.length - 1]), 
        vec2.set(vertices[i], vertices[i + 1]), center, squareRadius)) 
       return true; 
     } else { 
      if (Intersector.intersectSegmentCircle(vec1.set(vertices[i-2], vertices[i-1]), vec2.set(vertices[i], vertices[i+1]), center, squareRadius)) 
       return true; 
     } 
    } 
    return polygon.contains(circle.x, circle.y); 
} 

}

Problemi correlati