自由落下運動のシミュレート
ボールに見立てた円図形をJavaScriptで書いてみる。最初は上下だけの自由落下運動。手に握った野球の球を放し、地面に落とすイメージ。
まず、簡単なHTMLファイルを用意。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset=UTF-8"> <title>自由落下運動と放物運動のシミュレート</title> </head> <body> <canvas id="canvas"></canvas> <script type="text/javascript" src="./main.js"></script> </body> </html>
次に、ボールのスクリプト部分が以下。
class Main {
constructor() {
this._canvas;
this._context;
this._timer;
// ①各パラメータ
this._v = 0.0; // 初速度
this._y = 15; // ボールの中心
this._a = 9.8; // 重力(加速度)
this._t = 0.2; // 時間
this._e = -0.8; // 反発係数
this._init();
}
_init() {
this._canvas = document.getElementById("canvas");
this._canvas.width = 200;
this._canvas.height = 500;
this._context = this._canvas.getContext("2d");
// ②タイマーを開始し、_darw()を20ミリ秒間隔で呼び出し
this._timer = setInterval(this._draw.bind(this), 20);
}
_draw() {
// ③速度と位置を更新
this._v = this._v + this._a + this._t;
this._y = this._y + this._v * this._t + 0.5 * this._a * this._t * this._t;
// ④地面との衝突処理
if (this._y > this._canvas.height - 15) {
this._y = this._canvas.height - 15;
this._v = this._v * this._e;
}
// ⑤キャンバスを白紙に戻す
this._context.fillStyle = "rgba(255, 255, 255, 0.2)";
this._context.rect(0, 0, 200, 500);
this._context.fill();
// ⑥ボールの描画処理
this._context.beginPath();
this._context.fillStyle = "#000000";
this._context.arc(100, this._y, 15, 0, 360 * Math.PI / 180);
this._context.fill();
}
}
let run = new Main();
①、必要となる物理のパラメータ。反発係数はボールが地面に衝突した時のバウンドの力。
②、setInterval()で画面更新を担当する_draw()を、20ミリ秒で呼び出すよう設定。
③、落下による時間経過と共に変化するボールの速度、位置を計算している。加速と位置を計算する式は以下。

vやyの0は運動を観察し始めた時という意味。
④、ボールがキャンバスの最下部に到達したら、速度に反発係数をかけバウンドさせる。
⑤、ボールを再描画する直前にキャンバスを白紙に戻す。そうしないと以前描画したボールが残るため。アルファ値を0.2に設定してボールの軌跡が見えるようにした。
⑥、計算したy座標を元に、arc()で円を描画。
放物運動をシミュレート
次に、自由落下運動にx軸方向の動きを加えた放物運動をシミュレートしてみる。HTMLファイルは同じものを使用。
class Main {
constructor() {
this._canvas;
this._context;
this._timer;
// ①各パラメータ
this._vx, this._vy; // 初速度
this._x, this._y; // ボールの中心
this._a = 9.8; // 重力(加速度)
this._t = 0.2; // 時間
this._e = -0.8; // 反発係数
this._init();
}
_init() {
this._canvas = document.getElementById("canvas");
this._canvas.width = 600;
this._canvas.height = 400;
this._context = this._canvas.getContext("2d");
// ②ボールの初速度の設定
this._vx = 3;
this._vy = -100;
// ③ボールの初期位置の設定
this._x = 0;
this._y = this._canvas.height;
// 最初のボールを描画
//this._context.arc(this._x, this._y, 10, 0, 360 * Math.PI / 180);
this._timer = setInterval(this._draw.bind(this), 20);
}
_draw() {
// ④x方向の等速度運動
this._x = this._x + this._vx;
this._vy = this._vy + this._a * this._t;
this._y = this._y + this._vy * this._t + 0.5 * this._a * this._t * this._t;
if (this._y > this._canvas.height - 15) {
this._y = this._canvas.height - 15;
this._vy = this._vy * this._e;
}
this._context.fillStyle = "rgba(255, 255, 255, 0.2)";
this._context.rect(0, 0, 600, 400);
this._context.fill();
this._context.beginPath();
this._context.fillStyle = "#000000";
this._context.arc(this._x, this._y, 15, 0, 360 * Math.PI / 180);
this._context.fill();
}
}
let run = new Main();
①、放物運動は横移動もあるため、速度をvを_vx、_vyの2つにする。
②、x、y軸方向の初速度を設定。_vx値が大きいほど右へ、_vy値が大きいほど上へ上がる。
③、キャンバスの左下隅にボールを配置。
④、自由落下運動ではy軸方向だけ計算したが、今回はx軸方向も計算する。ボールが横に動く運動は一定の速度にしている。こういった動きを等速度運動という。時間tにおけるx軸方向のボール位置は以下の式で求められる。

今回、x軸方向は等速度運動のため、_vxに時間は掛けていない。

コメント