Colisión linea - rectangulo

Consulte acerca de programas, técnicas, algoritmos etc.

Colisión linea - rectangulo

Notapor midder » Lun Jul 04, 2011 8:55 am

Muy buenas.

Llevo tiempo siguiendo este foro y es la primera vez que escribo. Así que ahí va la duda:

El caso es que tengo un tipo linea en la que almaceno los puntos de los extremos, en mi caso son (x1, y1) y (x2, y2). La duda me llega cuando quiero saber si esa linea esta colisionando con un rectángulo (tipo rect de pygame). He probado distintas formas de hacerlo, pero no doy con la clave.
Así que por aquí lo dejo a ver si a alguien se le ocurre.

Muchas gracias, un saludo.
midder
 
Mensajes: 4
Registrado: Jue Feb 17, 2011 9:08 am

Re: Colisión linea - rectangulo

Notapor midder » Mar Jul 05, 2011 7:03 pm

Bueno estuve trabajando un poco en el tema y he conseguido sacar algo, no saca todos los posibles casos, pero sí los que me hacen falta.
def line_rectangle_collision(self, line, rect):

#Colisiones eje X
#Atraviesa verticalmente el rectangulo, con los extremos fuera
if (min(line.x1, line.x2) >= rect.x and min(line.x1, line.x2) <= rect.x + rect.w) and \
(min(line.y1, line.y2) <= rect.y and max(line.y1, line.y2) >= rect.y + rect.h):
return True
#Atraviesa verticalmente el rectangulo, con el extremo inferior fuera
if (min(line.x1, line.x2) >= rect.x and min(line.x1, line.x2) <= rect.x + rect.w) and \
(min(line.y1, line.y2) >= rect.y and min(line.y1, line.y2) <= rect.y + rect.h):
return True
#Atraviesa verticalmente el rectangulo, con el extremo superior fuera
if (max(line.x1, line.x2) >= rect.x and max(line.x1, line.x2) <= rect.x + rect.w) and \
(max(line.y1, line.y2) >= rect.y and max(line.y1, line.y2) <= rect.y + rect.h):
return True

#Colisiones eje Y
#Atraviesa horizontalmente el rectangulo, con los dos extremos fuera
if (min(line.y1, line.y2) >= rect.y and min(line.y1, line.y2) <= rect.y + rect.h) and \
(min(line.x1, line.x2) <= rect.x and max(line.x1, line.x2) >= rect.x + rect.w):
return True
#Atraviesa horizontalmente el rectangulo, con el extremo derecho fuera
if (min(line.y1, line.y2) >= rect.y and min(line.y1, line.y2) <= rect.y + rect.h) and \
(min(line.x1, line.x2) >= rect.x and min(line.x1, line.x2) <= rect.x + rect.w):
return True
#Atraviesa horizontalmente el rectangulo, con el extremo izquierdo fuera
if (max(line.y1, line.y2) >= rect.y and max(line.y1, line.y2) <= rect.y + rect.h) and \
(max(line.x1, line.x2) >= rect.x and max(line.x1, line.x2) <= rect.x + rect.w):
return True

return False


Saludos!
midder
 
Mensajes: 4
Registrado: Jue Feb 17, 2011 9:08 am

Re: Colisión linea - rectangulo

Notapor carlostex » Dom Jul 10, 2011 2:42 am

Hola, hace tiempo que no comentaba pero he estado pendiente. mira te dejo un código que use para manejar colisiones con objetos que tienen forma arbitraria.

Código: Seleccionar todo

//--------------------LineIntersection2D-------------------------
//
//   Given 2 lines in 2D space AB, CD this returns true if an
//   intersection occurs.
//
//-----------------------------------------------------------------
#include<math_extra.h>
#include<vector>
inline bool LineIntersection2D(punto A,
                               punto B,
                               punto C,
                               punto D)
{
  double rTop = (A.y-C.y)*(D.x-C.x)-(A.x-C.x)*(D.y-C.y);
  double sTop = (A.y-C.y)*(B.x-A.x)-(A.x-C.x)*(B.y-A.y);

   double Bot = (B.x-A.x)*(D.y-C.y)-(B.y-A.y)*(D.x-C.x);

  if (Bot == 0)//parallel
  {
    return false;
  }

  double invBot = 1.0/Bot;
   double r = rTop * invBot;
   double s = sTop * invBot;

   if( (r > 0) && (r < 1) && (s > 0) && (s < 1) )
  {
    //lines intersect
    return true;
  }

  //lines do not intersect
  return false;
}


inline bool ObjectIntersection2D(const std::vector<punto>& object1,
                                 const std::vector<punto>& object2)
{
  //test each line segment of object1 against each segment of object2
  for (unsigned int r=0; r<object1.size()-1; ++r)
  {
    for (unsigned int t=0; t<object2.size()-1; ++t)
    {
      if (LineIntersection2D(object2[t],
                             object2[t+1],
                             object1[r],
                             object1[r+1]))
      {
        return true;
      }
    }
  }

  return false;
}

inline bool Pointinbox(punto point, punto p1, punto p2)
{

  return (point.x>p1.x && point.x<p2.x && point.y>p1.y && point.y<p2.y);



}

La estructura punto solo contiene 2 enteros X, Y. Fíjate que la función interesante aquí es la de ObjectIntersection2D pues determina si se produjo una colisión entre dos objetos, un objeto no es mas que un conjunto de puntos, así puedes definir una linea y un rectángulo, llamas a la función y te dirá si hubo colisión.
El conocimiento de unos es conocimiento de todos.
Avatar de Usuario
carlostex
 
Mensajes: 249
Registrado: Mar Jul 14, 2009 4:13 am
Ubicación: mexico


Volver a General

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado