14 円曲線          [もくじへ] [トップページへ] [前ページへ]

道路の中心線は折れ線で構成されます。折れ線と折れ線を接合するには、車

両の進行を円滑にするために円曲線を設置します。

ここでは、円曲線の設置、中間点計算、巾杭計算までを考えます。

14.1 円曲線の設置

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

プログラム例題27

BP、IP、EP の座標と円の半径Rを与えて、円曲線を設置せよ。

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

考え方

         

         BP:起点
         EP:終点
         IP:交点
         BC:曲線始点
         EC:曲線終点
         SP:曲線中点
         M :円の中心点
         R :円の半径
         IA:交角
         L1:BP〜IPまでの距離
         L2:IP〜EPまでの距離
         SL:外線長
         TL:接線長
         CL:曲線長
         α1:BPからIPへの方向角
         α2:IPからEPへの方向角

計算の順序と計算式を示します。

(1)α1、α2、L1、L2

   BP と IP の座標より、距離と方向角の計算でα1と L1を求める。

   IP と EP の座標より、距離と方向角の計算でα2と L2を求める。

(2)IA

   IA = α2 1 (負の場合は360°加える)

(3)TL

   TL = Rtan(IA/2)

(4)BC の座標

   XBC = XBP + (L1 - TL)cosα1

   YBC = YBP + (L1 - TL)sinα1

(5)EC の座標

   XEC = XIP + TLcosα2

   YEC = YIP + TLsinα2

(6)M の座標

   XM = XBC + Rcos(α1 + 90°)

   YM = YBC + Rsin(α1 + 90°)

(7)SL

   SL = Rsec(IA/2) - R

(8)SPの座標

   XSP = XIP + SLcos(α1 + 90°+ IA/2)

   YSP = YIP + SLsin(α1 + 90°+ IA/2)

(9)CL

   CL = R・IA

 

 

プログラム

 

<HTML>
<HEAD>
   <TITLE>例題27(円曲線の設置)</TITLE>

<SCRIPT LANGUAGE="JavaScript">
<!--
// 入力データ
        var XBP,YBP;          // BPの座標
        var XIP,YIP;          // IPの座標
        var XEP,YEP;          // EPの座標
        var RR;               // R
//
        XBP = -51274.2779;
        YBP = -31305.5806;
        XIP = -51813.3467;
        YIP = -31423.3201;
        XEP = -52144.8230;
        YEP = -31551.5362;
        RR = 2000;
//
// 出力データ
        var XBC,YBC;          // BCの座標
        var XEC,YEC;          // ECの座標
        var XSP,YSP;          // SPの座標
        var XM,YM;            // Mの座標
        var IA;               // IA
        var CL;               // CL
        var AL1,AL2;          // α1,α2
        var L1,L2;            // L1,L2
        var TL;               // TL
        var SL;               // SL
//
//
//
//
//
        var doo, fun, byo;                         // 度分秒
//
//
        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 Dobyo( x ) {
                var d, f, b, r;
                d = Math.floor(x);
                f = Math.floor((x - d)*100);
                b = Math.floor(((x - d)*100 - f)*100 + 0.5);
                r = d*3600 + f*60 + b;
                return r;
        }
//
//
//  角度の変換(秒を度分秒に)
//
        function Byodfb( x ) {
                doo = Math.floor(x/3600);
                fun = Math.floor((x - doo*3600)/60);
                byo = x - doo*3600 - fun*60;
                if (byo<0) {byo = 0;}
        }
//
//
//  四捨五入
//
        function Rund(x,y) {
                var sg, r;
                if (x>=0) {sg = 1;}
                else {sg =-1;}
                r = sg*Math.floor(Math.abs(x)*Math.pow(10,y) + 0.5)/Math.pow(10,y);
                return r;
        }
//
//
                // 計算ボタンをクリック
//
        function onCAL( ) {
                var i, r;
                var x1,y1,x2,y2;
//
                // α1, α2, L1, L2
                x1 = XBP;
                y1 = YBP;
                x2 = XIP;
                y2 = YIP;
                AL1 = Alph(x1,y1,x2,y2);
                L1 = Dist(x1,y1,x2,y2);
                x1 = XIP;
                y1 = YIP;
                x2 = XEP;
                y2 = YEP;
                AL2 = Alph(x1,y1,x2,y2);
                L2 = Dist(x1,y1,x2,y2);
//
                // IA
                IA = AL2 - AL1;
                if (IA<0) { IA = IA + 2*Math.PI; }
//
                // TL
                TL = Math.abs(RR)*Math.tan(IA/2);
//
                // BC
                XBC = XBP + (L1-TL)*Math.cos(AL1);
                YBC = YBP + (L1-TL)*Math.sin(AL1);
//
                // EC
                XEC = XIP + TL*Math.cos(AL2);
                YEC = YIP + TL*Math.sin(AL2);
//
                // M
                if (RR>0) {
                   XM = XBC + RR*Math.cos(AL1+Math.PI/2);
                   YM = YBC + RR*Math.sin(AL1+Math.PI/2);
                }
                else {
                   XM = XBC + Math.abs(RR)*Math.cos(AL1-Math.PI/2);
                   YM = YBC + Math.abs(RR)*Math.sin(AL1-Math.PI/2);
                }
//
                // SL
                SL = Math.abs(RR)/Math.cos(IA/2) - Math.abs(RR);
//
                // SP
                if (RR>0) {
                   XSP = XIP + SL*Math.cos(AL1+Math.PI/2+IA/2);
                   YSP = YIP + SL*Math.sin(AL1+Math.PI/2+IA/2);
                }
                else {
                   XSP = XIP + SL*Math.cos(AL1-Math.PI/2-IA/2);
                   YSP = YIP + SL*Math.sin(AL1-Math.PI/2-IA/2);
                }
//
                // CL
                CL = Math.abs(RR)*IA;
//
                En();
//
        }
//
//
                // 円曲線設置計算結果出力
//
function En() {
      var i, r;
//
      document.write ("<CENTER>","*** 円曲線設置計算 ***","</CENTER><BR>");
//
      document.write ("<CENTER><TABLE BORDER='0'>");
      document.write ("<TR ALIGN='CENTER'>");
      document.write ("<TD ALIGN='right'>","   IA","</TD>");
      r = Byodfb(IA*648000/Math.PI);
      byo = Rund(byo,2);
      document.write ("<TD ALIGN='right'>",doo + "-" + fun + "-" + byo,"</TD>");
      document.write ("<TD ALIGN='right'>","    R","</TD>");
      document.write ("<TD ALIGN='right'>",RR,"</TD></TR>");
//
      document.write ("<TR ALIGN='CENTER'>");
      document.write ("<TD ALIGN='left'>","曲線の要素","</TD></TR>");
      document.write ("<TR ALIGN='CENTER'><TD ALIGN='right'>","   TL","</TD>");
      TL = Rund(TL,4);
      document.write ("<TD ALIGN='right'>",TL,"</TD>");
      document.write ("<TD ALIGN='right'>","  (M) X","</TD>");
      XM = Rund(XM,4);
      document.write ("<TD ALIGN='right'>",XM,"</TD></TR>");
//
      document.write ("<TR ALIGN='CENTER'><TD ALIGN='right'>","   CL","</TD>");
      CL = Rund(CL,4);
      document.write ("<TD ALIGN='right'>",CL,"</TD>");
      document.write ("<TD ALIGN='right'>","    Y","</TD>");
      YM = Rund(YM,4);
      document.write ("<TD ALIGN='right'>",YM,"</TD></TR>");
//
      document.write ("<TR ALIGN='CENTER'><TD ALIGN='right'>","  CL/2","</TD>");
      r = Rund(CL/2,4);
      document.write ("<TD ALIGN='right'>",r,"</TD></TR>");
//
      document.write ("<TR ALIGN='CENTER'><TD ALIGN='right'>","   SL","</TD>");
      SL = Rund(SL,4);
      document.write ("<TD ALIGN='right'>",SL,"</TD></TR>");
//
      document.write ("<TR ALIGN='CENTER'>");
      document.write ("<TD ALIGN='left'>","曲線の主要点座標","</TD></TR>");
//
      document.write ("<TR ALIGN='CENTER'><TD ALIGN='right'>","  NAME","</TD>");
      document.write ("<TD ALIGN='right'>","    X    ","</TD>");
      document.write ("<TD ALIGN='right'>","    Y    ","</TD></TR>");
//
      document.write ("<TR ALIGN='CENTER'><TD ALIGN='right'>","   BC","</TD>");
      XBC = Rund(XBC,4);
      document.write ("<TD ALIGN='right'>",XBC,"</TD>");
      YBC = Rund(YBC,4);
      document.write ("<TD ALIGN='right'>",YBC,"</TD></TR>");
//
      document.write ("<TR ALIGN='CENTER'><TD ALIGN='right'>","   SP","</TD>");
      XSP = Rund(XSP,4);
      document.write ("<TD ALIGN='right'>",XSP,"</TD>");
      YSP = Rund(YSP,4);
      document.write ("<TD ALIGN='right'>",YSP,"</TD></TR>");
//
      document.write ("<TR ALIGN='CENTER'><TD ALIGN='right'>","   EC","</TD>");
      XEC = Rund(XEC,4);
      document.write ("<TD ALIGN='right'>",XEC,"</TD>");
      YEC = Rund(YEC,4);
      document.write ("<TD ALIGN='right'>",YEC,"</TD></TR>");
//
      document.write ("<TR ALIGN='CENTER'><TD ALIGN='right'>","   IP","</TD>");
      XIP = Rund(XIP,4);
      document.write ("<TD ALIGN='right'>",XIP,"</TD>");
      YIP = Rund(YIP,4);
      document.write ("<TD ALIGN='right'>",YIP,"</TD></TR>");
//
      document.write ("<TR ALIGN='CENTER'><TD ALIGN='right'>","   α1","</TD>");
      r = Byodfb(AL1*648000/Math.PI);
      byo = Rund(byo,2);
      document.write ("<TD ALIGN='right'>",doo + "-" + fun + "-" + byo,"</TD></TR>");
      document.write ("<TR ALIGN='CENTER'><TD ALIGN='right'>","   α2","</TD>");
      r = Byodfb(AL2*648000/Math.PI);
      byo = Rund(byo,2);
      document.write ("<TD ALIGN='right'>",doo + "-" + fun + "-" + byo,"</TD></TR>");
      document.write ("</TABLE>");
}
//
// -->
</SCRIPT>

</HEAD>


<BODY>


<FORM NAME="Form1">
 *** 円曲線設置計算 ***<BR>
<BR>
<INPUT TYPE="button" NAME="CAL" VALUE="計 算"
onClick="onCAL( )">
<HR>

</FORM>



</BODY>
</HTML>

 

 

入力データと実行結果

      BPの座標
            XBP = -51274.2779
            YBP = -31305.5806
      IPの座標
            XIP = -51813.3467
            YIP = -31423.3201
      EPの座標
            XEP = -52144.8230
            YEP = -31551.5362
      半径
            RR = 2000.0000

     ※データ入力は、代入文で直接代入しています。

     ※ボタンをクリックして実行します。

     ※半径は、進行方向に対して右廻りを正、左廻りを負で入力します。

 

      

 

 

プログラムの説明

入力画面は、中間点計算や巾杭計算などの後続のプログラムが完成した後

で作成することにします。プログラムの作成中は、代入文の方が計算結果を

確認し修正(デバッグ)のたびにデータを入力する必要がなく便利です。

また、四捨五入などのプロシージャは、トラバース計算のものをそのままそっ

くり使っています。

 

if (RR>0) {
   XM = XBC + RR*Math.cos(AL1+Math.PI/2);
   YM = YBC + RR*Math.sin(AL1+Math.PI/2);
}
else {
   XM = XBC + Math.abs(RR)*Math.cos(AL1-Math.PI/2);
   YM = YBC + Math.abs(RR)*Math.sin(AL1-Math.PI/2);
}

右カーブか左カーブかで、計算式が異なる部分です。このプログラムでは理

解を簡単にするために、右カーブ、左カーブの判定を行わず、それぞれ正、

負の値を入力するようにしています。

 

function En() {
 ・
 ・
}

トラバース計算のときと同じように、<TABLE> </TABLE> タグを使って表形

式で出力します。<TABLE BORDER='0'> で、罫線は隠してあります。表作

成のタグについては、13.3 開放トラバース をご覧ください。

 r = Byodfb(AL1*648000/Math.PI) は、ラジアン単位の AL1 を度分

秒に変換します。トラバース計算では、1秒の値まで合わせる必要があったの

で、秒単位で計算するようにしました。しかし、今回はその必要はないのでラ

ジアン単位で計算処理し、結果表示の時に度分秒に変換しています。

 


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

 りょうかんのアドバイス

計算式のとおりプログラミングするだけでしたから、比較的簡単にプログラム

を作れたのではないでしょうか。

それにしても、表作成は面倒ですね。りょうかんも、何回もやり直しました。

しかし、プログラムの善し悪しは入力と出力の部分で決まります。当然、時間

と労力をかけなければなりません。また、デザインのセンスも必要です。

りょうかんは、デザインには自信がありません。面倒くさいことは嫌いなのです。

あとは、みなさんが、りょうかんのプログラムを参考にして、すばらしいプログ

ラムにしてくださることを希望します。

 

次回は、『中間点計算』の予定です。(10月20日ごろ)

この講座に対する、ご意見やご要望はメールでお願いします。

      『JavaScriptによる測量計算プログラミング入門』 

                                講師 りょうかん


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