Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Colisión 2d: Rotated Rectangle - Rotated Rectangle

Iniciado por CoLSoN2, 12 de Diciembre de 2004, 01:20:24 AM

« anterior - próximo »

CoLSoN2

 Teniendo el código de si dos rectángulos colisionan (alineados con los ejes X e Y), ¿sabeis cómo puedo saber si dos rectángulos con una cierta rotación colisionan o no?  (algo como una oriented bounding box en 2D, supongo)
Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor

martiño

 Supongamos que tenemos 2 rectangulos R y S. Con 4 vertices (ya rotados) cada uno: R0, R1, R2, R3, S0, S1, S2 y S3.

Haciendo el producto escalar: (R0-S0) * (S1-S0) y mirando el signo puede saber en que lado de la arista (S0, S1) esta R0.

Haciendo asi para todas las aristas puedes saber si R0 esta dentro de S o no.

Haciendo lo mismo para todos los vertices de R y S puedes saber si colisionan o no los rectangulos.

CoLSoN2

Cita de: "martiño"...
Gracias por la respuesta, y más o menos es lo mismo que un código que he encontrado y que testearé en cuanto pueda. Por si a alguien le interesa:



Citarbool Wml::TestIntersection (const Box2& rkBox0,
    const Box2& rkBox1)
{
    // convenience variables
    const Vector2* akA = rkBox0.Axes();
    const Vector2* akB = rkBox1.Axes();
    const Real* afEA = rkBox0.Extents();
    const Real* afEB = rkBox1.Extents();

    // compute difference of box centers, D = C1-C0
    Vector2 kD = rkBox1.Center() - rkBox0.Center();

    Real aafAbsAdB[2][2], fAbsAdD, fRSum;
   
    // axis C0+t*A0
    aafAbsAdB[0][0] = Math::FAbs(akA[0].Dot(akB[0]));
    aafAbsAdB[0][1] = Math::FAbs(akA[0].Dot(akB[1]));
    fAbsAdD = Math::FAbs(akA[0].Dot(kD));
    fRSum = afEA[0] + afEB[0]*aafAbsAdB[0][0] + afEB[1]*aafAbsAdB[0][1];
    if ( fAbsAdD > fRSum )
        return false;

    // axis C0+t*A1
    aafAbsAdB[1][0] = Math::FAbs(akA[1].Dot(akB[0]));
    aafAbsAdB[1][1] = Math::FAbs(akA[1].Dot(akB[1]));
    fAbsAdD = Math::FAbs(akA[1].Dot(kD));
    fRSum = afEA[1] + afEB[0]*aafAbsAdB[1][0] + afEB[1]*aafAbsAdB[1][1];
    if ( fAbsAdD > fRSum )
        return false;

    // axis C0+t*B0
    fAbsAdD = Math::FAbs(akB[0].Dot(kD));
    fRSum = afEB[0] + afEA[0]*aafAbsAdB[0][0] + afEA[1]*aafAbsAdB[1][0];
    if ( fAbsAdD > fRSum )
        return false;

    // axis C0+t*B1
    fAbsAdD = Math::FAbs(akB[1].Dot(kD));
    fRSum = afEB[1] + afEA[0]*aafAbsAdB[0][1] + afEA[1]*aafAbsAdB[1][1];
    if ( fAbsAdD > fRSum )
        return false;

    return true;
}
Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor

Loover

 Ya se habló hace tiempo de algo parecido:

http://www.stratos-ad.com/forums/index.php...ulos+orientados

Y aquí están 4 métodos de colisión que tengo implementados: por envolvente rectangular, por círculo, por arista y por el teorema visto en el link al post. Están documentados, forman parte de la libreria 2d que estoy haciendo. Los métodos matriciales son de D3D pero puede portarse facilmente usando tu propia clase de matrices, lo mismo te son útiles:

http://galeon.com/loover/colisiones.cpp

Un saludo!
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.