物理模拟基础知识
考虑三维太阳系模拟。物理模拟基础知识
我的模拟循环:
[Calculate new positions]->[Render]->[Calculate new positions]->[Render] etc....
这个循环的,比方说,25FPS运行。
我的模拟中的一颗行星非常快地向着太阳行进(在碰撞过程中)。让我们看看模拟循环:
- 位置计算为行星和太阳(他们还没有相互碰撞,但彼此非常接近)。
- 场景呈现。
- 由于FPS不是无限的,在下一次迭代之前会有一个小的停顿。
- 位置是计算行星和太阳 - 这是我的问题的关键 - 他们没有相撞,因为在'小暂停'行星已经'穿过'太阳,他们的位置现在是一个很大的距离。碰撞检测算法不检测任何碰撞。
唯一的解决方案,我可以在这里看到:
- 提高FPS
- 下我的行星的速度(降低引力常数?)
- 有一个独立的仿真循环比沿着渲染循环运行,但速度更快
对于任何感兴趣的人,我使用的是three.js。
在射击游戏中发生射弹。一个解决方案是让你的运动舞台沿着前进路径拍摄一条线段,看看它是否会在下一帧之前触及任何东西。这假定只有一个对象正在快速移动。我想你也可以在最后的位置和新的位置之间运行一段,尽管我自己并没有这样做。我也成功地将我的对撞机定义向前扩展到覆盖未检查区域的椭圆。
你可以看看两个物体之间的角度变化,如果这将接近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度。
我不确定你应该采取哪一个范围来成功检测到碰撞,这一部分有点试错。我认为这不是碰撞检测中的唯一步骤,并且在此检查之后它们会发生碰撞,假定在这个时间步骤中两个物体以直线和恒定速度移动。 要解决的方程将是一个二次方程,它可以有两个可能的答案(其中之一是如果他们会相互干扰并在另一侧相撞)。但是如果你对它们相撞的确切时间不感兴趣,你仍然可以使用判别式来确定是否会发生碰撞。
对于手头的问题似乎过于复杂。 – Monkeyanator 2013-04-29 14:27:13
很高兴听到我并不孤单。感谢DrC。我会解决你的问题。 – JoeRocc 2013-04-04 16:15:55