12.距離と方向角計算          [もくじへ] [前ページへ] [トップページへ]

12.1 2点間の距離

===================================================

プログラム例題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 で、このようなビジュアルな測量計算のプログラムも作れ

るということが、おわかりいただけたと思います。

 


12.2 方向角               [もくじへ] [トップページへ]

===================================================

プログラム例題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で、方向角が以上のとき、を減じます。

        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つのプログラムを組み合わせることができます。

このように、ひとつのプログラムはいくつかのプロシージャを組み合わせて作

られます。これをモジュール化プログラミングといいます。複雑な計算も細か

くモジュールに分けることにより、プログラミングが簡単になりメンテナンスも

楽です。

 


[もくじへ] [トップページへ] [次ページへ]