物理模拟基础知识

问题描述:

考虑三维太阳系模拟。物理模拟基础知识

我的模拟循环:

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

这个循环的,比方说,25FPS运行。

我的模拟中的一颗行星非常快地向着太阳行进(在碰撞过程中)。让我们看看模拟循环:

  1. 位置计算为行星和太阳(他们还没有相互碰撞,但彼此非常接近)。
  2. 场景呈现。
  3. 由于FPS不是无限的,在下一次迭代之前会有一个小的停顿。
  4. 位置是计算行星和太阳 - 这是我的问题的关键 - 他们没有相撞,因为在'小暂停'行星已经'穿过'太阳,他们的位置现在是一个很大的距离。碰撞检测算法不检测任何碰撞。

唯一的解决方案,我可以在这里看到:

  • 提高FPS
  • 下我的行星的速度(降低引力常数?)
  • 有一个独立的仿真循环比沿着渲染循环运行,但速度更快

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

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

+0

很高兴听到我并不孤单。感谢DrC。我会解决你的问题。 – JoeRocc 2013-04-04 16:15:55

你可以看看两个物体之间的角度变化,如果这将接近180度或pi弧度,它们很可能会碰撞。 计算两个物体之间角度的变化可以用线性代数的一点点(使用dot product)来完成:

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(悬)将接近-1的吊环接近180度。

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

+0

对于手头的问题似乎过于复杂。 – Monkeyanator 2013-04-29 14:27:13