2019/10/28
最大弛み位置mの導出について追加しました。
2019/10/19
パラボラ式グラフ高さ計算を修正しました。
2019/10/07
パラボラ式(近似計算)を追加しました。
懸垂線
横弾性係数のゼロの線の両端を支持して、自重で垂らして出来る線が懸垂線です。
送電線は、懸垂線です。
次の計算式は、インターネットで探してきた計算式です。
プログラムを組んで計算し、計算式が正しいことを確認しました。
左が懸垂線の基本的な計算式です。
懸垂線の形状は、線自重と水平張力で決まります。
水平方向張力は線の何処の部分でも一定です。
線方向の張力は、線の自重が加わるので支持している場所で高い方の支持部が一番大きくなり、一番弛んで水平になった位置の張力が水平張力と一致します。
懸垂線の近似計算として放物線の計算式(パラボラ式)がありますが、ハイパボリックの計算が出来なかった時、使用していましたが、現在では電卓でも計算出来るものがあるので放物線での計算は不要でしょう。
線の両端の高さが違う場合で、弛みが大きい場合は一番弛みが大きくなる場所は両端の内側になりますが、張力が大きく弛みが小さい場合は、一番弛みが大きくなる場所は、低い方の端の外側の仮想点となります。
懸垂線の各位置の弛みは、最大弛み位置を基準として計算した後、低い方の支持位置を基準に変換します。
懸垂線の最大弛み位置mを求めないと、懸垂線の殆どの計算が出来ないので、最大弛み位置mの計算式の導き出し方について掲載します。
双曲線関数の積和の公式を利用します。
各位置の弛みを求めるプログラム実行例
最大弛み位置が支持点間の外側となる場合でも、支持点間の外側のグラフは作図されません。
パラボラ式で、各位置の弛みを求める計算は、Y=X2/(2C)なので修正しました。
前は、通過点三点から二次式を求めてから計算していました、計算結果に変化はありません。
パラボラ式の近似計算の場合、弛みが大きくなると、カテナリー計算より弛みが小さくなります。
上側の曲線がパラボラ式で計算したものです。
送電線の場合は、大きな弛みを付けることは無いので、実用上は問題ない値です。
プログラム
unit Main; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, VclTee.TeeGDIPlus, VCLTee.TeEngine, VCLTee.Series, VCLTee.TeeProcs, VCLTee.Chart; type TForm1 = class(TForm) Memo1: TMemo; Panel1: TPanel; W_Edit: TLabeledEdit; h_Edit: TLabeledEdit; T_Edit: TLabeledEdit; S_Edit: TLabeledEdit; Chart1: TChart; Series1: TLineSeries; Series2: TPointSeries; Button1: TButton; CheckBox1: TCheckBox; Series3: TLineSeries; Series4: TPointSeries; Series5: TLineSeries; procedure Button1Click(Sender: TObject); private { Private 宣言 } function datainput: boolean; procedure Drawing; procedure parabole_calc; public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm} uses system.Math; var S : double; // 支持間 m h : double; // 高低差 m W : double; // 線自重 kgw/m T : double; // 線張力 kgf C : double; // カテナリー数 d : double; // 弛度 m m : double; // 最大たるみ位置 m dm :double; // 最大たるみ位置 弛度 m x : double; // 斜弛度地点までの距離 m L : double; // 線実長 // 入力処理 function TForm1.datainput: boolean; var ch: integer; begin S := 0; W := 0; T := 0; result := false; val(S_edit.Text, S, ch); if (ch <> 0) or (S <= 0) then begin application.MessageBox('支持間距離に間違いがあります。','注意',0); exit; end; val(h_edit.Text, h, ch); if ch <> 0 then begin application.MessageBox('高低差に間違いがあります。','注意',0); exit; end; val(W_edit.Text, W, ch); if (ch <> 0) or (W <= 0) then begin application.MessageBox('線自重に間違いがあります。','注意',0); exit; end; val(T_edit.Text, T, ch); if (ch <> 0) or (T <= 0) then begin application.MessageBox('線張力に間違いがあります。','注意',0); exit; end; result := true; end; // 懸垂線作図 // 低い方の支持位置基準 procedure TForm1.Drawing; const K = 500; var xn : double; x, dx : double; y : double; i : integer; begin dx := S / K; // 懸垂線作図 for i := 0 to K do begin xn := i * dx; // 計算位置 x := abs(xn - m); // 最大弛み位置からの距離 y := C * (cosh(x / C) - 1) - dm; // 高さ 低い方の支持位置を基準として計算 Series1.AddXY(xn, y); end; // 斜弛み位置通過接線 Series3.AddXY(0, 0 - d); // 斜弛み位置通過傾斜線 低い方 Series3.AddXY(S, h - d); // 斜弛み位置通過傾斜線 高い方 // 支持位置 斜弛度地点 丸表示 Series4.AddXY(0, 0); // 低い方の支持位置 x := m + C * arcsinh(h / S); // 斜弛度地点距離 x y := h / S * x - d; // 斜弛度y座標 Series4.AddXY(x, y); // 斜弛度xy Series4.AddXY(S, h); // 高い方の支持位置 end; // パラボラ式近似計算 procedure TForm1.parabole_calc; const K = 100; var dp : double; Lp : double; mp : double; dmp : double; xi, yi : double; i : integer; dx, xp : double; begin dp := W*S*S/8/T; // 斜弛度 Lp := S+W*W*S*S*S/24/T/T + h*h/2/S; // 線 長 mp := S/2 - C*h/S; // 最大弛み位置 dmp := dp*(1 - h/4/dp)*(1 - h/4/dp); // 最大弛み memo1.Lines.Add(''); memo1.Lines.Add('パラボラ式 近似計算'); memo1.Lines.Add('最大たるみ位置 m= ' + floatTostr(mp)); memo1.Lines.Add('最大位置 弛度 dm= ' + floatTostr(dmp)); memo1.Lines.Add('斜弛度位置 x=' + floatTostr(S/2)); memo1.Lines.Add('斜弛度 d=' + floatTostr(dp)); memo1.Lines.Add('線 長 L=' + floatTostr(Lp)); dx := S / K; for i := 0 to K do begin xi := i * dx; xp := abs(xi - mp); yi := xp * xp / 2 / C - dmp; Series5.AddXY(xi, yi); end; end; // 懸垂線計算の実行 procedure TForm1.Button1Click(Sender: TObject); var s1 : double; lmin, lmax : double; bmin, bmax : double; mg : double; begin if not datainput then exit; memo1.Clear; C := T / W; memo1.Lines.Add('カテナリー数 C= ' + floatTostr(C)); m := S / 2 - C * arcsinh(h / (2 * C * sinh(S / 2 / C))); memo1.Lines.Add('最大たるみ位置 m= ' + floatTostr(m)); s1 := abs(m * 2); dm := C * (cosh(s1 / 2 / C) - 1); memo1.Lines.Add('最大位置 弛度 dm= ' + floatTostr(dm)); x := m + C * arcsinh(h / S); memo1.Lines.Add('斜弛度位置 x=' + floatTostr(x)); d := x / S * h + C * (cosh(m / C) - cosh(arcsinh(h / S))); memo1.Lines.Add('斜弛度 d=' + floatTostr(d)); L := C * (sinh(m / C) + sinh((S - m) / C)); memo1.Lines.Add('線実長 L=' + floatTostr(L)); // グラフスケール計算 if h < 0 then begin lmin := h - d; lmax := 0; end else begin lmin := -d; lmax := h; end; bmin := 0; bmax := S; // グラフ縦横スケール設定 if bmax > lmax - lmin then begin mg := (bmax - (lmax - lmin)) / 2; lmax := lmax + mg; lmin := lmin - mg; end else begin mg := ((lmax - lmin) - bmax) / 2; bmin := bmin - mg; bmax := bmax + mg; end; Series1.Clear; Series2.Clear; Series3.Clear; Series4.Clear; Series5.Clear; application.ProcessMessages; if checkbox1.Checked then begin Series2.AddXY(bmin, lmax); Series2.AddXY(bmin, lmin); Series2.AddXY(bmax, lmin); end; application.ProcessMessages; Drawing; parabole_calc; // パラボラ式計算 end; end.