我正在创建一个两体模拟,其中地球应该绕着太阳“绕圈”,但是它只能沿对角线传播。我之所以这样计算,是因为我将加速度视为标量,并且需要考虑其方向。
我写了一些代码,寻找从地球到太阳的向量,然后尝试寻找加速的x
和y
分量。但是它仍然没有像我期望的那样绕太阳转。
任何帮助都会很棒。
这是代码(只有两个相关的函数,请注意,我已将画布的轴转换为笛卡尔集):
function calAcc (){
//gravitational constant m3kg-1s-2
var G = 6.67408E-11;
//mass of earth kg
var m2 = 5.972E24;
//mass of sun kg
var m1 = 1.989E30;
var r = (Math.sqrt((Math.pow(xPos,2))+(Math.pow(yPos,2))));
//calculate the force on the earth using F = Gm1m2/r^2
//force is towards the centre of the sun
var F = ((G*m1*m2)/(Math.pow(r,2)));
//calculate earths acceleration using Newton 2nd a = F / m
var aMag = (F/m2);
var sunPos = [0,0];
var earthPos = [xPos, yPos];
var accVec = [];
//find position vector from earth to sun
for (var i=0; i<=1;i++){
accVec.push(sunPos[i]-earthPos[i]);
}
//find argument of this vector
var argRad = Math.atan(accVec[1]/accVec[0]);
//correct the argument based on which quadrant it is in
if (xPos < 0 && yPos < 0){
argRad = argRad + Math.PI;
} else if (xPos < 0 && yPos > 0){
argRad = Math.PI - argRad;
} else if (xPos > 0 && yPos < 0){
argRad = 2(Math.PI)-argRad;
} else{
argRad = argRad;
}
var argDeg = argRad*180/Math.PI;
// work out separate x and y components of velocity
var aX = Math.cos(argRad)*aMag;
var aY = Math.sin(argRad)*aMag;
console.log(Math.sqrt((Math.pow(aX, 2))+(Math.pow(aY,2))));
return [aX, aY];
}
function leapfrog (){
var xPosPrevious = xPos;
var yPosPrevious = yPos;
var xVelPrevious = xVel;
var yVelPrevious = yVel;
var dt = 1000;
//leapfrog for new position and velocity
// not in loop as loops around newAnimate function
var a = calAcc();
var xVelNextInt = xVelPrevious + a[0]*dt;
var yVelNextInt = yVelPrevious + a[1]*dt;
xPos = xPosPrevious + ((xVelPrevious+xVelNextInt)/2)*dt;
yPos = yPosPrevious + ((yVelPrevious+yVelNextInt)/2)*dt;
xVel = ((xVelPrevious+xVelNextInt)/2)+a[0]*dt/2;
yVel = ((yVelPrevious+yVelNextInt)/2)+a[1]*dt/2;
// calculates scaled positions
var xPosScaled = xPos / posScale;
var yPosScaled = yPos / posScale;
//calculates scaled velocities
var xVelScaled = xVel / velScale;
var yVelScaled = yVel / velScale;
return [xPosScaled, yPosScaled, xVelScaled, yVelScaled];
}