【问题标题】:Detecting the Direction of a Collision检测碰撞方向
【发布时间】:2018-11-02 23:58:27
【问题描述】:

一个方形瓷砖与另一个方形瓷砖碰撞。调酒师说……

我有:

  • 两个图块的高度、宽度、x 和 y。
  • 导致碰撞的运动的 2D 矢量。

我需要知道碰撞发生在哪一侧(例如顶部、底部、左侧、右侧),以便适当地重置位置。

我会给能回答这个问题的人一个心理饼干,因为我已经尝试了太多小时,这似乎很重要。

【问题讨论】:

  • 您是在寻找任何特定语言的编码解决方案还是只是算法提示?
  • 我在 node.js javascript 中对此进行编码,但实际上这只是一个算法问题。就数学库而言,我无法访问任何特别花哨的东西。
  • 实际上,在考虑了一会儿之后,根据给定的信息,不可能计算出影响的一面,因为说 r1 在 r2 上向下移动,然后剪辑,在两侧重叠,然后在 1 侧重叠,然后在 相反 侧的 2 侧重叠,然后离开。我怎么知道我是在计算接触重叠还是离开重叠...
  • 嗯,你知道引导它通过的向量,所以你知道原始位置是什么。这应该可以确定哪一个是正确的。
  • 基本上,您在这里所能做的就是使用坐标 r1 和 r2 以及移动矩形的速度来预测(使用 y=mx+b)它将在哪里发生碰撞,而不是使用实际的碰撞检测

标签: collision-detection


【解决方案1】:
float player_bottom = player.get_y() + player.get_height();
float tiles_bottom = tiles.get_y() + tiles.get_height();
float player_right = player.get_x() + player.get_width();
float tiles_right = tiles.get_x() + tiles.get_width();

float b_collision = tiles_bottom - player.get_y();
float t_collision = player_bottom - tiles.get_y();
float l_collision = player_right - tiles.get_x();
float r_collision = tiles_right - player.get_x();

if (t_collision < b_collision && t_collision < l_collision && t_collision < r_collision )
{                           
//Top collision
}
if (b_collision < t_collision && b_collision < l_collision && b_collision < r_collision)                        
{
//bottom collision
}
if (l_collision < r_collision && l_collision < t_collision && l_collision < b_collision)
{
//Left collision
}
if (r_collision < l_collision && r_collision < t_collision && r_collision < b_collision )
{
//Right collision
}

当对象在另一个对象中时,这并不能解决。但它确实适用于重叠

【讨论】:

  • 只是想对此进行扩展,因为目前还不清楚这里发生了什么:播放器/瓷砖底部和右侧分别代表播放器和瓷砖的底部和右侧。 b_collision 表示瓷砖底部和玩家顶部之间的距离。如果玩家从底部与瓷砖碰撞,这是最小的边之间的距离,这正是检查是否确实存在底部碰撞的内容。检查其他碰撞与其他方面做同样的事情。
【解决方案2】:

给定 r1 ​​和 r2(r2 是静止的),首先找到 r2 到 r1 的最近角。 这个点是 (c1.x,c1.y),现在想象你将它扩展到两个平面,一个平行于 x 轴,一个平行于 y。

现在获取 r1 到 r2 的最近角(称为 c2)并在以下公式中使用它 y = mx + b 其中 b 是 c2.x m 是你的向量。 x 是 c1.x

因此,如果 y 大于 c1.y,则意味着在 x 接触点(宽度)处,您已经到达顶部。如果它更少,那么你还没有击中它。 反转底部/顶部。

【讨论】:

  • 请记住,我不是逐像素移动,而是使用矢量移动。如果不止一侧重叠会怎样?
  • 我已经更新了我的答案,它并不准确,但我认为通过一些矢量数学你可以找到某个地方......
【解决方案3】:

假设您有一种方法可以检测碰撞,那么了解哪些侧面发生了碰撞就很简单了。您只需检查每个方格的xy 位置。

Square1 : (x1, y1)
Square2:(x2, y2)

我将假设您的工作区的左上角是(0,0),并且x 值会随着您向右移动而增加,y 值会随着您向下移动而增加。

考虑到这一点:

如果 (x1 如果 (x1 > x2),则正方形 1 的左侧与正方形 2 的右侧相撞
如果 (y1 if (y1 > y2), 方格 1 的上边与方格 2 的下边相撞

我建议你自己画几张图,你应该就清楚了。

【讨论】:

  • 我知道如何检测顶部与底部和左侧与右侧——但是当顶部和左侧重叠时会发生什么?我的麻烦是弄清楚哪个先重叠。
  • 取 x1 和 x2 以及 y1 和 y2 的差。较大的(绝对)差异将是首先受到影响的一方。
  • 这不一定是真的。如果您有向上英寸的宽矩形,那么碰撞应该从顶部/底部开始,但考虑到宽度,x2-x1 差异会大得多
  • Joe 所说的——这类似于我的第一次尝试,然后我意识到了这种极端情况。
  • 你是对的 - 我的错 - 我的借口是我在深夜:P
【解决方案4】:
  if(player.y <= wall.y + wall.height && player.y > wall.y || player.y + player.height  <= wall.y+wall.height && player.y + player.height > wall.y){
            if(player.x -2< wall.x + wall.width && player.x > wall.x){
                leftspeed = 0
            }else if(player.x + player.width +2 > wall.x && player.x + player.width < wall.x + wall.width){
                rightspeed = 0
            }
        }

        if(player.x <= wall.x + wall.width && player.x > wall.x || player.x + player.width  <= wall.x+wall.width && player.x + player.width > wall.x){
            if(player.y -2 < wall.y + wall.height && player.y > wall.y){
                upspeed = 0
            }else  if(player.y + player.height +2> wall.y && player.y + player.height < wall.y + wall.height){
                downspeed = 0
            }
        }

这应该可行,您可能想要删除的所有内容周围都有 2 个像素的边距

【讨论】:

    【解决方案5】:

    您也必须对正方形进行建模以捕捉方向,只需使用正方形的 (x,y,height) ,方向我的意思是它是否在第四象限的第一、第二、第三象限中,可能是通过对所有四个角进行建模正方形的顶点。

    那么你需要确定构成这个正方形的所有四个向量

    求二维向量与正方形各边之间的余弦 例如,如果给定边的余弦和 2D Vector 为 1 ,那么它们都是正交的或 0 它们是垂直的,任何其他值都将落在两者之间

    或任何其他关于如何确定/定义碰撞的向量代数技巧!

    【讨论】:

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