【问题标题】:Collision detection between two rectangles in javajava中两个矩形之间的碰撞检测
【发布时间】:2020-06-21 07:51:20
【问题描述】:

我有两个矩形,红色矩形(可以移动)和蓝色矩形。 两者都有:x、y、宽度、高度。

当蓝色和红色矩形之间发生冲突时,我如何用 Java 等编程语言表达?

【问题讨论】:

    标签: java algorithm collision-detection


    【解决方案1】:
    if (RectA.X1 < RectB.X2 && RectA.X2 > RectB.X1 &&
        RectA.Y1 < RectB.Y2 && RectA.Y2 > RectB.Y1) 
    

    假设你有 Rect A 和 Rect B。证明是矛盾的。四个条件中的任何一个都保证不存在重叠:

    Cond1. If A's left edge is to the right of the B's right edge, - then A is Totally to right Of B
    Cond2. If A's right edge is to the left of the B's left edge, - then A is Totally to left Of B
    Cond3. If A's top edge is below B's bottom edge, - then A is Totally below B
    Cond4. If A's bottom edge is above B's top edge, - then A is Totally above B
    So condition for Non-Overlap is
    
    Cond1 Or Cond2 Or Cond3 Or Cond4
    

    因此,重叠的充分条件是相反的(德摩根)

    非 Cond1 且非 Cond2 且非 Cond3 且非 Cond4 这相当于:

    A's Left Edge to left of B's right edge, and
    A's right edge to right of B's left edge, and
    A's top above B's bottom, and
    A's bottom below B's Top
    

    注 1:很明显,同样的原理可以扩展到任意数量的维度。 注意 2:仅计算一个像素的重叠也应该是相当明显的,将该边界上的 更改为 =。

    如果您很难想象它的工作原理,我在 silentmatt.com/intersection.html 上制作了一个示例页面,您可以在其中拖动矩形并查看比较。

    【讨论】:

    • @dopatraman BufBills 的 if 条件只是说明解决方案的伪代码。 RectA.X1 代表矩形 A 的左边缘,RectA.X1 &lt; RectB.X2 表示“A 的左边缘在 B 的右边缘的左侧”。如何在 Java 中实现它是您的决定。
    • OP 明确要求在 Java 中实现。至少接受的答案应该是可运行的代码。
    • @dopatraman 如果您决定使用具有矩形边缘坐标的 X1、X2、Y1、Y2 属性的类对矩形进行建模,并且如果您使用变量 RectA 和 RectB 来引用两个矩形对象,那么您可以按原样使用 BufBills 的 if 条件。它是有效的 Java 代码,这正是 OP 所要求的。否则,OP 不会接受答案。
    • 这似乎不适用于旋转的矩形。在纸上,我有一个旋转 45 度的大矩形和一个靠近大矩形边缘线的非常小的矩形,它似乎满足所有条件,但没有包含在矩形中或与之相交。
    【解决方案2】:

    在java中,检测两个矩形是否碰撞时,可以使用intersects()方法

    示例代码:

    Rectangle r1 = new Rectangle(x1,y1,x2,y2);
    Rectangle r2 = new Rectangle(x1,y1,x2,y2);
    if(r1.intersects(r2))
    {
        //what to happen when collision occurs goes here
    }
    

    【讨论】:

    • 我的意思是,如果你为这个问题做采访。没有人期望您使用库来解决这个算法问题。不过,很高兴知道有一个矩形库:D
    • 我赞成这个答案,只是因为问题中没有说明他正在寻找解决这个问题的算法,只是寻找解决方案。
    • @BufBills ,哦,对不起,直到你提到我才注意到算法标签,我应该把这个答案记下来吗?
    【解决方案3】:
    bool isIntersect(
      int Ax, int Ay, int Aw, int Ah,
      int Bx, int By, int Bw, int Bh)
    {
      return
        Bx + Bw > Ax &&
        By + Bh > Ay &&
        Ax + Aw > Bx &&
        Ay + Ah > By;
    }
    

    【讨论】:

      【解决方案4】:

      您必须检查沿 x 轴和沿 y 轴的交点。如果缺少其中任何一个,则矩形之间不会发生碰撞。

      一维代码:

      boolean overlaps(double point1, double length1, double point2, double length2)
      {
          double highestStartPoint = Math.max(point1, point2);
          double lowestEndPoint = Math.min(point1 + length1, point2 + length2);
      
          return highestStartPoint < lowestEndPoint;
      }
      

      你必须同时为 x 和 y 调用它:

      boolean collision(double x1, double x2, double y1, double y2, double width1, double width2, double height1, double height2)
      {
          return overlaps(x1, width1, x2, width2) && overlaps (y1, height1, y2, height2);
      }
      

      【讨论】:

        【解决方案5】:
        1. 计算第一个矩形的 4 个点。将它们记为 pointA、pointB、pointC、pointD。
        2. 计算第二个矩形的 4 个点。将它们记为点 E、F、G H。

        3. 迭代点 E、F、G、H (1) 如果其中任何一个位于 A、B、C、D 所包围的区域内。返回碰撞。 (2) 否则不会发生碰撞。

        对于 3.(1) 算法。你需要这样的东西。

        Xe >= Xa && Xc = Yc && 叶

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-10-30
          • 1970-01-01
          • 2023-01-26
          • 1970-01-01
          • 2016-04-05
          • 2014-05-05
          • 2011-08-17
          • 1970-01-01
          相关资源
          最近更新 更多