线段和圆碰撞算法

时间:2015-11-27 08:44:29

标签: python game-physics

我的游戏中有一个能够使用激光杀死僵尸的机器人。我一直在浏览论坛以获得这个问题的答案,有些人提到投影是最简单的方法。我还听说过,如果你让线段成为一个更容易的实际无限线。如果无限指的是一个如此长的激光,它从屏幕的一个角落到相对的角落,那么我就可以做到。你必须记住这个激光基本上是一个矩形图片。我的机器人也可以旋转到位,所以我希望激光器也可以旋转。所以基本上我想知道如何检测将被建模为圆形的僵尸与我的激光之间的碰撞,该激光将被建模为线段或无限线。

1 个答案:

答案 0 :(得分:0)

慢速方法是沿着激光运行一个点,检查它是否可以触及任何僵尸"。

def distance(x1, y1, x2, y2):
  """Returns the distance between (x1, y1) and (x2, y2)."""
  return math.sqrt((x2 - x1) **2 + (y2 - y1) ** 2)

def check_laser_beam(sx, sy, dx, dy, zombies):
  """Runs a point along a laser beam, checking if it hits any zombie."""

  # Start the laser at the origin
  lx = sx
  ly = sy

  # run a point along the laser, until we hit the edge of the screen
  while onscreen(lx, ly):
    for z in zombies:
       if distance(lx, ly, z.x, z.y) < ZOMBIE_SIZE:
          return z
  return None

这是非常低效的,基本上与僵尸的数量成比例,乘以到屏幕边缘的距离。但是,它很简单,可以简单地将其识别为正确。

它还为我们提供了如何更快地解决这个问题的提示。以上代码的作用是查看光束是否截取半径为ZOMBIE_SIZE的圆,以任何僵尸为中心。

我们可以将该线建模为一般&#34; a x + b y = t&#34;我们可以将我们的圆形僵尸的周长建模为&#34;(x - zx)** 2 +(y - zy)** 2 = r ** 2&#34; (只有x和y是变量,zx,zy和r是常量)。这可以转化为方程组,可以机械地求解。如果你得到两个解决方案,光束肯定会通过&#34;圆形僵尸&#34;,如果你得到一个解决方案,它只会切断僵尸。如果你没有得到任何解决方案,它根本就不会拦截僵尸。