我正在尝试实现Clavet method来模拟JavaScript中的流体,所以调试是一场噩梦,这就是为什么我在这里问,希望有人经历同样的事情会告诉我我是什么做错了。
到目前为止我的工作正常:
但我有两个问题:
1)因为在这种方法中,所有东西都是“偏移”半步,我不知道如何正确地将粒子从墙壁上反弹。现在我取出粒子的位置和先前的位置并将它们绕过交叉的墙壁,然后通过反弹因子围绕交叉点进行缩放。
我的逻辑告诉我这应该有效。算法的下一步是更新粒子速度,所以我也反映了之前的位置。但在实践中,这给了我一个我不明白的结果:
这显示了粒子上的“力”。墙壁反射过多的力量,使一切都保持不变。
this paper中的公式4.58显然显示了一种防止这种情况的方法,但我无法让它发挥作用。
还有一些我没有得到的文章,比如“我们只想反映碰撞中省略的速度”的意思。为什么?请问有人ELI5这件事给我好吗?
2)即使不涉及墙壁,模拟也会定期“爆炸”。更高的压力会发生这种情况:
这个是 JavaScript,所以有那个,但是我已经查看了代码并且没有任何划分,或者我可以想象NaN正在发生的情况。
我在论文中看到过关于SIM卡不稳定性的一些话题,我想知道是不是这样。这篇文献中的大部分都超出了我的范围。
根据我的理解(我认为),消除不稳定性的方法之一是粘度,但我添加了它并且它对爆炸没有帮助:
我可以发布代码,但是在即将开始工作的第一阶段,它现在很难阅读。
最后一个问题:我如何弄清楚如何将此方法中的伪常数转换为物理单位?
编辑:我发现SIM卡偶尔会冻结,看起来确实会在某个地方产生NaN,但Chrome会抓得太晚。
答案 0 :(得分:3)
显然这里有很多。我确信我无法回答这一切,但这里有一些有希望的重点:
围墙:您实施的内容称为momentum mirror。在压力下的流体中,动量镜用于吸引具有一种负表面张力的粒子(因为在其之外没有粒子可以排斥边界附近的粒子)。颗粒越紧密,就会产生更大的力,更容易引起数值问题(特别是因为它们的传送往往会给它们带来潜在的能量)。
关于恢复系数:碰撞周围的简单线性缩放产生冲击切向力,这对于动量镜来说并不典型,但确实会产生物理上真实的无滑动条件。
关于您链接的第二篇论文:我认为他们正在尝试根据他们的点数投射来做一些智能化的事情。但是,我不知道为什么他们只是投射回表面(而不是计算碰撞时间,然后根据(减少的)新速度计算新位置。)
答案 1 :(得分:3)
假设这是一个没有严格物理意义的cg项目......
首先,您应该考虑为模拟代码使用固定的时间步长,否则当dt(和错误)抖动时,您将会出现不稳定(和视觉上令人不安)的行为。 如果根据最终要求无法获得一致的帧速率,则应对位置进行插值,而不是在非固定时间点进行模拟。
关于你的墙壁计算,它显然取决于你想要最终实现的效果;所以,如果你应用一个或多或少的动量保持镜像条件(你现在正在做) 粒子将继续循环。即使应用了阻尼也是如此。如果你想让液体粘在一起。不知何故,你需要引入壁力或其他更强的耗散效应。
我运行了你的代码,在设置了一致的dt并调整粘度并简化了墙面计算以简化" if(p.px< left)p.px = left +(left - p.px) * canvas.wallBounce;否则if()..."条件我很好 '松弛'行为(如果这是你正在寻找的)。更新之前的位置也会适得其反,因为它会增加墙壁的反射性['可以这么说。