1

With the following code, collisions are detected, but sides are incorrectly registered.

public int checkBoxes(int aX, int aY, int aWidth, int aHeight, int bX, int bY, int bWidth, int bHeight){

    /*
     * Returns int
     * 0 - No collisions
     * 1 - Top
     * 2 - Left
     * 3 - Bottom
     * 4 - Right
     */

    Vector2f aMin = new Vector2f(aX, aY);
    Vector2f aMax = new Vector2f(aX + aWidth, aY + aHeight);

    Vector2f bMin = new Vector2f(bX, bY);
    Vector2f bMax = new Vector2f(bX + bWidth, bY + bHeight);

    float left = bMin.x - aMax.x;
    float right = bMax.x - aMin.x;
    float top = bMin.y - aMax.y;
    float bottom = bMax.y - aMin.y;

    if(left > 0) return 0;
    if(right < 0) return 0;
    if(top > 0) return 0;
    if(bottom < 0) return 0;

    int returnCode = 0;

    if (Math.abs(left) < right)
    {
        returnCode = 2;
    } else {
        returnCode = 4;
    }

    if (Math.abs(top) < bottom)
    {
        returnCode = 1;
    } else {
        returnCode = 3;
    }

    return returnCode;
}

When A is colliding with the top, left, or right of shape B, the number 3 is returned, and when colliding with the bottom, the number 1 is returned. I don't really know what's causing this. What is wrong with my code?

Jack Wilsdon
  • 6,706
  • 11
  • 44
  • 87

2 Answers2

2

With these if blocks, you'll always get 1 or 3 because second if block will always execute independent of what you've set in the first one.

if (Math.abs(left) < right)
{
    returnCode = 2;
} else {
    returnCode = 4;
}

if (Math.abs(top) < bottom)
{
    returnCode = 1;
} else {
    returnCode = 3;
}
auselen
  • 27,577
  • 7
  • 73
  • 114
  • Ah, so do I need to reverse the order, or modify the code in some way? – Jack Wilsdon Dec 22 '12 at 00:16
  • It now acts differently, the top, right and bottom being 4, and the left being 2. I'm starting to think it's something wrong with my maths. – Jack Wilsdon Dec 22 '12 at 00:21
  • 1
    I actually didn't think about your collision algorithm. However I don't understand it anyway. What would happen if they are overlapping? One inside another? how you can say it with your 4 state? – auselen Dec 22 '12 at 00:26
  • To be perfectly honest, I don't know. I was provided this code in ActionScript format, without an explanation. I have been trying to understand and run it, but to no avail. Hopefully someone can explain it. – Jack Wilsdon Dec 22 '12 at 00:32
  • Sorry i think it is my suggestion that's wrong. Now with this one it will be always 4 or 2 :) - removing from the answer. – auselen Dec 22 '12 at 00:45
1

The problem is you are checking for one side, but when you check for left by example and the bottom is also collided you are neglecting that one. I tested the code here: http://wonderfl.net/c/i90L

What I did was first getting the distances for the X and Y of the sides. And then checking which distance was the biggest, multiplied by the size of the rectangle itself, because that side will always be the good edge on a square.

    Vector2f returnCode = new Vector2f(0, 0);

    returnCode.x = (Math.abs(left) - right) * aWidth;
    returnCode.y = (Math.abs(top) - bottom) * aHeight;

    int temp = 0;

    if(returnCode.x > 0){
        //Hits left
        temp = 2;
    }else{
        //Hits right
        temp = 4;
    }

    if(returnCode.y > 0){
        //Hits top
        if(returnCode.y > Math.abs(returnCode.x)){
            temp = 1;
        }
    }else{
        //Hits bottom
        if(returnCode.y < -Math.abs(returnCode.x)){
            temp = 3;
        }
    }

    return temp;
tversteeg
  • 4,717
  • 10
  • 42
  • 77