14 円曲線 [もくじへ] [トップページへ] [前ページへ]
道路の中心線は折れ線で構成されます。折れ線と折れ線を接合するには、車
両の進行を円滑にするために円曲線を設置します。
ここでは、円曲線の設置、中間点計算、巾杭計算までを考えます。
===================================================
プログラム例題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による測量計算プログラミング入門』
講師 りょうかん