java - n体模拟幻象力
问题描述
在我的 n 体模拟中,我有大约 1k 个粒子飞来飞去。我将位置存储为浮点数。我遇到的一个问题是,每次我运行代码时,当两个粒子彼此非常接近(基本上是相同的位置)时,它们会被极大地加速。通常粒子的行为是平滑的。
if((planet.position.x != otherPlanet.position.x && planet.position.y != otherPlanet.position.y) && !otherPlanet.delete)
{
//First we get the x,y and magnitudal distance between the two bodies.
float xDist = (otherPlanet.position.x - planet.position.x);
float yDist = (otherPlanet.position.y - planet.position.y);
float dist = Vector2Math.distance(planet.position, otherPlanet.position);
//Now we compute first the total and then the component forces
//Depending on choice, use r or r^2
float force = Constants.GRAVITATIONAL_CONSTANT * ((planet.mass*otherPlanet.mass)/(dist*dist));
float forceX = force * xDist/dist;
float forceY = force * yDist/dist;
//Given the component forces, we construct the force vector and apply it to the body.
Vector2 forceVec = new Vector2(forceX, forceY);
planet.force = Vector2Math.add(planet.force, forceVec);
otherPlanet.force = Vector2Math.subtract(otherPlanet.force, forceVec);
}
我还没有找到关于这个主题的任何内容,但这是我做错了什么还是我必须实现最大加速度或粒子之间的最小距离?
解决方案
模拟世界与现实世界有点不同,为了做出好的模拟,我们需要添加一些限制。
问题:
当两个粒子彼此真正靠近时,它们就会以极快的速度向外爆炸。
原因
原因很简单,重力与两个物体之间的距离平方成反比。当两个物体靠得太近时,半径(它们之间的距离)变得非常小,作用在它们上的力变得非常非常大。
解决方案
为两个粒子可以接近多少添加一个虚拟限制。虚拟限制是指该限制仅在值上,而不在模拟上。例如。如果它们之间的距离小于 5(阈值),则将距离设置为 5。
代码中的更改
if((planet.position.x != otherPlanet.position.x && planet.position.y != otherPlanet.position.y) && !otherPlanet.delete)
{
//First we get the x,y and magnitudal distance between the two bodies.
float xDist = (otherPlanet.position.x - planet.position.x);
float yDist = (otherPlanet.position.y - planet.position.y);
// add a limit to xDist and yDist
if(xDist<5)
xDist=5;
if(yDist<5)
yDist=5;
float dist = Vector2Math.distance(planet.position, otherPlanet.position);
//Now we compute first the total and then the component forces
//Depending on choice, use r or r^2
float force = Constants.GRAVITATIONAL_CONSTANT * ((planet.mass*otherPlanet.mass)/(dist*dist));
float forceX = force * xDist/dist;
float forceY = force * yDist/dist;
//Given the component forces, we construct the force vector and apply it to the body.
Vector2 forceVec = new Vector2(forceX, forceY);
planet.force = Vector2Math.add(planet.force, forceVec);
otherPlanet.force = Vector2Math.subtract(otherPlanet.force, forceVec);
}
当然,您希望将 5 更改为适合您模拟的值。
推荐阅读
- html - 为什么我使用 table-cell css 样式的页面在相同的宽度比率下显示不同的 div 宽度?
- android - 如何在 findNavController().navigate() 中发送带有方向的导航器附加信息
- asp.net-core - Serilog - can not log to multiple files based on property
- javascript - 遍历并删除对象数组中的元素
- r - 如何区分 R 中的“alist”和“list”?
- javascript - 如何在 Angular 应用程序中使用 BokehJS?
- reactjs - 如何使用 useEffect 从 Redux 获取更新的状态
- excel - 试图过滤包含“-M”的数据,但它给了我一个错误
- python - Docker 容器随机分段错误
- html - 在 CSS 中定位单个图像