【问题标题】:Intersection between Rectangle and a Circle sector in libgdxlibgdx中矩形和圆形扇区之间的交集
【发布时间】:2014-01-15 08:53:19
【问题描述】:

我正在使用 libgdx 编写游戏。对于敌人,我想写一个简单的 AI。如果玩家曾经在视野中,这个 AI 应该会跟踪玩家。视野是一个圆形扇区或二维圆锥。实现这一目标的最有效方法是什么?我已经阅读了以下内容: Point in circle sector

我可以在我的播放器的每个角点上使用它,但我也有带有方向和角度的视野(direction - angle/2direction + angle/2 之间的扇区)。 角度不会超过 180 度(因为这对算法来说是个问题)。为游戏中的每个敌人计算扇区开始和结束的向量会是个问题吗?最好的解决方案是什么?如何根据给定的方向和角度计算向量?

【问题讨论】:

    标签: java algorithm libgdx intersection


    【解决方案1】:

    您可以使用链接帖子中描述的解决方案,但您必须通过计算 dir +/- angle/2 的正弦和余弦将角度转换为矢量。链接的解决方案讨论整数算术,但您的向量将是浮点数:

    arm1 = [cos(d - 0.5 * a), sin(d - 0.5 * a)]
    arm2 = [cos(d + 0.5 * a), sin(d + 0.5 * a)]
    

    cossin 的参数以弧度表示。 x 方向的零点角度,即传统笛卡尔坐标系中的东。

    为了不做不必要的工作,你应该先检查容易的事情。

    在检查与扇区的交点之前,我会做一个简单的方框检查:如果矩形的所有四个角点都在敌人周围的方框之外,则没有交点:

    if (x0 < x-r && x1 < x-r && x2 < x-r && x3 < x-r) return false;
    if (x0 > x+r && x1 > x+r && x2 > x+r && x3 > x+r) return false;
    if (y0 < y-r && y1 < y-r && y2 < y-r && y3 < y-r) return false;
    if (y0 > y+r && y1 > y+r && y2 > y+r && y3 > y+r) return false;
    

    这个简单的检查应该可以排除很多敌人。

    接下来,检查链接答案中描述的所有四个点的半径,如果您的角点都不在半径内,则返回 false。

    只是现在我们必须用三角函数计算向量。您可以使用上面给出的公式来做到这一点。如果你已经有了敌人和角度的正余弦,你可以使用addition theoremes加速向量计算:

    # sin_d = sin(d), cos_d = cos(d)
    # sin_a = sin(0.5 * a), cos_a = cos(0.5 * a)
    
    arm1 = [cos_d * cos_a + sin_d * sin_a, sin_d * cos_a - cos_d * sin_a]
    arm2 = [cos_d * cos_a - sin_d * sin_a, sin_d * cos_a + cos_d * sin_a]
    

    每个敌人的视角可能是一个常数,因此您可以预先计算它,并且您可能已经预先计算了 cos_dsin_d

    如果您不关心准确性并且不想进入弧度,您可以预先计算 1 度步长的正弦和余弦并将它们存储在大小为 360 的两个数组中。然后计算正弦将成为问题查找数组,即它会很快,并且您可以进行所有计算 n 度。 (但要注意包裹:5° - 15° 应该是 350°,而不是 -10°。)

    【讨论】:

    • 非常感谢(:我不需要非常准确,因为它只是为了说敌人来跟踪玩家。只是一个小问题:我为什么要先检查框然后检查半径检查?半径检查不会花费太多,因为它只是将中心之间的平方距离与视野和玩家的平方半径进行比较(实际上我的玩家和敌人都是圆圈,因为它们可以旋转,旋转圆圈更容易然后旋转矩形:P)。那么我可以让该框在不损失性能的情况下检查吗?
    • @Springrbua:当您不计算平方根时,半径检查可能会执行得更好,您是对的。您可以通过比较带有和不带有附加复选框的性能来轻松检查这一点。
    • 我不使用平方根(这没有意义)。所以我做半径检查,然后是顺时针和逆时针检查。
    • 是的,我知道在这里调用 sqrt 是多余的。链接的答案还比较了半径的平方。我认为方框检查比计算平方距离要快(直觉上也不差),但我可能错了,它增加了不必要的开销:只要检查距离就足够了。
    • @M Oehm 我找到了另一种可能的解决方案:我有敌人的旋转,以及玩家和敌人之间的角度(相对于 x 轴)。我不能检查它们之间的角度是否在公差范围内(可以说 enemie.getRotation() + 20 >= 它们之间的角度 >= enemie.getRotation() - 20)。而且距离检查保持不变。这不是更容易吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    • 1970-01-01
    • 2013-03-27
    • 2023-01-26
    • 2023-04-01
    • 1970-01-01
    相关资源
    最近更新 更多