Search code examples
javacollision-detectionrectangles

Axis Aligned Rectangle Collision Detection - Java


I have some problem checking if the 2 rectangles has a collision given with 4 points, so I have a rect1 with p1(x,y) for lower left corner and p2(x,y) for upper right corner, same as rect2.


So this is my graph illustration:

Image

This is my sample code so far:

    int[][] rect1 = {{2,0},{3,1}};
    int[][] rect2 = {{0,0},{1,2}};
    if(rect1[1][0] >= rect2[0][0] && rect1[1][1] >= rect2[0][1] && rect1[0][0] <= rect2[1][0] && rect1[0][1] <= rect2[1][1])
    {
        System.out.println("Collision");
    } else {
        System.out.println("No Collision");
    }

I'm not pretty sure if I got it correctly with this code, can anyone give my some idea? (I'm beginner!)


Solution

  • First, your code do not compiles in the if block. There is an unmatched opening parenthesis. I will remove it.

    So, lets add some intermediate variables to better see the meaning of the code:

    int[][] rect1 = {{2,0},{3,1}};
    int[][] rect2 = {{0,0},{1,2}};
    
    int rect1X1 = rect1[0][0];
    int rect1X2 = rect1[1][0];
    int rect1Y1 = rect1[0][1];
    int rect1Y2 = rect1[1][1];
    
    int rect2X1 = rect2[0][0];
    int rect2X2 = rect2[1][0];
    int rect2Y1 = rect2[0][1];
    int rect2Y2 = rect2[1][1];
    
    if (rect1X2 >= rect2X1 && rect1Y2 >= rect2Y1 && rect1X1 <= rect2X2 && rect1Y1 <= rect2Y2)
    {
        System.out.println("Collision");
    } else {
        System.out.println("No Collision");
    }
    

    Now, lets separate the logic of each axis:

    int[][] rect1 = {{2,0},{3,1}};
    int[][] rect2 = {{0,0},{1,2}};
    
    int rect1X1 = rect1[0][0];
    int rect1X2 = rect1[1][0];
    int rect1Y1 = rect1[0][1];
    int rect1Y2 = rect1[1][1];
    
    int rect2X1 = rect2[0][0];
    int rect2X2 = rect2[1][0];
    int rect2Y1 = rect2[0][1];
    int rect2Y2 = rect2[1][1];
    
    boolean xCollides = rect1X2 >= rect2X1 && rect1X1 <= rect2X2;
    boolean yCollides = rect1Y2 >= rect2Y1 && rect1Y1 <= rect2Y2;
    
    if (xCollides && yCollides)
    {
        System.out.println("Collision");
    } else {
        System.out.println("No Collision");
    }
    

    How can we get a collision for one axis? There are 15 forms of how the two objects are positioned along an axis in relation to each other:

    Case 1 - Full coincident collision:

    X-----X
    X-----X
    

    Cases 2, 3, 4, 5, 6 and 7 - Full non-coincident collision:

    X---X              X---X          X-----X
    X-----X          X-----X            X---X
    
    
    X-----X            X-X            X-----X
      X-X            X-----X          X---X
    

    Cases 8 and 9 - Partial collision:

    X---X              X---X
      X---X          X---X
    

    Cases 10 and 11 - Barely colliding:

    X--X                X--X
       X--X          X--X
    

    Cases 12 and 13 - Just touching (not colliding):

    X--X                 X-X
        X-X          X--X
    

    Cases 14 and 15 - Far apart (not colliding):

    X-X                  X-X
        X-X          X-X
    

    Your code should separate the cases 1 to 11 from the cases 12 to 15 in each axis. Lets see what it does:

    boolean xCollides = rect1X2 >= rect2X1 && rect1X1 <= rect2X2;
    
    • Case 1: true and true -> true
    • Case 2: true and true -> true
    • Case 3: true and true -> true
    • Case 4: true and true -> true
    • Case 5: true and true -> true
    • Case 6: true and true -> true
    • Case 7: true and true -> true
    • Case 8: true and true -> true
    • Case 9: true and true -> true
    • Case 10: true and true -> true
    • Case 11: true and true -> true
    • Case 12: false and true -> false
    • Case 13: true and false -> false
    • Case 14: false and true -> false
    • Case 15: true and false -> false

    So, your code is able to separate the cases 1 to 11 from cases 12 to 15, and thus it is correct for axis X. The code for axis Y is equivalent to the code to axis X (just under a different axis), so it is also correct. Finally, we conclude that your entire code is correct.