N 体重力/太阳系 Javascript 模拟
N-Body Gravity / Solar System Javascript Simulation
美好的一天,我正在尝试在 javascript 中创建一个简单的 2D 太阳系模型,但我在理解如何计算下一帧的行星位置以及一些我将很快详细介绍的其他内容。
看完 this 非常好的视频和他的一大堆其他视频后,我制作了一个快速的 MS 绘画图像来尝试简化我的情况。
在第二个场景中,您可以看到新位置是使用速度、引力和这两者之间的角度计算的 'directions'?
我不知道如何解决这一切。
下面是我的代码的 JS fiddle。您会注意到我正在尽最大努力使用真实的 NASA 给定数据以保持其准确性。
您需要专门查看第 138 行,这是进行下一步行动的所有计算的地方。
https://jsfiddle.net/c8eru7mk/9/
attraction: function(p2) {
// Distance to other body
var dx = p2.position.x - this.position.x;
var dy = p2.position.y - this.position.y;
var d = Math.sqrt(dx ** 2 + dy ** 2); // Possibly correct
// Force of attracrtion
this.f = G * (this.mass * p2.mass) / (d ** 2); // Possibly Correct
// Direction of force, If you read it hard enough you should be able to hear my screams of pain
// Not sure if this is correct, most likely not.
var theta = Math.atan2(dy, dx);
var fx = Math.cos(theta) * this.f;
var fy = Math.sin(theta) * this.f;
this.velocity.x += fx / this.mass;
this.velocity.y += fy / this.mass;
this.position.x += this.velocity.x;
this.position.y += this.velocity.y;
}
我目前面临的问题是
- 如果我要使用 NASA 值,行星之间的距离太大,它们将无法显示在屏幕上,我不能简单地通过将它们乘以 0.0002 或其他任何方法来缩小距离,因为那样会弄乱引力常数,模拟将完全关闭。
- 我不知道如何计算下一个位置,过去一周我的大脑崩溃了好几次,我尝试了好几次。
- 我不知道如何检查我的行星配置数据是否错误,或者模拟是否错误,所以我几乎只是猜测。
这也是我第一次在 javascript 中实际编写比按钮更复杂的代码,因此欢迎提供有关代码布局等方面的反馈!
非常感谢
使用单独的坐标进行绘图时,使用 NASA 值不是问题。使用适当的从实际坐标到屏幕坐标的线性变换进行显示不影响物理值和计算。
为了模拟具有迭代更新的行星运动,我们可以假设引力和速度在一小部分时间内保持不变 dt
。在从加速度到速度以及从速度到距离的转换中缺少这个因素 dt
。为 dt
选择一个合适的值可能需要一些实验。如果该值太大,则近似值将与现实相差太远。如果值太小,您可能看不到任何移动或舍入错误可能会影响结果。
一开始让我们假设太阳总是在 (0,0)。同样,首先让我们忽略行星之间的作用力。然后这里是第一个不太糟糕的近似值的必要公式:
- 太阳引力(质量
M
)在位置 (x,y)
处行星的标量加速度:a = G*M/(d*d)
其中 d=sqrt(x*x+y*y)
。请注意,这与行星的质量无关。
- 加速度矢量:
ax = -a*x/d
、ay = -a*y/d
(矢量(-x,-y)
指向太阳,长度必须为a
)
- 行星速度的变化
(vx,vy)
:vx += ax*dt
、vy += ay*dt
- 行星位置的变化:
x += vx*dt
、y += vy*dt
美好的一天,我正在尝试在 javascript 中创建一个简单的 2D 太阳系模型,但我在理解如何计算下一帧的行星位置以及一些我将很快详细介绍的其他内容。
看完 this 非常好的视频和他的一大堆其他视频后,我制作了一个快速的 MS 绘画图像来尝试简化我的情况。 在第二个场景中,您可以看到新位置是使用速度、引力和这两者之间的角度计算的 'directions'?
我不知道如何解决这一切。
下面是我的代码的 JS fiddle。您会注意到我正在尽最大努力使用真实的 NASA 给定数据以保持其准确性。
您需要专门查看第 138 行,这是进行下一步行动的所有计算的地方。
https://jsfiddle.net/c8eru7mk/9/
attraction: function(p2) {
// Distance to other body
var dx = p2.position.x - this.position.x;
var dy = p2.position.y - this.position.y;
var d = Math.sqrt(dx ** 2 + dy ** 2); // Possibly correct
// Force of attracrtion
this.f = G * (this.mass * p2.mass) / (d ** 2); // Possibly Correct
// Direction of force, If you read it hard enough you should be able to hear my screams of pain
// Not sure if this is correct, most likely not.
var theta = Math.atan2(dy, dx);
var fx = Math.cos(theta) * this.f;
var fy = Math.sin(theta) * this.f;
this.velocity.x += fx / this.mass;
this.velocity.y += fy / this.mass;
this.position.x += this.velocity.x;
this.position.y += this.velocity.y;
}
我目前面临的问题是
- 如果我要使用 NASA 值,行星之间的距离太大,它们将无法显示在屏幕上,我不能简单地通过将它们乘以 0.0002 或其他任何方法来缩小距离,因为那样会弄乱引力常数,模拟将完全关闭。
- 我不知道如何计算下一个位置,过去一周我的大脑崩溃了好几次,我尝试了好几次。
- 我不知道如何检查我的行星配置数据是否错误,或者模拟是否错误,所以我几乎只是猜测。
这也是我第一次在 javascript 中实际编写比按钮更复杂的代码,因此欢迎提供有关代码布局等方面的反馈!
非常感谢
使用单独的坐标进行绘图时,使用 NASA 值不是问题。使用适当的从实际坐标到屏幕坐标的线性变换进行显示不影响物理值和计算。
为了模拟具有迭代更新的行星运动,我们可以假设引力和速度在一小部分时间内保持不变 dt
。在从加速度到速度以及从速度到距离的转换中缺少这个因素 dt
。为 dt
选择一个合适的值可能需要一些实验。如果该值太大,则近似值将与现实相差太远。如果值太小,您可能看不到任何移动或舍入错误可能会影响结果。
一开始让我们假设太阳总是在 (0,0)。同样,首先让我们忽略行星之间的作用力。然后这里是第一个不太糟糕的近似值的必要公式:
- 太阳引力(质量
M
)在位置(x,y)
处行星的标量加速度:a = G*M/(d*d)
其中d=sqrt(x*x+y*y)
。请注意,这与行星的质量无关。 - 加速度矢量:
ax = -a*x/d
、ay = -a*y/d
(矢量(-x,-y)
指向太阳,长度必须为a
) - 行星速度的变化
(vx,vy)
:vx += ax*dt
、vy += ay*dt
- 行星位置的变化:
x += vx*dt
、y += vy*dt