【问题标题】:How can I detect if a ball is moving away from a wall?如何检测球是否正在远离墙壁?
【发布时间】:2010-08-29 16:00:31
【问题描述】:

球被定义为一个具有半径、位置和速度的圆,这是一个二维向量。墙由起点和终点定义。

我能够检测到球和墙壁之间的碰撞,并且知道如何将其反射到法线。然而,同样的碰撞可以再次被检测到,并且方向的变化被反复翻转,这意味着球基本上停止了移动。

所以真的需要一个简单的方法来说明一个球已经离开了球线,这样我就可以忽略任何额外的碰撞。

【问题讨论】:

  • Hitesh 的回答对我有用,因为我的球只能撞到墙的一侧,所以我可以交换起点和终点,使法线指向远离他们可以撞击的一侧,但威尔有一点,这并不适用于所有情况。

标签: collision-detection


【解决方案1】:

你需要在墙上有一个法线向量才能知道它的方向。在球速度矢量和壁法线之间进行点积。如果点积的结果大于零,则球正在远离墙壁。如果为零,则球平行移动,如果小于零,则球向墙壁移动。

补充说明:2010-08-29 18:17

关于墙何时支持双方碰撞的情况出现了一个问题。要正确处理碰撞,您必须回答两个问题:球当前在墙的哪一侧(“内侧”或“外侧”)以及它相对于墙法线的移动方向是什么?如何确定第二个问题的答案上面已经回答了。

要回答关于球是在墙“内”还是“外”的问题,首先要计算从球到墙的向量(墙上的一点 - 球的中心)。取该向量与壁法向量的点积。如果结果小于零,则球在墙“外”。等于零在墙上,大于零在墙内。

然后你就有了两个问题的答案。球目前是在墙的“里面”还是“外面”,它目前是在向墙的“里面”还是“外面”移动。

【讨论】:

    【解决方案2】:

    Hitesh 的回答实际上是错误的,因为线的法线可以指向垂直于线的任一方向。这是我一开始想解决问题的方法,但很快意识到这是行不通的。

    球:xb, yb, radius, vx, vy

    墙:x1, y1, x2, y2

    float Ang1 = atan2(y1-yb, x1-xb);
    float Ang2 = atan2(y2-yb, x2-xb);
    float AngB = atan2(vy, vx);
    
    //Catch cases where the wall straddles the change from 2pi radians to 0 radians
    //and revolve all the angles around by pi to avoid the problem
    //Can only happen in a specific region, this can be done easily by adding 2pi to
    // any negative angles.
    
    Ang1 = (Ang1 < 0) ? Ang1 + 2 *PI : Ang1;
    Ang2 = (Ang2 < 0) ? Ang2 + 2 *PI : Ang2;
    AngB = (AngB < 0) ? AngB + 2 *PI : AngB;
    
    AngU = max(Ang1, Ang2);
    AngL = min(Ang1, Ang2);
    
    bool Towards = (AngL < AngB && AngB < AngU) ? true : false;
    

    【讨论】:

    • 如果最近壁面的法线指向远离球,则球在壁内。另外,请注意 arctan() 并非在所有象限中都是唯一的。
    • @David Lively:尽管他只使用两个点来定义每面墙,所以每面墙实际上只是一条线,没有深度,因此没有“墙内”的定义。此外,我使用 atan2 的原因是 arctan() 不是唯一的; en.wikipedia.org/wiki/Atan2
    【解决方案3】:

    也许不是最好的方法,但你可以将球放置在离墙壁很小的地方......否则我认为了解更多关于你的设计会很好......

    【讨论】:

      【解决方案4】:

      只是一个想法.. 如果您知道球已经撞到了墙上 - 使用某种这样的标志怎么样。一旦检测到碰撞 - 将此标志设置为 true。 更具体地说 - 如果你有一些墙壁,并且球不能相互碰撞 - 为每个代表天气的球添加一组布尔值,或者它是否与每个墙壁发生碰撞。将其初始化为全假。一旦检测到碰撞 - 将对应墙的值设置为 true,这样您就知道不要寻找同一个球与同一个墙的碰撞。一旦你检测到球与另一面墙碰撞 - 将数组的所有值设置为 false,除了最后一个碰撞的墙。显然,一个球在撞到另一堵墙之前不能与同一堵墙发生两次碰撞(同样,假设墙是直的,球不会相互碰撞,而且球会朝直线方向移动……不假设这些需要更多的工作:) )

      这是你要找的还是我没有得到你的问题?

      【讨论】:

      • 我想过这样做,这无疑会奏效,但检查是否分开似乎更干净。
      猜你喜欢
      • 2018-03-22
      • 2022-01-19
      • 2016-04-24
      • 2021-06-20
      • 1970-01-01
      • 2018-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多