上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人
实验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%的速度,在真实的物理引擎当中,会为每个碰撞物体设定一个弹性系数,当然复杂一些的物理引擎会为物体的每个面设置一个弹性系数,然后根据接触面的弹性系数,计算出最后的速度大小。