12.距離と方向角計算 [もくじへ] [前ページへ] [トップページへ]
===================================================
プログラム例題20
2点の座標を入力して、その距離を求めよ。
=========================================================
<HTML>
<HEAD>
<TITLE>例題20</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
//
function
Dist(xa, ya, xb, yb) {
var
ss;
//
ss
= Math.sqrt(Math.pow((xb-xa),2) + Math.pow((yb - ya),2));
return
ss;
}
//
//
function
OnCalc( ) {
var
x1,y1,x2,y2,s;
//
x1
= eval(document.Form1.X1.value);
y1
= eval(document.Form1.Y1.value);
x2
= eval(document.Form1.X2.value);
y2
= eval(document.Form1.Y2.value);
//
s
= Dist(x1,y1,x2,y2);
document.Form1.S.value
= s;
}
//
// -->
</SCRIPT>
</HEAD>
<BODY>
<FORM NAME="Form1">
*** 2点間の距離計算 ***<BR>
<BR>
X1= <INPUT TYPE="text" NAME="X1"
size=15><BR>
Y1= <INPUT TYPE="text" NAME="Y1"
size=15><BR>
<BR>
X2= <INPUT TYPE="text" NAME="X2"
size=15><BR>
Y2= <INPUT TYPE="text" NAME="Y2"
size=15><BR>
<BR>
<INPUT TYPE="button"
NAME="calc" VALUE="計算" onClick="OnCalc( )"><BR>
<BR>
距離 S= <INPUT TYPE="text" NAME="S"
size=15><BR>
</FORM>
</BODY>
</HTML>
点1 ( X1,Y1) と点2 (X2,Y2) の距離は、次の式で求められます。
点1(-300, 200),点2(-250, 400)の場合の実行結果は、次のようになります。
function Dist(xa, ya, xb, yb) {
var ss;
//
ss
= Math.sqrt(Math.pow((xb-xa),2) + Math.pow((yb - ya),2));
return ss;
}
2点間の距離を計算する関数プロシージャです。これぐらいの計算は関数プ
ロシージャにしなくてもいいのですが、座標値から距離を求める計算は後で
使うので独立させておきます。
function OnCalc( ) { @
var x1,y1,x2,y2,s;
//
x1
= eval(document.Form1.X1.value); A
y1
= eval(document.Form1.Y1.value); B
x2
= eval(document.Form1.X2.value); C
y2
= eval(document.Form1.Y2.value); D
//
s
= Dist(x1,y1,x2,y2); E
document.Form1.S.value
= s; F
}
コマンドボタンをクリックすると、この関数プロシージャが実行されます。
Aは、
document (HTML文書)の、
Form1 という名前のフォームにある、
X1 という名前のテキストボックスの
データ(value)を
数値に変換(eval( ))し、
変数 x1 に代入
しています。
eval( ) は、文字列を数値に変換する関数です。
Eは、x1, y1, x2, y2 の引数で Dist 関数プロシージャを呼び出し、計算結
果を変数 s に代入しています。
Fは、s の値をテキストボックスに表示します。
<FORM
NAME="Form1"> @
*** 2点間の距離計算 ***<BR> A
<BR>
X1= <INPUT
TYPE="text" NAME="X1" size=15><BR> B
Y1= <INPUT
TYPE="text" NAME="Y1" size=15><BR> C
<BR>
X2= <INPUT
TYPE="text" NAME="X2" size=15><BR> D
Y2= <INPUT
TYPE="text" NAME="Y2" size=15><BR> E
<BR>
<INPUT
TYPE="button" NAME="calc" VALUE="計算"
onClick="OnCalc( )"><BR> F
<BR>
距離 S= <INPUT
TYPE="text" NAME="S" size=15><BR> G
</FORM> H
<FORM></FORM>タグのブロックで、入力画面を作ります。JavaScript で、
このような画面を作るには、document.write ・・・ のような形でタグを書き込
めばいいのですが、直接タグを使った方が簡単です。
計算は JavaScript、画面はHTMLタグで作るというように、両方を組み合わ
せてプログラミングしていきます。
@で、Form1 という名前のフォームを作ります。
Aは、そのフォーム画面に"*** 2点間の距離計算 ***"というタ
イトルを表示します。HTMLでは、その中に書かれた文字がそのまま表示さ
れます。普通に表示するだけなら、特別な命令やタグは必要ありません。
<BR> は改行のタグです。文字の間にスペースを入れる時は全角のスペー
スを入れます。
Bは、"X1=" の文字を表示し、X1 という名前の半角15文字分の大きさの
テキストボックスを作ります。先頭のスペースで、表示位置を少し右にずらし
ています。
Fは、calc という名前のコマンドボタンを作ります。"計算"はボタンに表示さ
れる文字です。onClick="OnCalc( )" でクリックされたら、OnCalc( ) のプロ
シージャを実行します。
距離を四捨五入をすればもっと使い易くなりますが、インターネット用の言語
である JavaScript で、このようなビジュアルな測量計算のプログラムも作れ
るということが、おわかりいただけたと思います。
===================================================
プログラム例題21
2点の座標を入力して、その方向角を求めよ。
=========================================================
考え方
●方向角の計算
方向角というのは、数学の三角関数の角度の扱いと同じで、X軸の正の方向
からY軸の正の方向に測った角のことです。通常、数学の座標では横軸をX
軸、縦軸をY軸としますが、測量の座標では北の方向を基準に角度を測るた
め、縦軸がX軸、横軸がY軸になっています。
しかし、測量座標は数学座標そのものをY軸周りに180度回転して裏返しに
し、右回り(時計回り)に90度回転しただけなので、角の向きが反対回りに見
えますが、考え方は数学座標と全く同じになります。当然のことですが、三角
関数の公式もそのまま使えます。
点1から点2への方向角αを求めるには、次のようにします。
(1)2点の座標の座標差を求めます。
dX = X2 - X1
dY = Y2 - Y1
(2)dX の符号で場合分けします。
@)dX = 0 の場合、
dY = 0 のとき、α = 0°
dY > 0 のとき、α = 90°
dY < 0 のとき、α = 270°
A)dX≠0 の場合、
まず、dY/dX の逆正接(θ
= )を求めます。
各象限での方向角αは、
(ア)T象限 ( X>0, Y>0 ) : α = θ
(イ)U、V象限 ( X<0 ) : α = θ + 180°
(ウ)W象限 ( X>0, Y<0) : α = θ + 360°
なぜなら、θ = で求められた角は90°以内の角になり、
図のように、dY/dX と同じ符号をもつからです。
また、T象限とW象限は360°(=1回転)の違いなので、
α = θ + 360°
として、もしαが360°超えたら360°を減ずるようにすると、1つの
式にまとめることができます。
●角度の変換(ラジアンを度分秒に変換)
コンピュータ内(組み込み関数)で扱われる角度の単位はラジアンです。した
がって、ラジアンを度分秒に変換したり、度分秒をラジアンに変換するプログ
ラムを作成しなければなりません。度分秒をラジアンに変換するプログラムは、
例題7で作成しましたので、ここではラジアンを度分秒に変換するプログラム
について考えます。
R は変換前の角度(ラジアン)とします。
D = R×180/π で度に変換
A = Int(D) で整数部の度を取り出す
B = (D - A)×60 で度を除いた値を分になおす
さらに、
B = Int(B) で分を取り出す
C = D - A - B/60 で秒の部分を取り出す
さらに、
C = C×3600 で秒になおす
これで、A, B, C にそれぞれ度、分、秒の値が求められます。
以上の考え方でプログラミングします。
<HTML>
<HEAD>
<TITLE>例題21</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
//
var d, f, b; //
グローバル変数の宣言
//
function
Alph(xa, ya, xb, yb) {
var
dx, dy;
var
Thi; // atan(dy/dx)
var
A;
//
dx
= xb - xa;
dy
= yb - ya;
//
if
(dx == 0) {
if (dy == 0) { A = 0; }
if (dy > 0) { A =
Math.PI/2; }
if (dy < 0) { A =
Math.PI*3/2; }
}
//
if
(dx != 0) { Thi = Math.atan(dy/dx); }
//
if
(dx > 0) { A = Thi + 2*Math.PI; }
//
if
(dx < 0) { A = Thi + Math.PI; }
//
if
(A >= 2*Math.PI) { A = A - 2*Math.PI; }
return
A;
//
}
//
//
function
RadDeg (r) {
var
deg;
//
deg
= r * 180/Math.PI;
d
= Math.floor(deg);
f =
Math.floor((deg - d)*60);
if ( f<0
) { f=0; }
b =
(deg - d - f/60)*3600;
if ( b<0 ) { b=0; } else
{ b=Math.floor(b+0.5); }
//
}
//
//
function
OnCalc( ) {
var
x1, y1, x2, y2, t;
var
doo, fun, byo;
//
x1
= eval(document.Form1.X1.value);
y1
= eval(document.Form1.Y1.value);
x2
= eval(document.Form1.X2.value);
y2
= eval(document.Form1.Y2.value);
//
t =
Alph(x1,y1,x2,y2);
RadDeg(t);
doo = d;
fun = f;
byo = b;
document.Form1.T.value
= doo+"-"+fun+"-"+byo;
}
//
//
// -->
</SCRIPT>
</HEAD>
<BODY>
<FORM NAME="Form1">
*** 方向角計算 ***<BR>
<BR>
X1= <INPUT TYPE="text"
NAME="X1" size=15><BR>
Y1= <INPUT TYPE="text"
NAME="Y1" size=15><BR>
<BR>
X2= <INPUT TYPE="text"
NAME="X2" size=15><BR>
Y2= <INPUT TYPE="text"
NAME="Y2" size=15><BR>
<BR>
<INPUT TYPE="button"
NAME="calc" VALUE="計算"
onClick="OnCalc( )"><BR>
<BR>
方向角 T = <INPUT TYPE="text" NAME="T"
size=15><BR>
</FORM>
</BODY>
</HTML>
点1(250, -300),点2(-200, 400)の場合の実行結果は、つぎのようになりま
す。
var d, f, b; // グローバル変数の宣言
プロシージャの外で宣言された変数は、各プロシージャで有効です。このよう
な変数をグローバル変数といいます。これに対し、プロシージャ内で宣言され
た変数は、そのプロシージャ内だけで有効です。このような変数をローカル変
数といいます。変数 d, f, b には、関数プロシージャ RadDeg で返される値が
代入されています。JavaScript では、プロシージャで返すことができる値は1
個なので、グローバル変数にしました。(他にも方法があるかもしれません。)
function Alph(xa, ya, xb, yb) { @
var dx, dy;
var Thi; // atan(dy/dx)
var A;
//
dx = xb - xa;
dy = yb - ya;
//
if (dx == 0) {
if (dy
== 0) { A = 0; }
if (dy
> 0) { A = Math.PI/2; }
if (dy
< 0) { A = Math.PI*3/2; }
}
//
if (dx != 0) { Thi = Math.atan(dy/dx); }
//
if (dx > 0) { A = Thi
+ 2*Math.PI; }
//
if (dx < 0) { A = Thi
+ Math.PI; }
//
if (A >= 2*Math.PI) { A = A -
2*Math.PI; } A
return
A;
//
}
2点の座標から方向角を計算するプローシージャです。
@で、xa, ya, xb, yb にそれぞれ X1, Y1, X2, Y2 が渡されます。
Aで、方向角が2π以上のとき、2πを減じます。
function RadDeg (r) {
var deg;
//
deg = r * 180/Math.PI;
d
= Math.floor(deg);
f = Math.floor((deg - d)*60);
if ( f<0 ) { f=0; } @
b = (deg - d - f/60)*3600;
if (
b<0 ) { b=0; } else { b=Math.floor(b+0.5); } A
//
}
ラジアンの値を度分秒に変換するプローシージャです。
@は、減算の結果がちょうど0の場合、コンピュータの変換誤差で計算結果
がマイナスになる場合があるため、そのときは0にします。
Aは、マイナスのときは変換誤差を修正し、それ以外のときは四捨五入しま
す。
さきに述べたとおり、JavaScript のプロシージャでは、計算された結果を1個
しか返せないため、d, f, b をグローバル変数にしています。
function OnCalc( ) {
var x1, y1, x2, y2, t;
var doo, fun, byo;
//
x1
= eval(document.Form1.X1.value);
y1
= eval(document.Form1.Y1.value);
x2
= eval(document.Form1.X2.value);
y2
= eval(document.Form1.Y2.value);
//
t = Alph(x1,y1,x2,y2); @
RadDeg(t); A
doo = d;
fun = f;
byo = b;
document.Form1.T.value
= doo+"-"+fun+"-"+byo;
}
コマンドボタンをクリックしたとき、実行されるプロシージャです。
@は、引数 x1, y1, x2, y2 を方向角を求める関数プロシージャ Alph に渡し、
その結果(方向角)を t に代入します。
Aは、その t をラジアンを度分秒を求める関数プロシージャ RadDeg に渡し、
その結果はグローバル変数 d, f, b で返されます。
Bは、doo, fun, byo の値を "-" でつないでテキストボックスTに表示します。
数値変数と文字列をつなげて表示するときは、(,)でなく(+)にしないとうまく
表示されません。
長いプログラムになりましたが、このプログラムは後でも出てきますので、よく
理解しておいてください。
12.3 距離と方向角計算 [もくじへ] [トップページへ]
===================================================
プログラム例題22
例題20と例題21のプログラムを組み合わせて、2点間の距離と方向
角を求めるプログラムを作成せよ。
=========================================================
<HTML>
<HEAD>
<TITLE>例題22</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
//
var d, f, b // グローバル変数の宣言
//
//
function
Dist(xa, ya, xb, yb) {
var
ss;
//
ss
= Math.sqrt(Math.pow((xb-xa),2) + Math.pow((yb - ya),2));
return
ss;
}
//
//
function
Alph(xa, ya, xb, yb) {
var
dx, dy;
var
Thi; // atan(dy/dx)
var
A;
//
dx
= xb - xa;
dy
= yb - ya;
//
if
(dx == 0) {
if (dy == 0) { A = 0; }
if (dy > 0) { A =
Math.PI/2; }
if (dy < 0) { A =
Math.PI*3/2; }
}
//
if
(dx != 0) { Thi = Math.atan(dy/dx); }
//
if
(dx > 0) { A = Thi + 2*Math.PI; }
//
if
(dx < 0) { A = Thi + Math.PI; }
//
if
(A >= 2*Math.PI) { A = A - 2*Math.PI; }
return
A;
//
}
//
//
function
RadDeg (r) {
var
deg;
//
deg
= r * 180/Math.PI;
d
= Math.floor(deg);
f =
Math.floor((deg - d)*60);
if ( f<0
) { f=0; }
b =
(deg - d - f/60)*3600;
if ( b<0 ) { b=0; } else
{ b=Math.floor(b+0.5); }
//
}
//
//
function OnCalc(
) {
var
x1, y1, x2, y2, s, t;
//
x1
= eval(document.Form1.X1.value);
y1
= eval(document.Form1.Y1.value);
x2
= eval(document.Form1.X2.value);
y2
= eval(document.Form1.Y2.value);
//
s
= Dist(x1,y1,x2,y2);
//
t =
Alph(x1,y1,x2,y2);
RadDeg(t);
doo = d;
fun = f;
byo = b;
//
document.Form1.S.value
= s;
document.Form1.T.value
= doo+"-"+fun+"-"+byo;
//
}
//
//
// -->
</SCRIPT>
</HEAD>
<BODY>
<FORM NAME="Form1">
*** 2点間の距離と方向角計算 ***<BR>
<BR>
X1= <INPUT TYPE="text"
NAME="X1" size=15><BR>
Y1= <INPUT TYPE="text"
NAME="Y1" size=15><BR>
<BR>
X2= <INPUT TYPE="text"
NAME="X2" size=15><BR>
Y2= <INPUT TYPE="text"
NAME="Y2" size=15><BR>
<BR>
<INPUT TYPE="button"
NAME="calc" VALUE="計算"
onClick="OnCalc( )"><BR>
<BR>
距離 S= <INPUT TYPE="text" NAME="S"
size=15><BR>
<BR>
方向角 T= <INPUT TYPE="text" NAME="T"
size=15><BR>
</FORM>
</BODY>
</HTML>
点1(300, 200),点2(-320, -260)の場合の実行結果は、つぎのようになりま
す。
プログラムそのものは当然ながくなりますが、ほとんど変更することなしに、
2つのプログラムを組み合わせることができます。
このように、ひとつのプログラムはいくつかのプロシージャを組み合わせて作
られます。これをモジュール化プログラミングといいます。複雑な計算も細か
くモジュールに分けることにより、プログラミングが簡単になりメンテナンスも
楽です。