1

考虑一个 3D 太阳系模拟。

我的模拟循环:

[Calculate new positions]->[Render]->[Calculate new positions]->[Render] etc....

这个循环以 25FPS 的速度运行。

在我的模拟中,一颗行星正以非常快的速度向太阳移动(在碰撞过程中)。让我们看一下模拟循环:

  1. 计算行星和太阳的位置(它们尚未碰撞,但彼此非常接近)。
  2. 场景被渲染。
  3. 由于 FPS 不是无限的,因此在下一次迭代之前会有一个小的停顿。
  4. 计算行星和太阳的位置——这是我的问题的症结所在——它们没有发生碰撞,因为在“小暂停”期间,行星已经“穿过”太阳,它们的位置现在相距很远。碰撞检测算法不检测任何碰撞。

我在这里能看到的唯一解决方案是:

  • 提高FPS
  • 降低我的行星的速度(降低引力常数??)
  • 有一个单独的模拟循环,而不是在渲染循环旁边运行,但速度更快

对于任何感兴趣的人,我正在使用three.js

4

2 回答 2

3

射击游戏中的弹丸会发生。一种解决方案是让您的移动平台沿着前进路径拍摄一条线段,看看它是否会在下一帧之前撞到任何东西。这假设只有一个物体在快速移动。我想你也可以在最后一个位置和新位置之间运行一段,尽管我自己没有这样做。我也成功地将我的对撞机定义向前扩展为一个覆盖未检查区域的椭圆。

于 2013-04-04T05:34:49.940 回答
0

您可以查看两个物体之间的角度变化,如果这接近 180 度或 pi 弧度,那么它们很可能会发生碰撞。可以使用一点线性代数(使用点积)来计算两个对象之间的角度变化:

dx0 = object[i].x - object[j].x;
dy0 = object[i].y - object[j].y;
dz0 = object[i].z - object[j].z;
dx1 = object[i].x + timeStep * object[i].u - object[j].x - timeStep * object[j].u;
dy1 = object[i].y + timeStep * object[i].v - object[j].y - timeStep * object[j].v;
dz1 = object[i].z + timeStep * object[i].w - object[j].z - timeStep * object[j].w;
dangle = acos((dx0 * dx1 + dy0 * dy1 + dz0 * dz1) / (sqrt(dx0 * dx0 + dy0 * dy0 + dz0 * dz0) * sqrt(dx1 * dx1 + dy1 * dy1 + dz1 * dz1)));

您不必取反余弦,因为 cos(dangle) 将接近 -1 以使悬垂接近 180 度。

我不确定您应该采用哪个范围来成功检测碰撞,这部分需要进行一些试验和错误。而且我建议这不是碰撞检测的唯一步骤,并且在此检查之后它们会发生碰撞,假设两个物体在此时间步骤中以直线和恒定速度移动。要求解的方程将是一个二次方程,它可以有两个可能的答案(其中一个是它们是否会相互干扰并在另一侧发生碰撞)。但是,如果您对它们碰撞的确切时间不感兴趣,您仍然可以使用判别式来确定是否会发生碰撞。

于 2013-04-08T13:25:54.960 回答