轴对齐矩形碰撞检测 - Java

时间:2015-01-04 05:42:05

标签: java collision-detection rectangles

我有一些问题,检查2个矩形是否有 4分的碰撞,所以我有 rect1 p1(x,y)左下角右上角的p2(x,y),与 rect2 相同。


所以这是我的图表插图

Image

到目前为止,这是我的示例代码:

    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");
    }

我不确定我是否正确使用此代码,是否有人可以提出我的想法? (我是初学者!)

2 个答案:

答案 0 :(得分:0)

简答:是

基本上你有四个条件你必须检查以确保你有碰撞的矩形:

  • 第一个矩形的右上角必须位于第二个左下角的右侧
  • 第一个矩形的右上角必须位于第二个左下角的上方
  • 第一个矩形的左下角必须留在第二个右上角
  • 第一个矩形的左下角必须位于第二个右上角的下方

重构您的代码,如下所示,如何满足上述四个条件将更加清晰:

public class HelloWorld {

     public static void main(String []args){
        int[][] rect1 = {{1,5},{4,8}};
        int[][] rect2 = {{4,1},{7,4}};
        if( isRect1UpperRightCornerRightOfRect2BottomLeftCorner(rect1, rect2) && 
            isRect1UpperRightCornerAboveRect2BottomLeftCorner(rect1, rect2) && 
            isRect1BottomLeftCornerLeftOfRect2UpperRightCorner(rect1, rect2) && 
            isRect1BottomLeftCornerBelowRect2UpperRightCorner(rect1, rect2) ) {
            System.out.println("Collision");
        } else {
            System.out.println("No Collision");
        }
     }

     private static boolean isRect1UpperRightCornerRightOfRect2BottomLeftCorner(int[][] rect1, int[][] rect2) {
        return rect1[1][0] >= rect2[0][0];
     }

     private static boolean isRect1UpperRightCornerAboveRect2BottomLeftCorner(int[][] rect1, int[][] rect2) {
         return rect1[1][1] >= rect2[0][1];
     }

     private static boolean isRect1BottomLeftCornerLeftOfRect2UpperRightCorner(int[][] rect1, int[][] rect2) {
         return rect1[0][0] <= rect2[1][0];
     }

     private static boolean isRect1BottomLeftCornerBelowRect2UpperRightCorner(int[][] rect1, int[][] rect2) {
         return rect1[0][1] <= rect2[1][1];
     }
}

here is a good interactive website还可以直观地展示上述内容是如何运作的。注意角落是翻转的。

答案 1 :(得分:0)

首先,您的代码不会在if块中编译。有一个无与伦比的开括号。我会将其删除。

所以,让我们添加一些中间变量来更好地看到代码的含义:

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");
}

现在,让我们分开每个轴的逻辑:

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");
}

我们怎样才能让一个轴发生碰撞?这两个对象如何沿着轴相对于彼此定位有15种形式:

案例1 - 完全重合碰撞:

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

案例2,3,4,5,6和7--完全非重合碰撞:

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


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

案例8和9 - 部分碰撞:

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

案例10和11 - 几乎碰撞:

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

案例12和13 - 只是触摸(不碰撞):

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

案例14和15--相隔很远(没有碰撞):

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

您的代码应将案例1到11与每个轴中的案例12到15分开。让我们看看它的作用:

boolean xCollides = rect1X2 >= rect2X1 && rect1X1 <= rect2X2;
  • 案例1:真实而真实 - &gt;真
  • 案例2:真实而真实 - &gt;真
  • 案例3:真实而真实 - &gt;真
  • 案例4:真实而真实 - &gt;真
  • 案例5:真实而真实 - &gt;真
  • 案例6:真实而真实 - &gt;真
  • 案例7:真实而真实 - &gt;真
  • 案例8:真实而真实 - &gt;真
  • 案例9:真实而真实 - &gt;真
  • 案例10:真实而真实 - &gt;真
  • 案例11:真实而真实 - &gt;真
  • 案例12:错误和真实 - &gt;假
  • 案例13:真假 - &gt;假
  • 案例14:错误和真实 - &gt;假
  • 案例15:真假 - &gt;假

因此,您的代码能够将情况1到11与情况12到15分开,因此对于X轴是正确的。轴Y的代码等同于X轴的代码(正好在不同的轴下) ),所以它也是正确的。 最后,我们得出结论,您的整个代码都是正确的。