【发布时间】:2020-08-05 04:58:03
【问题描述】:
我正在制作一个仅使用 p5.js 而没有 box2D 的太阳系模型,尽管语言/平台对于这个问题并不重要。此外,用于描述问题的所有数字和变量并非 100% 准确,但行为是相同的。
我使用牛顿公式 ( F = G Mm / r^2 ) 来找到两个物体之间的相互引力,比如 A 和 B。现在为了将 A 吸引到 B,我将这个相互引力除以 A 的质量来找到A 上的向心加速度,然后将其乘以指向 B 的单位向量。将此关系应用于 A 和 B 时,它们都会相互吸引,与它们的质量成反比。
现在,如果我让它们彼此相互作用,A 的质量 = 1000 单位,B 的质量 = 10 单位,正如预期的那样,A 不会被拉动并保持静止,但 B 会向 A 加速。现在会发生什么当 B 到达中心并朝相反的方向飞行时,它会比我最初放置的距离更远。这在每个加速周期中都会滚雪球,并且在某些时候会离开屏幕。这似乎违反了能量守恒或我的物理学中的一些重大缺陷。
好的,然后继续第二个问题,我们有相同的对象和质量。不同之处在于我给 B(较轻的物体)某个值的初始速度,例如在 x 轴的正方向上的 x。现在我将 B 垂直于 A 的 x 轴并让它们相互作用。这一次,B 在一种椭圆轨道上运动,有两个问题。首先是A(较重的物体)不在椭圆的焦点之一,而是在它的确切中心,其次是随着时间的推移,轨道本身开始旋转。我觉得这种旋转是由提供的初始速度引起的,为了清楚起见,速度仅在最初应用,而不是在每一帧上应用。该轨道的轨迹如下:
还要注意每个轨道的最大范围如何比前一个多一点。这几乎就是之前的问题。
我目前正在尝试的下一件事是,应用与运动相切的恒定速度以及重力向心加速度。让我知道这是否有用,或者我的整个方法是否需要改变。
这也是我的模拟代码:
var constG;
var axisX;
var planets = [];
function setup() {
createCanvas(500, 500);
//createCanvas(displayWidth, displayHeight);
//fullscreen(true);
constG = 0.0001;//6.67 * pow(10, -11);
axisX = createVector(1, 0);
}
function draw() {
background(0, 5);
for (var planet of planets) {
planet.update();
planet.display();
}
for (var i = 0; i < planets.length; i++){
var selfPlanet = planets[i];
for (var j = 0; j < planets.length; j++){
if (j == i){
continue;
}
var otherPlanet = planets[j];
var gravitalAcc = calcGravitalAcc(selfPlanet, otherPlanet);
selfPlanet.applyForce(gravitalAcc);
}
}
if (planets.length > 0){
planets[0].radius = 15;
planets[0].mass = 100; // this just makes the first planet heavy so that i
planets[0].vel.mult(0); // can test stuff while making it the sun.
planets[0].speed = 0;
}
}
function mousePressed() {
planets.push(new CelestialBody(mouseX, mouseY, 7));
}
function calcGravitalAcc(self, other){
var tempVec = p5.Vector.sub(other.pos, self.pos);
return tempVec.normalize().mult(constG * (other.mass)/pow(tempVec.mag(), 2))
}
这是 Celestialbody 类,只是简单物理模拟中的任何典型类:
class CelestialBody {
constructor(x, y, radius) {
this.pos = createVector(x, y);
this.radius = radius;
this.color = color(255);
this.mass = 1;
this.speed = 1;
this.vel = createVector(1, 0) //p5.Vector.random2D();
this.vel.setMag(this.speed);
this.acc = createVector(0, 0);
}
display() {
fill(this.color);
stroke(this.color);
circle(this.pos.x, this.pos.y, this.radius * 2);
}
update() {
this.pos.add(this.vel);
this.vel.add(this.acc);
this.acc.mult(0);
}
applyForce(vForce){
this.acc.add(vForce);
}
}
【问题讨论】:
标签: math simulation physics orbital-mechanics