Seperating axis theorem

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Seperating axis theorem

Post 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;
    }
}
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
avansc
Respected Programmer
Respected Programmer
Posts: 1708
Joined: Sun Nov 02, 2008 6:29 pm

Re: Seperating axis theorem

Post by avansc »

Some person, "I have a black belt in karate"
Dad, "Yea well I have a fan belt in street fighting"
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: Seperating axis theorem

Post by short »

I read it... I'll read it again... thanks..
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: Seperating axis theorem

Post 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.
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: Seperating axis theorem

Post 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.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
captjack
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 50
Joined: Fri Sep 18, 2009 4:23 pm
Current Project: engine framework
Favorite Gaming Platforms: PC, XBox 360, PS3
Programming Language of Choice: C, C++
Location: Northern Virginia

Re: Seperating axis theorem

Post 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."
User avatar
MarauderIIC
Respected Programmer
Respected Programmer
Posts: 3406
Joined: Sat Jul 10, 2004 3:05 pm
Location: Maryland, USA

Re: Seperating axis theorem

Post 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.
I realized the moment I fell into the fissure that the book would not be destroyed as I had planned.
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: Seperating axis theorem

Post 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.
User avatar
Bakkon
Chaos Rift Junior
Chaos Rift Junior
Posts: 384
Joined: Wed May 20, 2009 2:38 pm
Programming Language of Choice: C++
Location: Indiana

Re: Seperating axis theorem

Post 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.
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: Seperating axis theorem

Post 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."
Post Reply