静岡理工科大学 菅沼ホーム JavaScript 目次 基礎技術目次 索引

速度と加速度(その1)

  1. 速度

      x 軸上の初期位置を x0,x 軸方向の速度を v/s としたとき,摩擦等の外力がなければ,物体は等速直線運動を行い,t 秒後の位置 x は (1) 式のようになります.従って,一定時間( dt )毎に位置を計算する場合は,現在の位置を x(t),dt 時間後の位置を x(t+dt) としたとき,(2) 式のように表せます.
    x = x0 + vt  (1)
    x(t+dt) = x(t) + v・dt  (2)
    			
      以下のプログラムは,DOM 及び CANVAS 関係の JavaScript のプロパティとメソッドwindow オブジェクトにおける setInterval メソッドを利用して,等速直線運動を描画したものです.

    01	<!DOCTYPE HTML>
    02	<HTML>
    03	<HEAD>
    04		<TITLE>等速直線運動</TITLE>
    05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    06		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    07		<SCRIPT TYPE="text/javascript">
    08			canvas  = null;
    09			ctx     = null;
    10			timerID = -1;
    11			x       = 0.0;   // 円の位置( x )
    12			y       = 0.0;   // 円の位置( y )
    13			x0      = 0.0;   // 円の水平方向の初期位置
    14			t       = 0.0;   // 時間
    15			dt      = 0.1;   // 時間の刻み幅
    16			v       = 20.0;   // 移動速度
    17	
    18			function start() {
    19				canvas = document.getElementById('canvas_e');
    20				canvas.width  = 600;   // キャンバス要素の幅
    21				canvas.height = 400;   // キャンバス要素の高さ
    22				ctx = canvas.getContext('2d');
    23				y = canvas.height / 2;
    24				timerID = setInterval('draw()', 33);
    25			}
    26						// 描画
    27			function draw()
    28			{
    29				if (x < canvas.width) {
    30					t += dt;
    31					x  = v * t;   // x += v * dt; でも良い
    32				}
    33				else {
    34					x = x0;
    35					t = 0;
    36				}
    37				ctx.clearRect(0, y-20, canvas.width, 40);
    38				ctx.beginPath();
    39				ctx.fillStyle = "rgb(0, 255, 0)";
    40				ctx.arc(x, y, 20, 0, 2*Math.PI, false);
    41				ctx.fill();
    42			}
    43		</SCRIPT>
    44	</HEAD>
    45	<BODY CLASS="white" STYLE="text-align: center" onLoad="start()">
    46		<H1>等速直線運動</H1>
    47		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="600" HEIGHT="400"></CANVAS>
    48	</BODY>
    49	</HTML>
    			

    45 行目

      onLoad 属性の記述によって,このページがロードされると関数 start( 18 行目~ 25 行目)が呼ばれます.

    24 行目

      この記述によって,関数 draw が 33 ms 毎に実行されます.

    29 行目~ 36 行目

      円が右端に到達していないときは,時間を増加させ( 30行目),円の位置を変更しています( 31 行目).また,そうでないときは,時間を 0 に設定し( 35 行目),円の位置を初期位置に戻します( 34 行目).

    37 行目~ 41 行目

      円が描画される領域をクリア( 37 行目)した後,塗りつぶした円を描画しています.

  2. 加速度

      x 軸上の初期位置を x0,x 軸方向の初期速度を v0,かつ,x 軸方向の加速度を a/s2 としたとき,摩擦等の外力がなければ,物体は等加速度運動を行い,t 秒後の速度 v,及び,位置 x は (3) 式,(4) 式のようになります.従って,一定時間( dt )毎に位置を計算する場合は,現在の位置及び速度を x(t),v(t),dt 時間後の位置及び速度を x(t+dt),v(t+dt) としたとき,(5) 式,(6) 式のように表せます.
    v = v0 + at  (3)
    x = x0 + v0t + 0.5at2  (4)
    v(t+dt) = v(t) + a・dt  (5)
    x(t+dt) = x(t) + 0.5(v(t) + v(t+dt))・dt  (6)
    			
      以下のプログラムは,window オブジェクトにおける setInterval メソッドを利用して,等加速度運動を描画したものです.なお,34 行目~ 37 行目は,(5) 式,(6) 式を使用して計算した場合を表しています.

    01	<!DOCTYPE HTML>
    02	<HTML>
    03	<HEAD>
    04		<TITLE>等加速度運動</TITLE>
    05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    06		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    07		<SCRIPT TYPE="text/javascript">
    08			canvas  = null;
    09			ctx     = null;
    10			timerID = -1;
    11			x       = 0.0;   // 円の位置( x )
    12			y       = 0.0;   // 円の位置( y )
    13			x0      = 0.0;   // 円の水平方向の初期位置
    14			t       = 0.0;   // 時間
    15			dt      = 0.04;   // 時間の刻み幅
    16			v0      = 0.0;   // 初期速度
    17			v       = 0.0;   // 速度
    18			a       = 100.0;   // 加速度
    19	
    20			function start() {
    21				canvas = document.getElementById('canvas_e');
    22				canvas.width  = 600;   // キャンバス要素の幅
    23				canvas.height = 400;   // キャンバス要素の高さ
    24				ctx = canvas.getContext('2d');
    25				y = canvas.height / 2;
    26				timerID = setInterval('draw()', 40);
    27			}
    28						// 描画
    29			function draw()
    30			{
    31				if (x < canvas.width) {
    32					t += dt;
    33					x  = v0 * t + 0.5 * a * t * t;
    34	//				var v1 = v;
    35	//				var v2 = v + a * dt;
    36	//				x += 0.5 * (v1 + v2) * dt;
    37	//				v = v2;
    38				}
    39				else {
    40					x = x0;
    41					v = v0;
    42					t = 0;
    43				}
    44				ctx.clearRect(0, y-20, canvas.width, 40);
    45				ctx.beginPath();
    46				ctx.fillStyle = "rgb(0, 255, 0)";
    47				ctx.arc(x, y, 20, 0, 2*Math.PI, false);
    48				ctx.fill();
    49			}
    50		</SCRIPT>
    51	</HEAD>
    52	<BODY CLASS="white" STYLE="text-align: center" onLoad="start()">
    53		<H1>等加速度運動</H1>
    54		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="600" HEIGHT="400"></CANVAS>
    55	</BODY>
    56	</HTML>
    			

  3. 自由落下

      今まで示した例は,すべて,x 軸方向の運動だけでした.一般に,平面上の運動に対しては,x 軸方向,及び,y 軸方向に対して計算してやる必要があります.速度と加速度の応用として,物を投げ上げた場合の運動について考えてみます.摩擦がなければ,x 軸方向に対しては等速度運動を行います.また,y 軸方向に対しては,重力の加速度 g がかかりますので,等加速度運動を行うことになります.投げ上げた時点の水平方向( x 軸方向)の位置を x0,高さ( y 軸方向の位置)を y0,x 軸方向の初期速度を vx0,y 軸方向の初期速度を vy0,かつ,重力の加速度を g/s2 としたとき,t 秒後の x 軸方向の速度 vx,y 軸方向の速度 vy,位置 x,及び,高さ y は以下のようになります.なお,画面上では,実世界と上下方向が逆ですので,上に投げた場合,y 軸方向の初期速度 vy0 は負に,また,加速度 g は正の方向に働きます.
    vx = vx0
    vy = vy0 - gt
    x = x0 + vx0t
    y = y0 + vy0t - 0.5gt2
    			
      以下のプログラムは,window オブジェクトの setInterval メソッドを利用して,自由落下運動を描画したものです.ただし,以下の章においても同様ですが,時間は,実世界における場合と一致していません.なお,39 行目~ 43 行目は,(2) 式,(5) 式,(6) 式を使用して計算した場合を表しています.

    01	<!DOCTYPE HTML>
    02	<HTML>
    03	<HEAD>
    04		<TITLE>自由落下運動</TITLE>
    05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    06		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    07		<SCRIPT TYPE="text/javascript">
    08			canvas  = null;
    09			ctx     = null;
    10			timerID = -1;
    11			x       = 0.0;   // 円の位置( x )
    12			y       = 0.0;   // 円の位置( y )
    13			x0      = 0.0;   // 円の水平方向の初期位置
    14			y0      = 0.0;   // 円の垂直方向の初期位置
    15			t       = 0.0;   // 時間
    16			dt      = 0.04;   // 時間の刻み幅
    17			vx0     = 100.0;   // 水平方向の初期速度
    18			vy0     = -200.0;   // 垂直方向の初期速度
    19			vy      = 0.0;   // 垂直方向の速度
    20			g       = 98.0;   // 加速度
    21	
    22			function start() {
    23				canvas = document.getElementById('canvas_e');
    24				canvas.width  = 600;   // キャンバス要素の幅
    25				canvas.height = 600;   // キャンバス要素の高さ
    26				ctx = canvas.getContext('2d');
    27				y0  = canvas.height / 2;
    28				y   = y0;
    29				vy  = vy0;
    30				timerID = setInterval('draw()', 40);
    31			}
    32						// 描画
    33			function draw()
    34			{
    35				if (x < canvas.height) {
    36					t += dt;
    37					x  = vx0 * t;   // この行と次の行の代わりに,それ以降の5行でも良い
    38					y  = y0 + vy0 * t + 0.5 * g * t * t;
    39	//				x += vx0 * dt;
    40	//				var v1 = vy;
    41	//				var v2 = vy + g * dt;
    42	//				y += 0.5 * (v1 + v2) * dt;
    43	//				vy = v2;
    44				}
    45				else {
    46					x  = x0;
    47					y  = y0;
    48					vy = vy0;
    49					t  = 0;
    50				}
    51				ctx.clearRect(0, 0, canvas.width, canvas.height);
    52				ctx.beginPath();
    53				ctx.fillStyle = "rgb(0, 255, 0)";
    54				ctx.arc(x, y, 20, 0, 2*Math.PI, false);
    55				ctx.fill();
    56			}
    57		</SCRIPT>
    58	</HEAD>
    59	<BODY CLASS="white" STYLE="text-align: center" onLoad="start()">
    60		<H1>自由落下運動</H1>
    61		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="600" HEIGHT="600"></CANVAS>
    62	</BODY>
    63	</HTML>
    			

  4. もう一つの例

      この例では,上 20 度の方向に向かう円が等速度運動,下 20 度に向かう円が等加速度運動をしています.

    01	<!DOCTYPE HTML>
    02	<HTML>
    03	<HEAD>
    04		<TITLE>等速度運動と等加速度運動</TITLE>
    05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    06		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    07		<SCRIPT TYPE="text/javascript">
    08			canvas  = null;
    09			ctx     = null;
    10			timerID = -1;
    11			x1      = 0.0;   // 円1の位置( x )
    12			y1      = 0.0;   // 円1の位置( y )
    13			x2      = 0.0;   // 円2の位置( x )
    14			y2      = 0.0;   // 円2の位置( y )
    15			x0      = 0.0;   // 円の水平方向の初期位置
    16			t       = 0.0;   // 時間
    17			dt      = 0.04;   // 時間の刻み幅
    18			v10     = 50.0;   // 円1の初期速度
    19			v20     = 0.0;   // 円2の初期速度
    20			v       = 0.0;   // 円2の速度
    21			a       = 100.0;   // 円2の加速度
    22			ang1    = -20 * Math.PI / 180;   // 円1の進行方向
    23			ang2    = 20 * Math.PI / 180;   // 円2の進行方向
    24	
    25			function start() {
    26				canvas = document.getElementById('canvas_e');
    27				canvas.width  = 600;   // キャンバス要素の幅
    28				canvas.height = 400;   // キャンバス要素の高さ
    29				ctx = canvas.getContext('2d');
    30				y1  = canvas.height / 2;
    31				y2  = canvas.height / 2;
    32				timerID = setInterval('draw()', 40);
    33			}
    34						// 描画
    35			function draw()
    36			{
    37				if (x2 < canvas.width) {
    38					x1 += v10 * Math.cos(ang1) * dt;
    39					y1 += v10 * Math.sin(ang1) * dt;
    40					var v1 = v;
    41					var v2 = v + a * dt;
    42					x2 += 0.5 * (v1 + v2) * Math.cos(ang2) * dt;
    43					y2 += 0.5 * (v1 + v2) * Math.sin(ang2) * dt;
    44					v   = v2;
    45				}
    46				else {
    47					x1 = x0;
    48					y1 = canvas.height / 2;
    49					x2 = x0;
    50					y2 = canvas.height / 2;
    51					v  = v20;
    52					t  = 0;
    53				}
    54				ctx.clearRect(0, 0, canvas.width, canvas.height);
    55	
    56				ctx.beginPath();
    57				ctx.fillStyle = "rgb(0, 255, 0)";
    58				ctx.arc(x1, y1, 20, 0, 2*Math.PI, false);
    59				ctx.fill();
    60	
    61				ctx.beginPath();
    62				ctx.fillStyle = "rgb(255, 0, 0)";
    63				ctx.arc(x2, y2, 20, 0, 2*Math.PI, false);
    64				ctx.fill();
    65			}
    66		</SCRIPT>
    67	</HEAD>
    68	<BODY CLASS="white" STYLE="text-align: center" onLoad="start()">
    69		<H1>等速度運動と等加速度運動</H1>
    70		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="600" HEIGHT="400"></CANVAS>
    71	</BODY>
    72	</HTML>
    			
    22,23 行目

      20 度をラジアンに変換しています.PI は,Math オブジェクトのプロパティであり,円周率 π の値です.座標系の関係上,上向きの角度が負,下向きの角度が正になっている点に注意してください.

    38,39 行目

      上 20 度の方向に向かう円の x 座標,及び,y 座標を,(2) 式を利用して計算しています.「 v10 * Math.cos(ang1) * dt 」や「 v10 * Math.sin(ang1) * dt 」は,一定値ですので,初期設定の箇所で計算しておいた方が良いと思います.

    40 行目~ 44 行目

      下 20 度の方向に向かう円の x 座標,及び,y 座標を,(5) 式,(6) 式を利用して計算しています.「 0.5 * Math.cos(ang2) * dt 」や「 0.5 * Math.sin(ang2) * dt 」は,一定値ですので,初期設定の箇所で計算しておいた方が良いと思います.

静岡理工科大学 菅沼ホーム JavaScript 目次 基礎技術目次 索引