14.3 円曲線の巾杭計算   [もくじへ] [トップページへ] [前ページへ]

 

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

プログラム例題29

中間点計算後の巾杭計算をおこなえ。

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

考え方

         

 

中間点計算の後は、巾杭点の計算を行います。この計算は各中間点ごとに

左右の巾を入力して、それぞれの中間点における接線の法線方向の座標と

方向角を求めるものです。

したがって、計算には中間点計算の接線方向角と、中間点の座標、それと、

左右の巾が必要です。

通常は各中間点ごとの左右巾を入力できるようにするのが実用的ですが、こ

こでは、簡単のために左右の巾はそれぞれ一定の値を入力するものとします。

 

計算式を次に示します。

   左巾を WL、右巾を WR、中間点の接線方向角を αS、中間点の座標を

   ( XC,YC ) とします。

   左の巾杭点の座標 ( XL,YL )

     XL = XC + WLcos(αS-90°)

     YL = YC + WLsin(αS-90°)

   右の巾杭点の座標 ( XR,YR )

     XR = XC + WRcos(αS+90°)

     YR = YC + WRsin(αS+90°)

 


プログラム

 

<HTML>
<HEAD>
   <TITLE>例題29(円曲線の巾杭計算)</TITLE>

<SCRIPT LANGUAGE="VBScript">
<!--
' 入力データ
        Dim XBP,YBP          'BPの座標
        Dim XIP,YIP          'IPの座標
        Dim XEP,YEP          'EPの座標
        Dim RR               'R
'
        Dim SP               'ステーションピッチ
        Dim DL               '等間隔長
        Dim FN               'BP No.FN + SN
        Dim SN               '
        Dim BPT              'BPの追加距離
        Dim BCT              'BCの追加距離
        Dim ECT              'ECの追加距離
        Dim EPT              'EPの追加距離
        Dim n                '中間点数
'
        Dim WL               '左巾
        Dim WR               '右巾
'
        XBP = -51274.2779
        YBP = -31305.5806
        XIP = -51813.3467
        YIP = -31423.3201
        XEP = -52144.8230
        YEP = -31551.5362
        RR = 2000
'
        SP = 100
        DL = 20
        FN = 0
        SN = 0
'
        WL = 10.0000
        WR = 15.0000
'
' 出力データ
        Dim XBC,YBC          'BCの座標
        Dim XEC,YEC          'ECの座標
        Dim XSP,YSP          'SPの座標
        Dim XM,YM            'Mの座標
        Dim IA               'IA
        Dim CL               'CL
        Dim AL1,AL2          'α1,α2
        Dim L1,L2            'L1,L2
        Dim TL               'TL
        Dim SL               'SL
'
        Dim TK(500)          '中間点の追加距離
        Dim CX(500)          '中間点のX座標
        Dim CY(500)          '中間点のY座標
        Dim SA(500)          '中間点の接線方向角
        Dim GA(500)          '中間点の弦方向角
        Dim GL(500)          '中間点間の直線距離
'
        Dim XL(500)          '左巾杭点のX座標
        Dim YL(500)          '左巾杭点のY座標
        Dim XR(500)          '右巾杭点のX座標
        Dim YR(500)          '右巾杭点のY座標
'
'
'
        Dim PI
        PI = 3.141592653589793
'
'
        Function Dist(xa, ya, xb, yb)
                Dim ss
'
                ss = Sqr((xb-xa)^2 + (yb - ya)^2)
                Dist = ss
'
        End Function
'
'
        Function Alph(xa, ya, xb, yb)
                Dim dx, dy
                Dim Thi              'Atn(dy/dx)
'
                dx = xb - xa
                dy = yb - ya
'
                If dx = 0 Then
                     If dy = 0 Then Alph = 0
                     If dy > 0 Then Alph = PI/2
                     If dy < 0 Then Alph = PI*3/2
                End If
'
                If dx <> 0 Then Thi = Atn(dy/dx)
'
                If dx > 0 Then
                     Alph = Thi + 2*PI
                End If
'
                If dx < 0 Then
                     Alph = Thi + PI
                End If
'
                If Alph >= 2*PI Then Alph = Alph - 2*PI
'
        End Function
'
'
'  角度の変換(秒を度分秒に)
'
        Function Byodfb( x, doo, fun, byo )
                IF x<0 Then x = x + 1296000
                doo = Int(x/3600)
                fun = Int((x - doo*3600)/60)
                byo = x - doo*3600 - fun*60
                IF byo<0 Then byo = 0
        End Function
'
'
'  四捨五入
'
        Function Rund(x,y)
                Dim sg
                If x>=0 Then sg = 1 Else sg =-1
                Rund = sg*Int(abs(x)*10^y + 0.5)/10^y
        End Function
'
'
'  追加距離をステーションNo.に変換
'
        Function Sta(x,fs,es)
                fs = Int(x/SP)
                es = Rund(x - fs*SP,4)
        End Function
'
'
                '計算ボタンをクリック
'
        Sub CAL_OnClick
                Dim x1,y1,x2,y2      'プロシージャ引数
                Dim i                '中間点カウント  
'
                'α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 Then IA = IA + 2*PI
'
                'TL
                TL = Abs(RR)*tan(IA/2)
'
                'BC
                XBC = XBP + (L1-TL)*cos(AL1)
                YBC = YBP + (L1-TL)*sin(AL1)
'
                'EC
                XEC = XIP + TL*cos(AL2)
                YEC = YIP + TL*sin(AL2)
'
                'M
                If RR>0 Then
                   XM = XBC + RR*cos(AL1+PI/2)
                   YM = YBC + RR*sin(AL1+PI/2)
                Else
                   XM = XBC + Abs(RR)*cos(AL1-PI/2)
                   YM = YBC + Abs(RR)*sin(AL1-PI/2)
                End If
'
                'SL
                SL = Abs(RR)/cos(IA/2) - Abs(RR)
'
                'SP
                If RR>0 Then
                   XSP = XIP + SL*cos(AL1+PI/2+IA/2)
                   YSP = YIP + SL*sin(AL1+PI/2+IA/2)
                Else
                   XSP = XIP + SL*cos(AL1-PI/2-IA/2)
                   YSP = YIP + SL*sin(AL1-PI/2-IA/2)
                End If
'
                'CL
                CL = Abs(RR)*IA
'
'
'
'
'========================= 中間点計算 =====================================
'
'        TK()          '中間点の追加距離
'        CX()          '中間点のX座標
'        CY()          '中間点のY座標
'        SA()          '中間点の接線方向角
'        GA()          '中間点の弦方向角(後ろの点からの)
'        GL()          '中間点間の直線距離(後ろの点からの)
'
'      追加距離
                BPT = FN*SP + SN
                BCT = BPT + L1 - TL
                ECT = BCT + CL
                EPT = ECT + L2 - TL
'
'      BP
                Ls = BPT
                i = 1
                TK(i) = Ls
                CX(i) = XBP
                CY(i) = YBP
                SA(i) = AL1
                GA(i) = 0
                GL(i) = 0
'
'      BP<BC
                Ls = Int(Ls/DL)*DL + DL
'
                Do While Ls<BCT
                   i = i + 1
                   TK(i) = Ls
                   CX(i) = XBP + (Ls - BPT)*cos(AL1)
                   CY(i) = YBP + (Ls - BPT)*sin(AL1)
                   SA(i) = AL1
                   GA(i) = AL1
                   GL(i) = TK(i)-TK(i-1)
                   Ls = Ls + DL
                Loop
'
'      BC
                If Ls <> BCT Then
                   i = i + 1
                   TK(i) = BCT
                   CX(i) = XBC
                   CY(i) = YBC
                   SA(i) = AL1
                   GA(i) = AL1
                   GL(i) = TK(i)-TK(i-1)
                End If
'
'      BC<EC (円区間)
                Do While Ls<ECT
                   i = i + 1
                   TK(i) = Ls
                   If RR>0 Then
                      CX(i) = XM + RR*cos(AL1 - PI/2 + (Ls - BCT)/RR)
                      CY(i) = YM + RR*sin(AL1 - PI/2 + (Ls - BCT)/RR)
                   Else
                      CX(i) = XM + Abs(RR)*cos(AL1 + PI/2 + (Ls - BCT)/RR)
                      CY(i) = YM + Abs(RR)*sin(AL1 + PI/2 + (Ls - BCT)/RR)
                   End If
                   SA(i) = AL1 + (Ls - BCT)/RR
                   x1 = CX(i-1)
                   y1 = CY(i-1)
                   x2 = CX(i)
                   y2 = CY(i)
                   GA(i) = Alph(x1,y1,x2,y2)
                   GL(i) = Dist(x1,y1,x2,y2)
                   Ls = Ls + DL
                Loop
'
'      EC
                If Ls<>ECT Then
                   i = i + 1
                   TK(i) = ECT
                   CX(i) = XEC
                   CY(i) = YEC
                   SA(i) = AL2
                   x1 = CX(i-1)
                   y1 = CY(i-1)
                   x2 = CX(i)
                   y2 = CY(i)
                   GA(i) = Alph(x1,y1,x2,y2)
                   GL(i) = Dist(x1,y1,x2,y2)
                End If
'
'      EC<EP
                Do While Ls<EPT
                   i = i + 1
                   TK(i) = Ls
                   CX(i) = XEC + (Ls - ECT)*cos(AL2)
                   CY(i) = YEC + (Ls - ECT)*sin(AL2)
                   SA(i) = AL2
                   GA(i) = AL2
                   GL(i) = TK(i)-TK(i-1)
                   Ls = Ls + DL
                Loop
'
'      EP
                If Ls<>EPT Then
                   Ls = EPT
                   n = i + 1
                   TK(n) = Ls
                   CX(n) = XEP
                   CY(n) = YEP
                   SA(n) = AL2
                   GA(n) = AL2
                   GL(n) = TK(i)-TK(i-1)
                End If
'
'
'
'
'========================= 巾杭点計算 =====================================
'
'        XL()          '左巾杭点のX座標
'        YL()          '左巾杭点のY座標
'        LA()          '左巾杭点の方向角
'        XR()          '右巾杭点のX座標
'        YR()          '右巾杭点のY座標
'        RA()          '右巾杭点の方向角
'
                For i = 1 to n
                   XL(i) = CX(i) + WL*cos(SA(i)-PI/2)
                   YL(i) = CY(i) + WL*sin(SA(i)-PI/2)
                   XR(i) = CX(i) + WR*cos(SA(i)+PI/2)
                   YR(i) = CY(i) + WR*sin(SA(i)+PI/2)
                Next
'
                En
'
        End Sub
'
'
'
Sub En
      Dim i, r
      Dim sta1, sta2
'
'
'=================== 円曲線設置計算結果出力 ================================
'
      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/PI,doo,fun,byo)
      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/PI,doo,fun,byo)
      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/PI,doo,fun,byo)
      byo = Rund(byo,2)
      document.write"<TD ALIGN='right'>",doo & "-" & fun & "-" & byo,"</TD></TR>"
      document.write"</TABLE>"
      document.write"</TABLE>"
      document.write"<BR>"
      document.write"<BR>"
'
'
'========================= 中間点計算出力 ==================================
'
      document.write "<CENTER>","*** 中間点計算 ***","</CENTER><BR>"
'
      document.write"<CENTER><TABLE BORDER='0'>"
      document.write"<TR ALIGN='CENTER'>"
      document.write"<TD ALIGN='left'>","STA.No.","</TD>"
      document.write"<TD ALIGN='center'>","X","</TD>"
      document.write"<TD ALIGN='center'>","Y","</TD>"
      document.write"<TD ALIGN='right'>","S","</TD>"
      document.write"<TD ALIGN='right'>","弦方向角","</TD>"
      document.write"<TD ALIGN='right'>","接線方向角","</TD>"
      document.write"</TR>"
'
      For i = 1 to n
      document.write"<TR ALIGN='CENTER'>"
      r = Sta(TK(i),sta1,sta2)
      document.write"<TD ALIGN='left'>",sta1 & "+" & sta2,"</TD>"
      CX(i) = Rund(CX(i),4)
      CY(i) = Rund(CY(i),4)
      document.write"<TD ALIGN='right'>",CX(i),"</TD>"
      document.write"<TD ALIGN='right'>",CY(i),"</TD>"
      GL(i) = Rund(GL(i),4)
      document.write"<TD ALIGN='right'>",GL(i),"</TD>"
      r = Byodfb(GA(i)*648000/PI,doo,fun,byo)
      byo = Rund(byo,1)
      document.write"<TD ALIGN='right'>",doo & "-" & fun & "-" & byo,"</TD>"
      r = Byodfb(SA(i)*648000/PI,doo,fun,byo)
      byo = Rund(byo,1)
      document.write"<TD ALIGN='right'>",doo & "-" & fun & "-" & byo,"</TD></TR>"
      Next
      document.write"</TABLE>"
      document.write"<BR>"
      document.write"<BR>"
'
'
'========================= 巾杭点計算出力 ==================================
'
      document.write "<CENTER>","*** 巾杭点計算 ***","</CENTER><BR>"
'
      document.write"<CENTER><TABLE BORDER='0'>"
      document.write"<TR ALIGN='CENTER'>"
      document.write"<TD ALIGN='left'>","STA.No.","</TD>"
      document.write"<TD ALIGN='right'>","弦方向角","</TD>"
      document.write"<TD ALIGN='right'>","巾杭方向角","</TD>"
      document.write"<TD ALIGN='right'>","左右巾","</TD>"
      document.write"<TD ALIGN='center'>","X","</TD>"
      document.write"<TD ALIGN='center'>","Y","</TD>"
      document.write"</TR>"
'
      For i = 1 to n
      document.write"<TR ALIGN='CENTER'>"
      r = Sta(TK(i),sta1,sta2)
      document.write"<TD ALIGN='left'>",sta1 & "+" & sta2,"</TD>"
      r = Byodfb(GA(i)*648000/PI,doo,fun,byo)
      byo = Rund(byo,1)
      document.write"<TD ALIGN='right'>",doo & "-" & fun & "-" & byo,"</TD>"
'
      r = Byodfb((SA(i)-PI/2)*648000/PI,doo,fun,byo)
      byo = Rund(byo,1)
      document.write"<TD ALIGN='right'>",doo & "-" & fun & "-" & byo & "L","</TD>"
      WL = Rund(WL,4)
      document.write"<TD ALIGN='right'>",WL,"</TD>"
      XL(i) = Rund(XL(i),4)
      YL(i) = Rund(YL(i),4)
      document.write"<TD ALIGN='right'>",XL(i),"</TD>"
      document.write"<TD ALIGN='right'>",YL(i),"</TD></TR>"
      document.write"<TD ALIGN='right'>"," ","</TD>"
      document.write"<TD ALIGN='right'>"," ","</TD>"
      r = Byodfb((SA(i)+PI/2)*648000/PI,doo,fun,byo)
      byo = Rund(byo,1)
      document.write"<TD ALIGN='right'>",doo & "-" & fun & "-" & byo & "R","</TD>"
      WR = Rund(WR,4)
      document.write"<TD ALIGN='right'>",WR,"</TD>"
      XR(i) = Rund(XR(i),4)
      YR(i) = Rund(YR(i),4)
      document.write"<TD ALIGN='right'>",XR(i),"</TD>"
      document.write"<TD ALIGN='right'>",YR(i),"</TD></TR>"
      Next
      document.write"</TABLE>"

End Sub
'
-->
</SCRIPT>

</HEAD>


<BODY>


<FORM NAME="Form1">
 *** 円曲線設置計算 ***<BR>
<BR>
<INPUT TYPE="button" NAME="CAL" VALUE="計 算">
<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
          ステーションピッチ
        SP = 100
      等間隔長
            DL = 20
      計算開始点の追加距離
            No. 0 + 0
      左巾
            WL = 10
      右巾
            WL = 10

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

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

 

     計算結果の一部

  

 


プログラムの説明

前にも述べたように、VBScript では、データファイルが作れないので、中間点

計算のプログラムに追加する形で作成してあります。

もし、データファイルに中間点計算のデータを記憶することが可能になれば、

プログラムも短く、計算時間もかなり短縮されるでしょう。

巾杭計算そのもののプログラムはそれほど難しいものではありません。

 

Dim WL               '左巾
Dim WR               '右巾
    ・
    ・
    ・
Dim XL(500)          '左巾杭点のX座標
Dim YL(500)          '左巾杭点のY座標
Dim XR(500)          '右巾杭点のX座標
Dim YR(500)          '右巾杭点のY座標

巾杭計算で追加した、グローバル変数です。

左右の巾は配列変数にして、各中間点ごとに異なる値も入力できるようにす

ると、より汎用性が増します。

'========================= 巾杭点計算 =====================================
'
'        XL()          '左巾杭点のX座標
'        YL()          '左巾杭点のY座標
'        LA()          '左巾杭点の方向角
'        XR()          '右巾杭点のX座標
'        YR()          '右巾杭点のY座標
'        RA()          '右巾杭点の方向角
'
For i = 1 to n
   
XL(i) = CX(i) + WL*cos(SA(i)-PI/2)
   
YL(i) = CY(i) + WL*sin(SA(i)-PI/2)
   
XR(i) = CX(i) + WR*cos(SA(i)+PI/2)
   
YR(i) = CY(i) + WR*sin(SA(i)+PI/2)
Next

巾杭点の座標計算です。中間点の座標も接線方向角も求められているので、

座標計算をするだけです。

計算結果の出力は、中間点計算の後に追加しました。そのため、さらに計算

時間が長くなりました。


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

 りょうかんのアドバイス

中間点計算で、必要なデータが求められているので、座標計算を行うだけでし

たね。プログラムは、ほとんど中間点計算で出来上がっていたようなものです。

実用的には、設置計算、中間点計算、巾杭計算を3つのモジュールに分けて、

データファイルにデータを書き込んでモジュール間でデータのやり取りをすれ

ば、もっとスマートになります。

実は、前にも述べたようにVBScriptでは、クッキーというインターネット用のフ

ァイルを扱うことができます。これを計算のデータの書き込み用に利用すれば

なんとかなるかもしれません。りょうかんは、まだ勉強が足りなくてそこまでた

めしていませんが、この講座の最終回あたりに取り上げてみたいと思います。

 

次回は、『クロソイド曲線の設置』の予定です。(11月5日ごろ)

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

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

                                講師 りょうかん


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