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による測量計算プログラミング入門』
講師 りょうかん