Page 1 of 1

Seperating axis theorem

Posted: Tue Sep 22, 2009 2:26 pm
by short
Ok, let me preface this saying I'm not one for posting a huge function and saying "help" but I honestly don't know where else to turn.

I've been following this guide located here http://www.gamedev.net/reference/progra ... /page2.asp and trying to implement it manually. I've read almost every guide I can get my hands on through Google and it's still not clicking for me.

A large portion of this code is very extrapolated. I tried to follow the guide to the tooth, and when it says
"Repeat steps 2, 3, and 4 for each of the axes. If all of the axes show an overlap then there is a collision, if even one of the axes shows no overlap then there is no collision. "
for repeating, I did it all out manually again. For each axis, with the hope that it would click in my head.

With all that said, I hate posting such a large block of code for someone else to read, but it's basically the same thing four times over. Once I figure out what's wrong, I'll condense it and optimize it.

Hopefully somebody else can benefit from this discussion as well, but I need to ask for help. My brain's been stuck against this solid concrete wall for 48 hours and I can't seem to get past it on my own.

Thanks ;)

Code: Select all

bool seperatingAxisTheoremCollision(Rect * A, Rect * B)
{
    int count_overlap = 0;

    //Rect * A = new Rect(Vertex(1.5f, 1.5f, 0), 1.0f, 1.0f);
    //Rect * B = new Rect(Vertex(3.5f, 2.5f, 0), 1.0f, 1.0f);
    Point * axis1 = new Point(( A->getVertices()[TOP_RIGHT].x - A->getVertices()[TOP_LEFT].x ), (A->getVertices()[TOP_RIGHT].y - B->getVertices()[TOP_LEFT].y ));
    Point * axis2 = new Point(( A->getVertices()[TOP_RIGHT].x - A->getVertices()[BOTTOM_RIGHT].x ), (A->getVertices()[TOP_RIGHT].y - A->getVertices()[BOTTOM_RIGHT].y ));
    Point * axis3 = new Point(( B->getVertices()[TOP_LEFT].x - B->getVertices()[BOTTOM_LEFT].x ), (B->getVertices()[TOP_LEFT].y - B->getVertices()[BOTTOM_LEFT].y ));
    Point * axis4 = new Point(( B->getVertices()[TOP_LEFT].x - B->getVertices()[TOP_RIGHT].x ), (B->getVertices()[TOP_LEFT].y - B->getVertices()[TOP_RIGHT].y ));

 
/* AXIS 1, RECT A */
    GLfloat ATR_X = (( (A->getVertices()[TOP_RIGHT].x * axis1->x) + (A->getVertices()[TOP_RIGHT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->x;
    GLfloat ATR_Y = (( (A->getVertices()[TOP_RIGHT].x * axis1->x) + (A->getVertices()[TOP_RIGHT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->y;

    GLfloat ATL_X = (( (A->getVertices()[TOP_LEFT].x * axis1->x) + (A->getVertices()[TOP_LEFT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->x;
    GLfloat ATL_Y = (( (A->getVertices()[TOP_LEFT].x * axis1->x) + (A->getVertices()[TOP_LEFT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->y;

    GLfloat ABL_X = (( (A->getVertices()[BOTTOM_LEFT].x * axis1->x) + (A->getVertices()[BOTTOM_LEFT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->x;
    GLfloat ABL_Y = (( (A->getVertices()[BOTTOM_LEFT].x * axis1->x) + (A->getVertices()[BOTTOM_LEFT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->y;

    GLfloat ABR_X = (( (A->getVertices()[BOTTOM_RIGHT].x * axis1->x) + (A->getVertices()[BOTTOM_RIGHT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->x;
    GLfloat ABR_Y = (( (A->getVertices()[BOTTOM_RIGHT].x * axis1->x) + (A->getVertices()[BOTTOM_RIGHT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->y;

    GLfloat SCALE_A_TR = ( ATR_X * axis1->x ) + ( ATR_Y * axis1->y );
    GLfloat SCALE_A_TL = ( ATL_X * axis1->x ) + ( ATL_Y * axis1->y );
    GLfloat SCALE_A_BL = ( ABL_X * axis1->x ) + ( ABL_Y * axis1->y );
    GLfloat SCALE_A_BR = ( ABR_X * axis1->x ) + ( ABR_Y * axis1->y );


    GLfloat c = MIN(SCALE_A_TR, SCALE_A_TL);
    GLfloat d = MIN(SCALE_A_BL, SCALE_A_BR);
    GLfloat e = MAX(SCALE_A_TR, SCALE_A_TL);
    GLfloat f = MAX(SCALE_A_BL, SCALE_A_BR);

    GLfloat minA = MIN(c,d);
    GLfloat maxA = MAX(e,f);

    /* Axis1, RECT B */
    GLfloat BTR_X = (( (B->getVertices()[TOP_RIGHT].x * axis1->x) + (B->getVertices()[TOP_RIGHT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->x;
    GLfloat BTR_Y = (( (B->getVertices()[TOP_RIGHT].x * axis1->x) + (B->getVertices()[TOP_RIGHT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->y;

    GLfloat BTL_X = (( (B->getVertices()[TOP_LEFT].x * axis1->x) + (B->getVertices()[TOP_LEFT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->x;
    GLfloat BTL_Y = (( (B->getVertices()[TOP_LEFT].x * axis1->x) + (B->getVertices()[TOP_LEFT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->y;

    GLfloat BBL_X = (( (B->getVertices()[BOTTOM_LEFT].x * axis1->x) + (B->getVertices()[BOTTOM_LEFT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->x;
    GLfloat BBL_Y = (( (B->getVertices()[BOTTOM_LEFT].x * axis1->x) + (B->getVertices()[BOTTOM_LEFT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->y;

    GLfloat BBR_X = (( (B->getVertices()[BOTTOM_RIGHT].x * axis1->x) + (B->getVertices()[BOTTOM_RIGHT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->x;
    GLfloat BBR_Y = (( (B->getVertices()[BOTTOM_RIGHT].x * axis1->x) + (B->getVertices()[BOTTOM_RIGHT].y * axis1->y) ) / ((axis1->x*axis1->x)+(axis1->y*axis1->y)))*axis1->y;

    GLfloat SCALE_B_TR = ( BTR_X * axis1->x ) + ( BTR_Y * axis1->y );
    GLfloat SCALE_B_TL = ( BTL_X * axis1->x ) + ( BTL_Y * axis1->y );
    GLfloat SCALE_B_BL = ( BBL_X * axis1->x ) + ( BBL_Y * axis1->y );
    GLfloat SCALE_B_BR = ( BBR_X * axis1->x ) + ( BBR_Y * axis1->y );

    GLfloat g = MIN(SCALE_B_TR, SCALE_B_TL);
    GLfloat h = MIN(SCALE_B_BL, SCALE_B_BR);
    GLfloat i = MAX(SCALE_B_TR, SCALE_B_TL);
    GLfloat j = MAX(SCALE_B_BL, SCALE_B_BR);

    GLfloat minB = MIN(g,h);
    GLfloat maxB = MAX(i,j);

    if(minB <= maxA || maxB >= minA)
    {
        // overlap
        count_overlap++;
    }
    else
    {
        // no overlap, collision is not possible. WE MUST HAVE ALL 4 OVERLAPS for a collision to happen.
        return 0; // no collision.
    }

//2
    /* Axis2, RECT A */
    ATR_X = (( (A->getVertices()[TOP_RIGHT].x * axis2->x) + (A->getVertices()[TOP_RIGHT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->x;
    ATR_Y = (( (A->getVertices()[TOP_RIGHT].x * axis2->x) + (A->getVertices()[TOP_RIGHT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->y;

    ATL_X = (( (A->getVertices()[TOP_LEFT].x * axis2->x) + (A->getVertices()[TOP_LEFT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->x;
    ATL_Y = (( (A->getVertices()[TOP_LEFT].x * axis2->x) + (A->getVertices()[TOP_LEFT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->y;

    ABL_X = (( (A->getVertices()[BOTTOM_LEFT].x * axis2->x) + (A->getVertices()[BOTTOM_LEFT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->x;
    ABL_Y = (( (A->getVertices()[BOTTOM_LEFT].x * axis2->x) + (A->getVertices()[BOTTOM_LEFT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->y;

    ABR_X = (( (A->getVertices()[BOTTOM_RIGHT].x * axis2->x) + (A->getVertices()[BOTTOM_RIGHT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->x;
    ABR_Y = (( (A->getVertices()[BOTTOM_RIGHT].x * axis2->x) + (A->getVertices()[BOTTOM_RIGHT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->y;

    SCALE_A_TR = ( ATR_X * axis2->x ) + ( ATR_Y * axis2->y );
    SCALE_A_TL = ( ATL_X * axis2->x ) + ( ATL_Y * axis2->y );
    SCALE_A_BL = ( ABL_X * axis2->x ) + ( ABL_Y * axis2->y );
    SCALE_A_BR = ( ABR_X * axis2->x ) + ( ABR_Y * axis2->y );


    c = MIN(SCALE_A_TR, SCALE_A_TL);
    d = MIN(SCALE_A_BL, SCALE_A_BR);
    e = MAX(SCALE_A_TR, SCALE_A_TL);
    f = MAX(SCALE_A_BL, SCALE_A_BR);

    minA = MIN(c,d);
    maxA = MAX(e,f);

    /* axis2, RECT B */
    BTR_X = (( (B->getVertices()[TOP_RIGHT].x * axis2->x) + (B->getVertices()[TOP_RIGHT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->x;
    BTR_Y = (( (B->getVertices()[TOP_RIGHT].x * axis2->x) + (B->getVertices()[TOP_RIGHT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->y;

    BTL_X = (( (B->getVertices()[TOP_LEFT].x * axis2->x) + (B->getVertices()[TOP_LEFT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->x;
    BTL_Y = (( (B->getVertices()[TOP_LEFT].x * axis2->x) + (B->getVertices()[TOP_LEFT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->y;

    BBL_X = (( (B->getVertices()[BOTTOM_LEFT].x * axis2->x) + (B->getVertices()[BOTTOM_LEFT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->x;
    BBL_Y = (( (B->getVertices()[BOTTOM_LEFT].x * axis2->x) + (B->getVertices()[BOTTOM_LEFT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->y;

    BBR_X = (( (B->getVertices()[BOTTOM_RIGHT].x * axis2->x) + (B->getVertices()[BOTTOM_RIGHT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->x;
    BBR_Y = (( (B->getVertices()[BOTTOM_RIGHT].x * axis2->x) + (B->getVertices()[BOTTOM_RIGHT].y * axis2->y) ) / ((axis2->x*axis2->x)+(axis2->y*axis2->y)))*axis2->y;

    SCALE_B_TR = ( BTR_X * axis2->x ) + ( BTR_Y * axis2->y );
    SCALE_B_TL = ( BTL_X * axis2->x ) + ( BTL_Y * axis2->y );
    SCALE_B_BL = ( BBL_X * axis2->x ) + ( BBL_Y * axis2->y );
    SCALE_B_BR = ( BBR_X * axis2->x ) + ( BBR_Y * axis2->y );

    g = MIN(SCALE_B_TR, SCALE_B_TL);
    h = MIN(SCALE_B_BL, SCALE_B_BR);
    i = MAX(SCALE_B_TR, SCALE_B_TL);
    j = MAX(SCALE_B_BL, SCALE_B_BR);

    minB = MIN(g,h);
    maxB = MAX(i,j);

    if(minB <= maxA || maxB >= minA)
    {
        // overlap
        count_overlap++;
    }
    else
    {
        // no overlap, collision is not possible. WE MUST HAVE ALL 4 OVERLAPS for a collision to happen.
        return 0; // no collision.
    }
//3
    /* axis3, RECT A */
    ATR_X = (( (A->getVertices()[TOP_RIGHT].x * axis3->x) + (A->getVertices()[TOP_RIGHT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->x;
    ATR_Y = (( (A->getVertices()[TOP_RIGHT].x * axis3->x) + (A->getVertices()[TOP_RIGHT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->y;

    ATL_X = (( (A->getVertices()[TOP_LEFT].x * axis3->x) + (A->getVertices()[TOP_LEFT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->x;
    ATL_Y = (( (A->getVertices()[TOP_LEFT].x * axis3->x) + (A->getVertices()[TOP_LEFT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->y;

    ABL_X = (( (A->getVertices()[BOTTOM_LEFT].x * axis3->x) + (A->getVertices()[BOTTOM_LEFT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->x;
    ABL_Y = (( (A->getVertices()[BOTTOM_LEFT].x * axis3->x) + (A->getVertices()[BOTTOM_LEFT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->y;

    ABR_X = (( (A->getVertices()[BOTTOM_RIGHT].x * axis3->x) + (A->getVertices()[BOTTOM_RIGHT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->x;
    ABR_Y = (( (A->getVertices()[BOTTOM_RIGHT].x * axis3->x) + (A->getVertices()[BOTTOM_RIGHT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->y;

    SCALE_A_TR = ( ATR_X * axis3->x ) + ( ATR_Y * axis3->y );
    SCALE_A_TL = ( ATL_X * axis3->x ) + ( ATL_Y * axis3->y );
    SCALE_A_BL = ( ABL_X * axis3->x ) + ( ABL_Y * axis3->y );
    SCALE_A_BR = ( ABR_X * axis3->x ) + ( ABR_Y * axis3->y );


    c = MIN(SCALE_A_TR, SCALE_A_TL);
    d = MIN(SCALE_A_BL, SCALE_A_BR);
    e = MAX(SCALE_A_TR, SCALE_A_TL);
    f = MAX(SCALE_A_BL, SCALE_A_BR);

    minA = MIN(c,d);
    maxA = MAX(e,f);

    /* axis3, RECT B */
    BTR_X = (( (B->getVertices()[TOP_RIGHT].x * axis3->x) + (B->getVertices()[TOP_RIGHT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->x;
    BTR_Y = (( (B->getVertices()[TOP_RIGHT].x * axis3->x) + (B->getVertices()[TOP_RIGHT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->y;

    BTL_X = (( (B->getVertices()[TOP_LEFT].x * axis3->x) + (B->getVertices()[TOP_LEFT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->x;
    BTL_Y = (( (B->getVertices()[TOP_LEFT].x * axis3->x) + (B->getVertices()[TOP_LEFT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->y;

    BBL_X = (( (B->getVertices()[BOTTOM_LEFT].x * axis3->x) + (B->getVertices()[BOTTOM_LEFT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->x;
    BBL_Y = (( (B->getVertices()[BOTTOM_LEFT].x * axis3->x) + (B->getVertices()[BOTTOM_LEFT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->y;

    BBR_X = (( (B->getVertices()[BOTTOM_RIGHT].x * axis3->x) + (B->getVertices()[BOTTOM_RIGHT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->x;
    BBR_Y = (( (B->getVertices()[BOTTOM_RIGHT].x * axis3->x) + (B->getVertices()[BOTTOM_RIGHT].y * axis3->y) ) / ((axis3->x*axis3->x)+(axis3->y*axis3->y)))*axis3->y;

    SCALE_B_TR = ( BTR_X * axis3->x ) + ( BTR_Y * axis3->y );
    SCALE_B_TL = ( BTL_X * axis3->x ) + ( BTL_Y * axis3->y );
    SCALE_B_BL = ( BBL_X * axis3->x ) + ( BBL_Y * axis3->y );
    SCALE_B_BR = ( BBR_X * axis3->x ) + ( BBR_Y * axis3->y );

    g = MIN(SCALE_B_TR, SCALE_B_TL);
    h = MIN(SCALE_B_BL, SCALE_B_BR);
    i = MAX(SCALE_B_TR, SCALE_B_TL);
    j = MAX(SCALE_B_BL, SCALE_B_BR);

    minB = MIN(g,h);
    maxB = MAX(i,j);

    if(minB <= maxA || maxB >= minA)
    {
        // overlap
        count_overlap++;
    }
    else
    {
        // no overlap, collision is not possible. WE MUST HAVE ALL 4 OVERLAPS for a collision to happen.
        return 0; // no collision.
    }

//4
    /* axis4, RECT A */
    ATR_X = (( (A->getVertices()[TOP_RIGHT].x * axis4->x) + (A->getVertices()[TOP_RIGHT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->x;
    ATR_Y = (( (A->getVertices()[TOP_RIGHT].x * axis4->x) + (A->getVertices()[TOP_RIGHT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->y;

    ATL_X = (( (A->getVertices()[TOP_LEFT].x * axis4->x) + (A->getVertices()[TOP_LEFT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->x;
    ATL_Y = (( (A->getVertices()[TOP_LEFT].x * axis4->x) + (A->getVertices()[TOP_LEFT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->y;

    ABL_X = (( (A->getVertices()[BOTTOM_LEFT].x * axis4->x) + (A->getVertices()[BOTTOM_LEFT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->x;
    ABL_Y = (( (A->getVertices()[BOTTOM_LEFT].x * axis4->x) + (A->getVertices()[BOTTOM_LEFT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->y;

    ABR_X = (( (A->getVertices()[BOTTOM_RIGHT].x * axis4->x) + (A->getVertices()[BOTTOM_RIGHT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->x;
    ABR_Y = (( (A->getVertices()[BOTTOM_RIGHT].x * axis4->x) + (A->getVertices()[BOTTOM_RIGHT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->y;

    SCALE_A_TR = ( ATR_X * axis4->x ) + ( ATR_Y * axis4->y );
    SCALE_A_TL = ( ATL_X * axis4->x ) + ( ATL_Y * axis4->y );
    SCALE_A_BL = ( ABL_X * axis4->x ) + ( ABL_Y * axis4->y );
    SCALE_A_BR = ( ABR_X * axis4->x ) + ( ABR_Y * axis4->y );


    c = MIN(SCALE_A_TR, SCALE_A_TL);
    d = MIN(SCALE_A_BL, SCALE_A_BR);
    e = MAX(SCALE_A_TR, SCALE_A_TL);
    f = MAX(SCALE_A_BL, SCALE_A_BR);

    minA = MIN(c,d);
    maxA = MAX(e,f);

    /* axis4, RECT B */
    BTR_X = (( (B->getVertices()[TOP_RIGHT].x * axis4->x) + (B->getVertices()[TOP_RIGHT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->x;
    BTR_Y = (( (B->getVertices()[TOP_RIGHT].x * axis4->x) + (B->getVertices()[TOP_RIGHT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->y;

    BTL_X = (( (B->getVertices()[TOP_LEFT].x * axis4->x) + (B->getVertices()[TOP_LEFT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->x;
    BTL_Y = (( (B->getVertices()[TOP_LEFT].x * axis4->x) + (B->getVertices()[TOP_LEFT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->y;

    BBL_X = (( (B->getVertices()[BOTTOM_LEFT].x * axis4->x) + (B->getVertices()[BOTTOM_LEFT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->x;
    BBL_Y = (( (B->getVertices()[BOTTOM_LEFT].x * axis4->x) + (B->getVertices()[BOTTOM_LEFT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->y;

    BBR_X = (( (B->getVertices()[BOTTOM_RIGHT].x * axis4->x) + (B->getVertices()[BOTTOM_RIGHT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->x;
    BBR_Y = (( (B->getVertices()[BOTTOM_RIGHT].x * axis4->x) + (B->getVertices()[BOTTOM_RIGHT].y * axis4->y) ) / ((axis4->x*axis4->x)+(axis4->y*axis4->y)))*axis4->y;

    SCALE_B_TR = ( BTR_X * axis4->x ) + ( BTR_Y * axis4->y );
    SCALE_B_TL = ( BTL_X * axis4->x ) + ( BTL_Y * axis4->y );
    SCALE_B_BL = ( BBL_X * axis4->x ) + ( BBL_Y * axis4->y );
    SCALE_B_BR = ( BBR_X * axis4->x ) + ( BBR_Y * axis4->y );

    g = MIN(SCALE_B_TR, SCALE_B_TL);
    h = MIN(SCALE_B_BL, SCALE_B_BR);
    i = MAX(SCALE_B_TR, SCALE_B_TL);
    j = MAX(SCALE_B_BL, SCALE_B_BR);

    minB = MIN(g,h);
    maxB = MAX(i,j);

    if(minB <= maxA || maxB >= minA)
    {
        // overlap
        count_overlap++;
    }
    else
    {
        // no overlap, collision is not possible. WE MUST HAVE ALL 4 OVERLAPS for a collision to happen.
        return 0; // no collision.
    }





    if(count_overlap == 4)
    {
        return 1; // all projections overlapped, collision detected.
    }
    else
    {
        return 0;
    }
}

Re: Seperating axis theorem

Posted: Tue Sep 22, 2009 3:12 pm
by avansc

Re: Seperating axis theorem

Posted: Tue Sep 22, 2009 3:43 pm
by short
I read it... I'll read it again... thanks..

Re: Seperating axis theorem

Posted: Tue Sep 22, 2009 5:12 pm
by Falco Girgis
That article on GameDev.net is absolutely fucktarded. When Kendall and I first started, that article was one of the first things that we ran into. After at least a day of trying to implement their bullshit, I gave up. I later learned how to implement it, and went back to examine the article.

I'm not sure how they are under the impression that that article 1) works or 2) is anywhere remotely efficient.

Step 1: Determine your axes and normalize them.
Step 2: Take the DOT PRODUCT of every vertex on that axis. Why the hell are they taking a VECTOR PROJECTION then later rederiving a dot product? Redundant, stupid.
Step 3: Find your axis of minimal overlap
Step 4: Find the distance of overlap

Now you have a normalized vector for your direction, and a scalar for magnitude of impact. Multiply the two and you have your normal vector.

Re: Seperating axis theorem

Posted: Wed Sep 23, 2009 1:37 am
by short
GyroVorbis wrote:That article on GameDev.net is absolutely fucktarded. When Kendall and I first started, that article was one of the first things that we ran into. After at least a day of trying to implement their bullshit, I gave up. I later learned how to implement it, and went back to examine the article.

I'm not sure how they are under the impression that that article 1) works or 2) is anywhere remotely efficient.

Step 1: Determine your axes and normalize them.
Step 2: Take the DOT PRODUCT of every vertex on that axis. Why the hell are they taking a VECTOR PROJECTION then later rederiving a dot product? Redundant, stupid.
Step 3: Find your axis of minimal overlap
Step 4: Find the distance of overlap

Now you have a normalized vector for your direction, and a scalar for magnitude of impact. Multiply the two and you have your normal vector.


aaaahhhhh thank you.

Re: Seperating axis theorem

Posted: Wed Sep 23, 2009 3:58 pm
by captjack
GyroVorbis wrote:That article on GameDev.net is absolutely fucktarded. When Kendall and I first started, that article was one of the first things that we ran into. After at least a day of trying to implement their bullshit, I gave up. I later learned how to implement it, and went back to examine the article.

I'm not sure how they are under the impression that that article 1) works or 2) is anywhere remotely efficient.

Step 1: Determine your axes and normalize them.
Step 2: Take the DOT PRODUCT of every vertex on that axis. Why the hell are they taking a VECTOR PROJECTION then later rederiving a dot product? Redundant, stupid.
Step 3: Find your axis of minimal overlap
Step 4: Find the distance of overlap

Now you have a normalized vector for your direction, and a scalar for magnitude of impact. Multiply the two and you have your normal vector.

GyroVorbis FTW! :worship:


Those guys must have studied out of "Teach Yourself Linear Algebra in 24 Hours."

Re: Seperating axis theorem

Posted: Thu Sep 24, 2009 11:00 am
by MarauderIIC
Do they have a feedback button? I'm sure that if you got them to fix the article, you'd help a lot more programmers.

Re: Seperating axis theorem

Posted: Thu Sep 24, 2009 3:28 pm
by Falco Girgis
I've just learned to take everything on GameDev.net with a grain of salt. That's why I want to get articles up here at TheChaosRift relatively soon.

Re: Seperating axis theorem

Posted: Thu Sep 24, 2009 5:07 pm
by Bakkon
GyroVorbis wrote: Step 1: Determine your axes and normalize them.
Step 2: Take the DOT PRODUCT of every vertex on that axis. Why the hell are they taking a VECTOR PROJECTION then later rederiving a dot product? Redundant, stupid.
Step 3: Find your axis of minimal overlap
Step 4: Find the distance of overlap
Goddamn, that's so much easier to understand than everything else I've read on this topic.

Re: Seperating axis theorem

Posted: Thu Sep 24, 2009 5:38 pm
by Falco Girgis
The math behind it such:

Look at the "Vector Projection" formula. A vector projection is taking a dot product and multiplying it by a normalized vector. That's the "projection" of a vector in the direction of another.

So when you're doing the separating axis theorem, you first NORMALIZE THE AXES THAT YOU'RE GOING TO TEST. You just did half of the projection right there. Now taking the dot product of a vertex and a normalized axis will tell you how far along the axis the vertex is which is the same thing as a vector projection of two UNnormalized vectors.

Every SAT implementation that I stumbled upon while researching seemed half-assed. It's like people don't understand the linear algebra, so they play around or brute force it.

I abandoned all hope, then Kendall and I got out our linear algebra book and started from scratch with JUST the separation axis theorem: "For two convex polygons, if there cannot be a line drawn to divide the two, they are colliding."