實驗9 萬有引力
簡介
實驗8是把物體看成質點,模擬了勻速直線運動。質點是一個理想化的物理模型,當把物體看成質點時,不需要考慮它的大小、形狀和旋轉。在 Canvas中,同樣可以模擬一個勻加速運動,比如,重力場下的物體運動。由于地球的吸引而使物體受到的力,叫做重力(Gravity),生活中常把物體所受重力的大小簡稱物重。重力的方向總是豎直向下或指向地心的,如圖2-4所示。

圖2-4 重力
重力的單位是N,但是表示符號為G,公式為:G=mg。其中,m是物體的質量,g一般取9.8 N/kg。在一般使用中,常把重力近似看做等于萬有引力。但實際上,重力是萬有引力的一個分力。重力之所以是一個分力,是因為在地球上與地球一起運動,這個運動可以近似看成勻速圓周運動。做勻速圓周運動需要向心力,在地球上,這個力由萬有引力的一個指向地軸的分力提供,而萬有引力的另一個分力就是平時所說的重力了。
速度是加速度對時間的累積,即:
v=∫a dt
重力場下的永動機
想象一個彈性質量完美的小球,在重力場的作用下,碰撞地面(無能量損失),彈起,碰撞地面,彈起……無限循環下去,其代碼實現:
var canvas=document.getElementById("myCanvas"); var cxt=canvas.getContext("2d"); var ball={ x: 100, y: 100, r: 15, vx: 0, vy: 0 }; var cyc=10; var a=50; var moveAsync=eval(Jscex.compile("async", function () { while (true) { cxt.fillStyle="rgba(0, 0, 0, .3)"; cxt.fillRect(0, 0, canvas.width, canvas.height); cxt.fillStyle="#fff"; cxt.beginPath(); cxt.arc(ball.x, ball.y, ball.r, 0, Math.PI * 2, true); cxt.closePath(); cxt.fill(); ball.y +=ball.vy * cyc / 1000; \注:位移是速度對時間的累積。\ if (ball.r+ball.y >=canvas.height) { ball.vy *=-1; } else { ball.vy +=a; \注:速度是加速度對時間的累積。\ } $await(Jscex.Async.sleep(cyc)); } })) moveAsync().start();
耗能的重力場
想象一個彈性鐵球,在重力場的作用下,碰撞地面(一部分動能轉化為與地面碰撞產生的熱能),彈起,碰撞地面,彈起……循環下去,最后靜止,其代碼實現:
var canvas=document.getElementById("mycanvas");
var cxt=canvas.getContext("2d");
var ball={
x: 100,
y: 100,
r: 15,
vx: 0,
vy: 0
};
cxt.fillStyle="#030303";
cxt.fillRect(0, 0, canvas.width, canvas.height);
cxt.fillStyle="#fff";
cxt.beginPath();
cxt.arc(ball.x, ball.y, ball.r, 0, Math.PI * 2, true);
cxt.closePath();
cxt.fill();
var hitCount=0 ,cyc=10, a=50;
var moveAsync2=eval(Jscex.compile("async", function () {
while (true) {
cxt.fillStyle="rgba(0, 0, 0, .3)";
cxt.fillRect(0, 0, canvas.width, canvas.height);
cxt.fillStyle="#fff";
cxt.beginPath();
cxt.arc(ball.x, ball.y, ball.r, 0, Math.PI * 2, true);
cxt.closePath();
cxt.fill();
ball.y +=ball.vy * cyc / 1000;
if (ball.r+ball.y >=canvas.height) {
if (ball.vy > 0) {
ball.vy *=-0.7; \注:碰撞之后,一部分動能轉化為與地面碰撞產生的熱能,所以速度降低,方向相反。\
hitCount++;
}
}
else {
ball.vy +=a;
}
if (hitCount > 15) break;
$await(Jscex.Async.sleep(cyc));
}
}))
在上面的代碼中,假設碰撞之后損失了30%的速度,在真實的物理引擎當中,會為每個碰撞物體設定一個彈性系數,當然復雜一些的物理引擎會為物體的每個面設置一個彈性系數,然后根據接觸面的彈性系數,計算出最后的速度大小。