我有一个很大的要求。它涉及相当多的数学,这从来都不是我的强项,所以我想,我会问Stackoverflow上的人帮助我。
我正在使用Javascript处理这个太阳系交互式动画。我正在使用三角函数在物体周围创建完整的360度旋转旋转,用于围绕太阳的行星。我知道,行星会以椭圆形旋转,但我不想让它对我自己造成太大的压力。
function rotate_point(originX, originY, body) {
body.angle += (1.0 / body.period); //calculates the angle, divided by distance from center of body
var ang = body.angle * 2.0 * Math.PI / 180.0; //calculates full 360° rotation required based on angle
var r = body.orbit;
return {
x: Math.cos(ang) * r - Math.sin(ang) * r + originX,
y: Math.sin(ang) * r + Math.cos(ang) * r + originY
};} // generic rendering of a unit orbital progression of a planet
正如你所看到的那部分已经完成,我的问题是:
我需要“调整”以便将物体驱动到太阳中心的效果。就像我突然使引力拉得更强,它会拉动行星的轨道,所以你看到它们最终撞向那个中心。
是否可以对上述代码进行任何更改,如果是,那么代码需要看起来像什么?
我有一个JS小提琴我已经得到了什么,我希望有一些聪明的家伙能看到这个挑战并帮助我!
答案 0 :(得分:5)
更新代码以使用开普勒的行星运动第三定律应该非常容易。因为你在使用圆形轨道,其中质量(行星)<<质量(太阳),开普勒第三定律基本上只是角动量守恒的一个陈述。
旋转动量定义为系统惯性矩( I )和角速度(ω)的乘积,以 rad为单位测量/ s的
数学上,这只是:
I1 * omega1 = I2 * omega2
根据我们可以使用的数量来表达:
I = m * r ^ 2 omega = r * dTheta / dt
所以通过财产保护:
I1 * omega1 = I2 * omega2
群众取消了双方,留下了 r 和 omega 的表达。
r1 ^ 2 * omega1 = r2 ^ 2 * omega2
因此,考虑到半径的变化,我们可以计算角速度的必要变化。如果 r1 和 omega1 是初始半径和旋转速度,则给定轨道半径的新旋转速度表示为:
omega2 = omega1 *(r1 / r2)^ 2
这可以通过在function rotate_point(originX, originY, body) {
velocity_gain = Math.pow(sol["Earth"].orbit/body.orbit, 2)
body.angle += velocity_gain * (1.0 / body.period); //calculates the angle, divided by distance from center of body
var ang = body.angle * 2.0 * Math.PI / 180.0; //calculates full 360° rotation required based on angle
var r = body.orbit * orbitScale
return {
x: Math.cos(ang) * r - Math.sin(ang) * r + originX,
y: Math.sin(ang) * r + Math.cos(ang) * r + originY
};
}
// generic rendering of a unit orbital progression of a planet
function planetrotation ( planet ) {
var x, y, x_sun, y_sun, e, c_new;
e = document.getElementById ( planet );
x_sun = parseFloat ( document.getElementById ( "Sun" ).getAttribute ( "cx" ) );
y_sun = parseFloat ( document.getElementById ( "Sun" ).getAttribute ( "cy" ) );
c_new = rotate_point ( x_sun, y_sun, sol[planet], 0.5 );
e.setAttribute ( "cx", c_new.x );
e.setAttribute ( "cy", c_new.y );
} // Rotations of the planets around Sun
var sol = {
Mars: { period: 5.2, orbit: 400, angle: 51.0},
Earth: { period: 5.2, orbit: 300, angle: 51.0},
Venus: { period: 5.2, orbit: 200, angle: 51.0}
};
function animate () {
planetrotation("Venus");
planetrotation("Earth");
planetrotation("Mars");
}
函数中添加一行代码来更新速度来实现:
period
这里是小提琴模拟3个行星:https://jsfiddle.net/8kcj3bvz/
基本上,这种平等性表明,随着轨道半径的减小,动量(和这种情况下的能量)的角速度必须增加。
长期来看,您可能需要考虑使用Euler的方法来模拟此系统。对于像这样的引力体,它实际上非常简单,并且在模拟两个以上的物体时可以非常强大。
修改强>
只是注意到轨道速度只是其半径的函数,前提是卫星的质量远小于母体。因此,在代码中定义angle
和for(var i = 0; i<content.length(); i++){
//perform whatever you need on the following object
var myobject = content[i];
}
实际上是多余的。
答案 1 :(得分:3)
你可以减少轨道的半径:
body.orbit = Math.max(body.orbit-.25, 0);
function rotate_point(originX, originY, body) {
body.angle += (1.0 / body.period); //calculates the angle, divided by distance from center of body
var ang = body.angle * 2.0 * Math.PI / 180.0; //calculates full 360° rotation required based on angle
body.orbit = Math.max(body.orbit - .25, 0);
var r = body.orbit;
return {
x: Math.cos(ang) * r - Math.sin(ang) * r + originX,
y: Math.sin(ang) * r + Math.cos(ang) * r + originY
};
}
// generic rendering of a unit orbital progression of a planet
function planetrotation(planet) {
var x, y, x_sun, y_sun, e, c_new;
e = document.getElementById(planet);
x_sun = parseFloat(document.getElementById("Sun").getAttribute("cx"));
y_sun = parseFloat(document.getElementById("Sun").getAttribute("cy"));
c_new = rotate_point(x_sun, y_sun, sol[planet]);
e.setAttribute("cx", c_new.x);
e.setAttribute("cy", c_new.y);
} // Rotations of the planets around Sun
var sol = {
Earth: {
period: 5.2,
orbit: 200,
angle: 51.0
}
};
function animate() {
planetrotation("Earth");
}
var animateInterval = setInterval(animate, 1000 / 60);
.st0 {
fill: #FFFF00;
}
.st1 {
fill: blue;
}
<div class="solarsystem">
<svg xmlns="http://www.w3.org/2000/svg" id="solly" viewBox="0 0 1000 600">
<g id="Sun2">
<circle id="Sun" class="st0" cx="500" cy="300.8" r="30" />
<circle id="Earth" class="st1" cx="375.4" cy="289.7" r="10.5" />
</g>
</svg>
</div>
当然,在物理上它不会像这样。
答案 2 :(得分:2)
为简单起见,您可以在时间内线性改变半径。例如:
function rotate_point(originX, originY, body) {
body.angle += (1.0 / body.period); //calculates the angle, divided by distance from center of body
body.orbit -= body.period*.04;
// ... other stuff ...
}