1 分子动力学模拟:hard discs 模型(Molecular dynamics simulation of hard discs)
目标:根据弹性碰撞定律(the laws of elastic collision)模拟 n 个运动粒子的运动^1
hard discs 模型:
- 移动粒子通过相互弹性碰撞以及与墙壁弹性碰撞相互作用
- 每个粒子都是一个已知位置、速度、质量和半径的圆盘
- 没有其他力量
意义:涉及到通过宏观(温度,压力,扩散常数)观测微观动力学(单个原子和分子的运动)
- 麦斯威尔-玻尔兹曼(Maxwell-Boltzmann):速率分布是温度的函数
- 爱因斯坦(Einstein):解释花粉颗粒的布朗运动
2 无碰撞弹球(bouncing balls without the collisions)
事件驱动模拟(Time-driven simulation):一个独立方格里有 N 个弹球
只根据球的速度和与墙壁的碰撞计算球的位置
1 | public class BouncingBalls |
1 | public class Ball |
缺点:没有检测球之间的相互碰撞
- 物理问题:什么时候发生碰撞?碰撞产生的影响?
- CS 问题:由哪个 object 来检测碰撞?当检测很多时能否将时间复杂度控制在 O(logn)?
3 时间驱动模拟(Time-driven simulation)
对于 dt 个单位时间,如图 1:
- 在 dt 个单位时间后,更新每个粒子的位置,并检测是否重叠
- 如果重叠,回滚到碰撞发生的时刻,更新碰撞粒子的速度,并继续模拟
主要的缺点:
- 每个时间段需要执行 ~ $\frac{N^2}{2}$ 次重叠检查
- 如果 dt 太小,模拟会非常慢
- 如果 dt 太大,可能会错过碰撞
4 事件驱动模拟(Event-driven simulation)
只有当某事发生时才改变状态
- 在碰撞之间,粒子按轨迹直线运动
- 只关注碰撞发生的时间
- 维护一个碰撞事件的优先队列(PQ),按时间排列
- 删除 min = 得到下一次碰撞(我们从 PQ 中删除的最小元素就是我们下次要处理的碰撞)
碰撞预测(Collision prediction):给定一个粒子的位置,速度和半径,它下一次和墙壁或另外一个球碰撞发生的时间?
当一个粒子在其它粒子之前通过交叉点,发生碰撞(见图 2)
碰撞处理(Collision resolution):如果发生碰撞,根据弹性碰撞定律更新碰撞粒子
碰撞后两个粒子的速度均发生变化(见图 2)
4.1 粒子-墙壁 碰撞(Particle-wall collision)
碰撞预测与处理:
- 粒子半径(radius)为 s,位置为 (rx, ry)
- 粒子运动速度为 (vx, vy)
- 它会与垂直的墙壁碰撞吗?如果会,发生在什么时候?
4.2 粒子-粒子 碰撞(Particle-particle collision)
4.2.1 粒子-粒子 碰撞预测(Particle-particle collision prediction)
- 粒子 i:半径 Si,位置 (rxi, ryi),速度 (vxi, vyi)
- 粒子 j:半径 Sj,位置 (rxj, ryj),速度 (vxj, vyj)
- 粒子 i 与 粒子 j 会发生碰撞吗?如果会,发生在什么时候?
根据牛顿第二定律,可得以下公式:
4.2.2 粒子-粒子 碰撞处理(Particle-particle collision resolution)
当两个粒子发生碰撞,它们的速度怎么变化?
4.3 代码
4.3.1 粒子数据结构框架(Particle data type skeleton)
1 | public class Particle |
4.3.2 粒子-粒子 碰撞预测与处理(Particle-particle collision and resolution implementation)
1 | public double timeToHit(Particle that) |
1 | public void bounceOff(Particle that) |
4.3.3 碰撞系统(Collision system)
初始化(Initialization)(时间复杂度 O(N^2),只用执行一次):
- 用所有潜在的粒子-墙壁碰撞填充 PQ
- 用所有潜在的粒子-粒子碰撞填充 PQ
(潜在的:由于其它粒子碰撞干涉,碰撞可能不会发生)
主循环(Main loop):
- 从 PQ 中删除即将发生的事件(min 的优先级为 t)
- 如果事件已经失效,忽略它
- 推进所有的粒子的直线轨迹到时刻 t
- 更新碰撞粒子的速度(s)
- 预测发生碰撞的粒子的未来的粒子-墙壁、粒子-粒子碰撞,并将事件插入 PQ
Event 数据结构(Event data type):
约定:
- 两个粒子都不是 null ⇒ 粒子-粒子碰撞
- 一个粒子是 null ⇒ 粒子-墙壁碰撞
- 两个粒子都是 null ⇒ 重新绘制 event
1 | private class Event implements Comparable<Event> |
碰撞系统实现:框架(Collision system implementation: skeleton):
1 | public class CollisionSystem |
碰撞系统实现:事件驱动模拟主循环(Collision system implementation: main event-driven simulation loop):
1 | public void simulate() |