情報学部 菅沼ホーム JavaScript 目次 基礎技術目次 索引

速度と加速度(その1)

  1. 速度

      x 軸上の初期位置を x0,x 軸方向の速度を v / t としたとき,摩擦等の外力がなければ,物体は等速直線運動を行い,t 秒後の位置 x は (1) 式のようになります.従って,一定時間( dt )毎に位置を計算する場合は,現在の位置を x(t),dt 時間後の位置を x(t+dt) としたとき,(2) 式のように表せます.
    x = x0 + vt  (1)
    x(t+dt) = x(t) + v・dt  (2)			
      以下のプログラムは,2d コンテキストのプロパティとメソッド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		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
    07		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    08		<SCRIPT TYPE="text/javascript">
    09			canvas  = null;
    10			ctx     = null;
    11			timerID = -1;
    12			x       = 0.0;   // 円の位置( x )
    13			y       = 0.0;   // 円の位置( y )
    14			x0      = 0.0;   // 円の水平方向の初期位置
    15			t       = 0.0;   // 時間
    16			dt      = 0.1;   // 時間の刻み幅
    17			v       = 20.0;   // 移動速度
    18	
    19			function start() {
    20				canvas = document.getElementById('canvas_e');
    21				canvas.width  = 600;   // キャンバス要素の幅
    22				canvas.height = 400;   // キャンバス要素の高さ
    23				ctx = canvas.getContext('2d');
    24				y = canvas.height / 2;
    25				timerID = setInterval('draw()', 33);
    26			}
    27						// 描画
    28			function draw()
    29			{
    30				if (x < canvas.width) {
    31					t += dt;
    32					x  = v * t;   // x += v * dt; でも良い
    33				}
    34				else {
    35					x = x0;
    36					t = 0;
    37				}
    38				ctx.clearRect(0, y-20, canvas.width, 40);
    39				ctx.beginPath();
    40				ctx.fillStyle = "rgb(0, 255, 0)";
    41				ctx.arc(x, y, 20, 0, 2*Math.PI, false);
    42				ctx.fill();
    43			}
    44		</SCRIPT>
    45	</HEAD>
    46	<BODY CLASS="white" STYLE="text-align: center" onLoad="start()">
    47		<H1>等速直線運動</H1>
    48		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="600" HEIGHT="400"></CANVAS>
    49	</BODY>
    50	</HTML>
    			
    46 行目

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

    25 行目

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

    30 行目~ 37 行目

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

    38 行目~ 42 行目

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

  2. 加速度

      x 軸上の初期位置を x0,x 軸方向の初期速度を v0 / t,かつ,x 軸方向の加速度を a / t2 としたとき,摩擦等の外力がなければ,物体は等加速度運動を行い,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 メソッドを利用して,等加速度運動を描画したものです.なお,35 行目~ 38 行目は,(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		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
    07		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    08		<SCRIPT TYPE="text/javascript">
    09			canvas  = null;
    10			ctx     = null;
    11			timerID = -1;
    12			x       = 0.0;   // 円の位置( x )
    13			y       = 0.0;   // 円の位置( y )
    14			x0      = 0.0;   // 円の水平方向の初期位置
    15			t       = 0.0;   // 時間
    16			dt      = 0.04;   // 時間の刻み幅
    17			v0      = 0.0;   // 初期速度
    18			v       = 0.0;   // 速度
    19			a       = 100.0;   // 加速度
    20	
    21			function start() {
    22				canvas = document.getElementById('canvas_e');
    23				canvas.width  = 600;   // キャンバス要素の幅
    24				canvas.height = 400;   // キャンバス要素の高さ
    25				ctx = canvas.getContext('2d');
    26				y = canvas.height / 2;
    27				timerID = setInterval('draw()', 40);
    28			}
    29						// 描画
    30			function draw()
    31			{
    32				if (x < canvas.width) {
    33					t += dt;
    34					x  = v0 * t + 0.5 * a * t * t;
    35	//				let v1 = v;
    36	//				let v2 = v + a * dt;
    37	//				x += 0.5 * (v1 + v2) * dt;
    38	//				v = v2;
    39				}
    40				else {
    41					x = x0;
    42					v = v0;
    43					t = 0;
    44				}
    45				ctx.clearRect(0, y-20, canvas.width, 40);
    46				ctx.beginPath();
    47				ctx.fillStyle = "rgb(0, 255, 0)";
    48				ctx.arc(x, y, 20, 0, 2*Math.PI, false);
    49				ctx.fill();
    50			}
    51		</SCRIPT>
    52	</HEAD>
    53	<BODY CLASS="white" STYLE="text-align: center" onLoad="start()">
    54		<H1>等加速度運動</H1>
    55		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="600" HEIGHT="400"></CANVAS>
    56	</BODY>
    57	</HTML>
    			

  3. 自由落下

      今まで示した例は,すべて,x 軸方向の運動だけでした.一般に,平面上の運動に対しては,x 軸方向,及び,y 軸方向に対して計算してやる必要があります.速度と加速度の応用として,物を投げ上げた場合の運動について考えてみます.摩擦がなければ,x 軸方向に対しては等速度運動を行います.また,y 軸方向に対しては,重力の加速度 g がかかりますので,等加速度運動を行うことになります.投げ上げた時点の水平方向( x 軸方向)の位置を x0,高さ( y 軸方向の位置)を y0,x 軸方向の初期速度を vx0 / t,y 軸方向の初期速度を vy0 / t,かつ,重力の加速度を g / t2 としたとき,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 メソッドを利用して,自由落下運動を描画したものです.ただし,以下の章においても同様ですが,時間は,実世界における場合と一致していません.なお,40 行目~ 44 行目は,(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		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
    07		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    08		<SCRIPT TYPE="text/javascript">
    09			canvas  = null;
    10			ctx     = null;
    11			timerID = -1;
    12			x       = 0.0;   // 円の位置( x )
    13			y       = 0.0;   // 円の位置( y )
    14			x0      = 0.0;   // 円の水平方向の初期位置
    15			y0      = 0.0;   // 円の垂直方向の初期位置
    16			t       = 0.0;   // 時間
    17			dt      = 0.04;   // 時間の刻み幅
    18			vx0     = 100.0;   // 水平方向の初期速度
    19			vy0     = -200.0;   // 垂直方向の初期速度
    20			vy      = 0.0;   // 垂直方向の速度
    21			g       = 98.0;   // 加速度
    22	
    23			function start() {
    24				canvas = document.getElementById('canvas_e');
    25				canvas.width  = 600;   // キャンバス要素の幅
    26				canvas.height = 600;   // キャンバス要素の高さ
    27				ctx = canvas.getContext('2d');
    28				y0  = canvas.height / 2;
    29				y   = y0;
    30				vy  = vy0;
    31				timerID = setInterval('draw()', 40);
    32			}
    33						// 描画
    34			function draw()
    35			{
    36				if (x < canvas.height) {
    37					t += dt;
    38					x  = vx0 * t;   // この行と次の行の代わりに,それ以降の5行でも良い
    39					y  = y0 + vy0 * t + 0.5 * g * t * t;
    40	//				x += vx0 * dt;
    41	//				let v1 = vy;
    42	//				let v2 = vy + g * dt;
    43	//				y += 0.5 * (v1 + v2) * dt;
    44	//				vy = v2;
    45				}
    46				else {
    47					x  = x0;
    48					y  = y0;
    49					vy = vy0;
    50					t  = 0;
    51				}
    52				ctx.clearRect(0, 0, canvas.width, canvas.height);
    53				ctx.beginPath();
    54				ctx.fillStyle = "rgb(0, 255, 0)";
    55				ctx.arc(x, y, 20, 0, 2*Math.PI, false);
    56				ctx.fill();
    57			}
    58		</SCRIPT>
    59	</HEAD>
    60	<BODY CLASS="white" STYLE="text-align: center" onLoad="start()">
    61		<H1>自由落下運動</H1>
    62		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="600" HEIGHT="600"></CANVAS>
    63	</BODY>
    64	</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		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
    07		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    08		<SCRIPT TYPE="text/javascript">
    09			canvas  = null;
    10			ctx     = null;
    11			timerID = -1;
    12			x1      = 0.0;   // 円1の位置( x )
    13			y1      = 0.0;   // 円1の位置( y )
    14			x2      = 0.0;   // 円2の位置( x )
    15			y2      = 0.0;   // 円2の位置( y )
    16			x0      = 0.0;   // 円の水平方向の初期位置
    17			t       = 0.0;   // 時間
    18			dt      = 0.04;   // 時間の刻み幅
    19			v10     = 50.0;   // 円1の初期速度
    20			v20     = 0.0;   // 円2の初期速度
    21			v       = 0.0;   // 円2の速度
    22			a       = 100.0;   // 円2の加速度
    23			ang1    = -20 * Math.PI / 180;   // 円1の進行方向
    24			ang2    = 20 * Math.PI / 180;   // 円2の進行方向
    25	
    26			function start() {
    27				canvas = document.getElementById('canvas_e');
    28				canvas.width  = 600;   // キャンバス要素の幅
    29				canvas.height = 400;   // キャンバス要素の高さ
    30				ctx = canvas.getContext('2d');
    31				y1  = canvas.height / 2;
    32				y2  = canvas.height / 2;
    33				timerID = setInterval('draw()', 40);
    34			}
    35						// 描画
    36			function draw()
    37			{
    38				if (x2 < canvas.width) {
    39					x1 += v10 * Math.cos(ang1) * dt;
    40					y1 += v10 * Math.sin(ang1) * dt;
    41					let v1 = v;
    42					let v2 = v + a * dt;
    43					x2 += 0.5 * (v1 + v2) * Math.cos(ang2) * dt;
    44					y2 += 0.5 * (v1 + v2) * Math.sin(ang2) * dt;
    45					v   = v2;
    46				}
    47				else {
    48					x1 = x0;
    49					y1 = canvas.height / 2;
    50					x2 = x0;
    51					y2 = canvas.height / 2;
    52					v  = v20;
    53					t  = 0;
    54				}
    55				ctx.clearRect(0, 0, canvas.width, canvas.height);
    56	
    57				ctx.beginPath();
    58				ctx.fillStyle = "rgb(0, 255, 0)";
    59				ctx.arc(x1, y1, 20, 0, 2*Math.PI, false);
    60				ctx.fill();
    61	
    62				ctx.beginPath();
    63				ctx.fillStyle = "rgb(255, 0, 0)";
    64				ctx.arc(x2, y2, 20, 0, 2*Math.PI, false);
    65				ctx.fill();
    66			}
    67		</SCRIPT>
    68	</HEAD>
    69	<BODY CLASS="white" STYLE="text-align: center" onLoad="start()">
    70		<H1>等速度運動と等加速度運動</H1>
    71		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="600" HEIGHT="400"></CANVAS>
    72	</BODY>
    73	</HTML>
    			
    23,24 行目

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

    39,40 行目

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

    41 行目~ 45 行目

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

情報学部 菅沼ホーム JavaScript 目次 基礎技術目次 索引