【问题标题】:Easy Rotated Rectangle Collision容易旋转的矩形碰撞
【发布时间】:2013-04-06 09:54:35
【问题描述】:

我正在使用 LibGDX 制作游戏,但遇到了有关矩形碰撞检测的问题。

public class Rectangle{
   final float width = 1f;
   final float height = 0.5f;
   Point topLeft;
   Point topRight;
   Point bottomRight;
   Point bottomLeft;  
   //The point of rotation is the middle of the rectangle
   float angle;
}

public class Point{
   float x;
   float y;
}

使用这些信息(所有这些变量都将被预先计算),我想计算两个矩形是否完全重叠?

【问题讨论】:

  • “但我不确定如何继续检测它们的碰撞,到目前为止我搜索的内容非常复杂。” 还有..什么是你的问题?如果是“如何进行简单的旋转矩形碰撞?”,请注意。答案是“雇人”。
  • “简单”的方法可能是检查Rectangle2D.contains(x,y) 中的每一对代表另一个矩形的角的 4 个 x,y 对。
  • 我不相信 Rectangle 类有办法让矩形变角。
  • 如需尽快获得更好的帮助,请发帖SSCCE
  • 编辑了我的帖子,希望它能清除一些东西。

标签: java awt collision-detection java-2d rectangles


【解决方案1】:

如果两个矩形相交,则一个矩形内会有一个点,该点也在另一个矩形内。

您可以将每个矩形视为四行。要在矩形内,一个点必须在左线的右边、右线的左边、底线的上方和顶线的下方。所以一个矩形可以表示为一个有解的四个线性不等式的系统。

如果将一个矩形的四个线性不等式与另一个矩形的四个线性不等式组合成一个八不等式系统,则新系统只有在矩形相交时才有解。

【讨论】:

  • 这也是我最初的想法,但我认为它会很长,我会在几秒钟内发布代码。
【解决方案2】:

这是我最终使用的,请注意,我根本不想优化代码。

private boolean isColliding(Point p){
    float countCol = 0f;
    // BottomLeft - BottomRight
    float slope = ((player.getBottomLeft().getY() - player.getBottomRight().getY()) / (player.getBottomLeft().getX() - player.getBottomRight().getX()));
    float intercept = (player.getBottomLeft().getY() - (player.getBottomLeft().getX() * slope));

    // BottomLeft - TopLeft
    float slope2 = ((player.getBottomLeft().getY() - player.getTopLeft().getY()) / (player.getBottomLeft().getX() - player.getTopLeft().getX()));
    float intercept2 = (player.getTopLeft().getY() - (player.getTopLeft().getX() * slope2));

    // TopLeft - TopRight
    float slope3 = ((player.getTopLeft().getY() - player.getTopRight().getY()) / (player.getTopLeft().getX() - player.getTopRight().getX()));
    float intercept3 = (player.getTopRight().getY() - (player.getTopRight().getX() * slope3));

    // TopRight - BottomRight
    float slope4 = ((player.getTopRight().getY() - player.getBottomRight().getY()) / (player.getTopRight().getX() - player.getBottomRight().getX()));
    float intercept4 = (player.getBottomRight().getY() - (player.getBottomRight().getX() * slope4));

    // Between top and bottom
    if(player.getAngle() > -90 && player.getAngle() < 90){
        // BottomLeft - BottomRight
        if(p.getX() * slope + intercept < p.getY()){
            countCol += 1;
        }

        // TopLeft - TopRight
        if(p.getX() * slope3 + intercept3 > p.getY()){
            countCol += 1;
        }
    }
    else{
        // BottomLeft - BottomRight
        if(p.getX() * slope + intercept > p.getY()){
            countCol += 1;
        }

        // TopLeft - TopRight
        if(p.getX() * slope3 + intercept3 < p.getY()){
            countCol += 1;
        }
    }

    // BottomLeft - TopLeft
    if(player.getAngle() < 0){
        if(p.getX() * slope2 + intercept2 > p.getY()){
            countCol += 1;
        }
        if(p.getX() * slope4 + intercept4 < p.getY()){
            countCol += 1;
        }
    }
    else{
        if(p.getX() * slope2 + intercept2 < p.getY()){
            countCol += 1;
        }
        if(p.getX() * slope4 + intercept4 > p.getY()){
            countCol += 1;
        }
    }

    if(countCol >= 4){
        return true;
    }
    return false;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多