Poligono Convexo: Este test algo mas complicado que los anteriores, pero es mas general. Mediante este algoritmo se puede probar cuando un punto se encuentra dentro de un polígono convexo (polígono convexo es aquel que no tiene ángulos internos mayores a 180 grados).

Punto dentro de poligono convexo

Primero es necesario hallar un punto a sobre cada lado (el intermedio puede ser), para de esta manera encontrar el vector ap que va del punto a al punto p (el punto del que se necesita saber si esta adentro del poligono). Se encuentra tambien el vector N normal "interior" del lado y finalmente se hace el producto punto ap.N. Los casos son:

  • ap.N es + o 0 para cada lado: El punto esta adentro.
  • ap.N es - para algun lado: El punto esta afuera.
C++:
  1. struct Punto2d
  2. {
  3.     float x;
  4.     float y;
  5. };
  6.  
  7. struct Poligono
  8. {
  9.     list<Punto2d> puntos; //lista de los puntos del poligono
  10. };
  11.  
  12. bool ladoCorrecto(Punto2d inicial,Punto2d terminal,Punto2d punto)
  13. {
  14.             //se calcula el vector "lado" que va de un punto a otro
  15.             vector2d lado;
  16.             lado.x = inicial.x - terminal.x;
  17.             lado.y =  inicial.y - terminal.y;
  18.  
  19.             //la perpendicular del vector "lado"
  20.             vector2d perp;
  21.             perp.x = -lado.y; //las perpendiculares son vectores con componentes intercambiadas
  22.             perp.y = lado.x// y una componente negativa
  23.  
  24.             //se saca un punto "muestra" en la mitad del lado
  25.             lado.escalar(0.5f);
  26.             vector2d muestra;
  27.             muestra.x = inicial.x + lado.x ;
  28.             muestra.y = inicial.y + lado.y;
  29.            
  30.             //se busca el vector entre el punto muestra y el punto supuestamente "adentro"
  31.             vector2d muestraPunto;
  32.             muestraPunto.x = muestra.x - punto.x;
  33.             muestraPunto.y = muestra.y - punto.y;
  34.  
  35.             //Finalmente se pregunta si el producto punto perp.muestraPunto es negativo
  36.             if(perp.punto(muestraPunto) <0)
  37.             {
  38.                 return false; // si con alguno falla, es que esta afuera
  39.             }
  40.             return true;
  41. }
  42.  
  43.  
  44. bool puntoDentroDePoly(Poligono *poly, Punto2d *punto)
  45. {
  46.     list<Punto2d>::iterator iterPuntos = poly->puntos.begin();
  47.     bool estaAdentro = true;   //En principio se supone que esta adentro
  48.  
  49.  
  50.     if(poly->puntos.size()> 2) //Bueno, es un poligono, no?
  51.     {
  52.         //El primer punto que se lee;
  53.         Punto2d puntoActual;
  54.         Punto2d puntoAnt = *iterPuntos;
  55.         iterPuntos++;
  56.  
  57.         while(iterPuntos != poly->puntos.end() && estaAdentro)
  58.         {   
  59.             puntoActual = *iterPuntos;
  60.             estaAdentro = ladoCorrecto(puntoAnt,puntoActual,*punto);       
  61.             puntoAnt = puntoActual;
  62.             iterPuntos++;
  63.         }
  64.  
  65.         //falta el ultimo con el primero
  66.         if(estaAdentro)// hay que comprobar que todavia se considere adentro
  67.         {
  68.             iterPuntos = poly->puntos.begin();
  69.             puntoActual = *iterPuntos;
  70.             estaAdentro = ladoCorrecto(puntoAnt,puntoActual ,*punto);
  71.         }
  72.  
  73.         return estaAdentro;
  74.     }
  75.  
  76.     return false; //eso no es ni siquiera un triangulo
  77. }

Por ahora estos test son útiles por ejemplo para hace seleccion sobre elementos del juego que se puedan encerrar en estas figuras y detectar cuando un cierto elemento del juego entra o sale de una zona demarcada por un circulo, un rectangulo alineado con los ejes o un poligono convexo.

Como nota final es importante ver que estos no son ni los únicos ni los mas eficientes test geométricos (pero con suerte son los mas faciles de entender). Ademas aún no se tiene en cuenta la variable tiempo y las colisiones entre los llamados "bounding", con lo que se puede realmente empezar a trabajar colisiones.

Informacion de Referencia:

Crashing into New Year, articulo de Gamasutra por Jeff Lander.

COMENTARIOS

Dejar un comentario

:mrgreen: :| :twisted: :arrow: 8O :) :? 8) :evil: :D :idea: :oops: :P :roll: ;) :cry: :o :lol: :x :( :!: :?: