はじめに
Step1
断面の決定
最初に、断面の決定をしたいと思います。
また、決定した断面の値からフォーム上に重力式擁壁の模式図を描画したいと思います。
そこで、フォーム上に「PictureBox」と「Button」を配置します。
これを使用し、まず線が描けるかやってみたいと思います。
「PictureBox」は画像を表示させるためのツールになります。なので、通常、プロパティの「Image」に表示させたい画像を
指定するのですが、今回はそうはいきません。
そこで、プログラムで画像を作成し、それを「PictureBox」に表示させたいと思います。
画像を表示する「PictureBox」の背景色を黒にしたいので、フォームをダブルクリックしそこに 「PictureBox」のBackColorを黒にするコードを入力します。
試し書きをします。
最初に、ビットマップ画像を作成します。作成するコードは、「 Bitmap _bitmap = new Bitmap(400, 400);」
になります。ここで_bitmapは変数になり、その変数に400pxサイズの画像を格納しています。(インスタンスというやつです。)
次に、このビットマップに描画ができるコードを書きます。(画像参照)
描画できる準備ができたので一旦画像を黒で塗りつぶします。これは、ボタンが押される都度、白紙の状態にしたいためです。
今回は、とりあえず線を描いてみます。コードは、「g.DrawLine(Pens.White, 10, 10, 100, 200);」になります。内容としては
白色で、始点座標(x1,y1)、この場合(10,10)から終点座標(x2,y2)、この場合(100,200)まで線を描くコードになります。
最後に、このビットマップを「PictureBox」の「Image」プロパティに転送します。
とりあえずこれで実行してみます。
無事白い線が描けています。
この画像からわかるとおり、原点は左上になり、右方向がx、下方向がyになることがわかると思います。
描画の練習が終わりましたので、実際に断面決定の内容に入りたいと思います。
まず、フォーム画面のレイアイウトです。
テキストボックスを4つ用意し、各断面寸法を入力できるようにします。
また、各断面の寸法定義のため、マンガ絵を用意しました。
ボタン名もここで「入力完了」に変更しています。
恒例の、文字が入力できないように入力制限を行います。
お馴染みのコードになります。
全角を半角に変換できる命令文が書けるようにその準備をします。
ソリューションエクスプローラーの「参照」を右クリックします。
そうするとメニューが表示されるので「参照の追加」をクリックします。
「参照マネージャー」ダイアログが表示されますので、「アセンブリ」を選択し、 表示されるアセンブリの一覧から 「Microsoft.VisualBasic」を選択し「OK」ボタンをクリックします。
コードを書く画面に移動し一番上の方に「using Microsoft.VisualBasic;」を追加します。
最近わかったのですが、ここに「using」で書いておくと、それ以降「using」以降の文字を省略できるようです。
なので、ここで指定をしていなければ、毎回関連するコードを書く場合、「Microsoft.VisualBasic.・・・・・」といった
ように書かなければならないようです。たぶん・・・
それでは「button1_Click」イベント内のコードに戻ります。
まずは、4つのテキストボックスに入力漏れがあった場合の処理をします。
続いて4つのテキストボックスの入力データを取得します。
全角から半角に変換するため、ここでは文字列として取得します。
そして、全角文字がある場合、半角文字に変換します。
コードは画像のとおりです。
その文字列を数字に変換します。
コードは画像のとおりです。
それでは「PictureBox」に入力された値で模式図を表示したいと思います。
まずは、画像のとおり①~④までの座標を決めます。
底盤の左側を①とし、その座標を(0,0)とすると残りの箇所の座標は画像のとおりとなります。
これをコード入力していきます。
それでは、「button1_Click」イベントのコードに戻ります。
それぞれの座標を変数「coordinateX」もしくは「coordinateY」として、値を格納します。
コードは画像のとおりです。
座標が決まりましたので、次は表示倍率を決めたいと思います。
現在設定しているビットマップ画像サイズは400px✕400pxです。ですのでこのサイズにほどよく表示できるようにしたいと思います。
まず、座標の中の数値で最大値を知る必要があります。最大値になれる座標の候補はx方向だとx4であり、y方向ではy2もしくはy3になります。
そこで、x4とy2(y3)の値の大きな方が最大値になります。一方、画像は余白として50pxを確保したいので300px✕300pxの範囲に模式図を表示
することにします。
ですので、コードとしては300pxを座標の最大値で除した値を表示倍率とします。
実際のコードは画像のとおりです。
この中で、表示用の座標計算をしていますが、格納する変数をfloat型という
ものにしています。
これは、このあと使用するGraphicsオブジェクトのDrawLine関数に入れる値(引数)の型が
float型でないといけない条件になっているためです。
ただし、座標の型はdouble型なので型変換をする必要があります。そこで便利なのがキャスト
とよばれる方法です。単純に変換したい型名を( )で囲んでそれを変更したい変数の前に付け加えるだけで
型変換可能になるようです。
先程書いた描画コードを改造します。
改造したコードは画像のとおりとなります。
本当は、もう少しこだわって中央表示するようにすれば良いのでしょうが
おいさんは根性がないのでしません。
ここで、実行してみます。
無事、模式図が表示されました(感動)。奇跡的にもここまでで大きなエラーも無く辿り着きました。
ここまではもっているようです。このまま続きますように。
最後に訂正をさせてください。
今回の座標(躯体)は、他の箇所でも使用する必要があります。
なので「button_Click1」イベントの1階層上で変数を宣言する必要がありました。
よって、コードを画像のとおり追加と修正をします。
Step2
擁壁背面形状の決定
安定計算の条件として、擁壁の背面形状を決定する必要があります。
背面形状も画像に示すような座標で決定したいと思います。
また、併せて上載荷重も入力できるようにします。
背面形状を入力するフォーム画面です。
背面形状は4つまで入力できるようにしました。
画像のt5~t16のt表記はtextBoxの略です。
それではコードを入力していきます。
最初は、得意の追加したテキストボックスに文字が入力できなよう入力制限をします。
ただ、今回、テキストボックスが多いので大変です。
次に、フォーム画面の背面形状決定の「入力完了」ボタンをダブルクリックします。
コードが書ける画面(button2.Click)に移動しますので、まず、テキストボックスに何も入力されていない
場合の処理を書きます。
今回の場合、最低限「tetxBox5」と「textBox6」が入力されていれば良いので、その場合の処理にしています。
次の処理に行く前に、「button_Click2」イベント以外でも取得した値が使用できるように
変数を宣言します。
宣言場所は、躯体座標の変数宣言の下にしています。
変数を宣言しましたので、入力値を取得したいところですが、もう一つやることがあります。
背面形状の値は、条件次第ではすべてのテキストボックスに入力することがありません。
そこで、どこまで入力されているか把握する必要があります。(把握パターンを格納するため先程変数「inDatanum」を宣言しました)
おいさんは、あまり知恵がないので、「button_Click2」イベントに戻りif文で場合分けをしました。
Y座標の入力の可否によって入力パターンを4つに分けてみました。ここで「!=」とありますが、
これは「イコールではない」という意味になります。
switch文を用いて、場合分けし入力データを取得します。また、同時に全角→半角変換と文字→数値変換もしています。
画像は、すべての値が入力されている場合のコードになります。
switch文の続きです。
画像は、3点までの値が入力されている場合のコードになります。
switch文の続きです。
画像は、2点までの値が入力されている場合のコードになります。
switch文の続きです。
画像は、いずれのケースにも該当しない、つまり1点のみの値が入力されている場合のコードになります。
背面形状の座標が固まりましたので、「PictureBox」に描画をします。
まずは、最大値より表示倍率を決定する必要がありますが、前提条件として躯体断面が決定している必要があります。
もし、断面決定せずに背面形状の決定の「入力完了」ボタンを押してしまうと、エラーになってしまう恐れがあります。
なので、まずは、躯体断面が決定しているかのフラグをたてます。
フラグ用の変数は、コードの上位の層にしたいので、「背面形状関係の変数宣言」の下に宣言します。
また、変数の型は「bool」型にします。(trueもしくはfalseの2択しか必要しないため)
「button_Click1」イベントの最後に「btn1.end」フラグを「true」にするコードを追加します。
これにより、躯体断面の決定は完了していることになります。
「button_Click2」イベントのコードに戻ります。
「btn1.end」フラグの設定ができたので、if文で「true」の場合のみその後の処理を行うようにします。
ここでは、描画倍率を決定します。倍率を決定するには、座標の最大値を知る必要がありますが、背面形状の末端を最大値とし
て、その値で画像サイズ(350px)を割ることにしました。
また、形状によって条件が異なるので、やはり「switch文」を用いて場合分けし、最大値を求めることにしました。
なんだか、ダラダラとしたコードになってきましたが、素人のおいさんなのでご了承ください。
続いて表示用の座標計算をしています。
背面形状の座標は擁壁③を始点にしていたので、擁壁③の座標を足しています。
また、背面形状の座標計算においては、またまた形状によって条件が異なるため、場合分けをする必要があります。
これまで、switch文を使用してきましたが、気分を変えてif文にしてみました。
描画コードになります。
ここでも、形状によって条件が異なるため、場合分けをしながら描画することにしました。
最後に背面形状が決定したので、「btn2end」フラグを「true」にしてます。
訂正です。(何回もすみません)
「button_Click2」イベントのコードを少し戻り、入力データの読み込みコードを画像のとおり変更しました。
理由としては、上載荷重のテキストボックスに何も入力されていない場合エラーになるためです。
なので、その対応としてif文を使用し未入力箇所は0を入れ込むコードにしました。(他の「case」も同様に変更しています。)
ここで、実行してみます。
かなり長いコードを書いた割には、ただ描画するだけの機能のみです。
とにもかくにも、背面形状の決定はこれで完了になります。
Step3
土質諸元の決定
土質諸元の入力を行えるようにします。
といっても、一番最初に入力するのはコンクリートの単位重量といういきなり違う内容です。修正するのが面倒なのでご容赦を。
フォーム画面のレイアウトは画像のとおりにしました。
実際の入力は、「textBox22」までで、以降は内部摩擦角で決まる値なのでバックカラーの色を変えています。
恒例の入力制限をします。
「textBox22」まで行うようにしました。
壁面摩擦角は背面土の内部摩擦角より決まる角度になります。そこで、このテキストボックス(textBox19)に入力された
時点で、壁面摩擦角を決定するようにします。
内部摩擦角と壁面摩擦角との関係は画像のとおりとします。
テキストボックスのイベントに「TextChange」がありましたので、これを使います。
「textBox19」を選択し、イベント(カミナリマーク)から、「TextChange」をダブルクリックします。
先程の壁面摩擦角の計算式をコードにしました。
一応、空白入力のときは、何もしないことにしました。
実行してみます。
内部摩擦角を入力したら、無事、壁面摩擦角が表示されました。
次に、土質諸元の入力値を格納する変数を宣言します。
この変数も、各所で使用したいので、上層で宣言するようにします。
ついでにその下の入力完了フラグも追加します。
追加するフラグは、土質諸元の「入力完了」ボタン「button3」になります。
フォーム上の「button3」をダブルクリックしコード入力画面を開きます。
まず、テキストボックスの入力値を取得します。
これまでどおり、未入力の処理から、入力データの取得、全角→半角変換および文字→数字変換を行います。
Step4
許容応力度の決定
まず、フォームのデザインです。今回は、コンボボックスも使用しています。
テキストボックスは5つ用意しています。このテキストボックスは直接入力せず、コンボボックスの選択により
自動で表示するように使います。なので、バックカラーを変更しています。
許容応力度については画像のとおりとします。
許容応力度の入力値を格納する変数を宣言します。
この変数も、各所で使用したいので、上層で宣言するようにします。
また、その下の入力完了フラグも追加します。
追加するフラグは、許容応力度の決定の「入力完了」ボタン「button4」になります。
テキストボックスに直接入力されてもいいように恒例の入力制限をします。
次はコンボボックスの初期設定をします。
comboBox1を選択し、そのプロパティから「Items」を選択します。
画像に示す画面が表示されます。
そこに、コンクリート設計基準強度「18~24」まで入力し、OKボタンを押します。
コンボボックスにキー入力ができないようにします。(選択のみ可能)
コンボボックスの「DropDownStyle」プロパティを「ComboBoxStyle.DropDownList」にします。
コンボボックスのイベントに「TextChange」がありましたので、これを使います。
「comboBox1」を選択し、イベント(カミナリマーク)から、「TextChange」をダブルクリックします。
コードが書ける画面になったら、まず、コンボボックスが未選択もしくは空白の場合、
メッセージをだし、処理を終えるようにします。
上記の条件をクリアした場合は、switch文で場合分けし、各変数に格納することにしました。
決定した許容応力度をフォーム画面に表示します。
「comboBox1」は選択で表示されているので、テキストボックスのみ表示するコードを書きます。
最後に入力完了の「button4」をダブルクリックしコードを書ける画面へと移ります。
変数はすでに格納済みなので、ここではフラッグを「true」にするだけの処理になります。
ただし、フラッグ変更前に、すべての項目が入力されているか確認するようにします。
Step5
いよいよ計算(躯体自重と重心の算定)
座標法について
重力式擁壁の躯体自重を知るには躯体断面積を求める必要があります。面積を求める式はいろいろありますが、ここでは
座標法により面積を求めることにします。
まず、座標法を理解するために画像の図形を例に面積を算出してみます。
例の図形は単純な10✕7の長方形になります。
これを座標法により表に表すと画像のとおりとなります。
左の2列は長方形4点の座標XとYになります。
左から3列目は1つ前のX座標になります。つまり、①の1つ前は④になりますので、そのX座標になります。
左から4列目は反対に1つ先のX座標になります。その他の列は表示のとおりです。
最終的に、答えは70となりしっかり面積が算出できています。
座標法の計算をメインコードに書くとさらにごちゃごちゃするので、別クラスを用意してそこで計算するようにします。
それでは、新しいクラスを追加したいと思います。
ソリューションエクスプローラーの「重力式擁壁」のところで右クリックします。
すると、画像のとおり、選択できる画面が出てきますので、「追加」→「新しい項目」を選択します。
「クラス」を選択し、名前を入力します。
名前の先頭文字は大文字にする必要があるようです。今回は「CoordinateMethod.cs」としました。
名前を入力したら「追加」ボタンを押します。
コードが書ける画面が現れます。
ここに、座標法で面積を計算するコードを入力していきます。
最初にメンバー変数、メンバー関数を定義します。
今回、メンバー変数は面積を格納する1つだけになります。頭に「private」を付けているので、クラス内でしか通用しない変数になります。
メンバー関数は「SetValue」という関数名にしてます。この関数に渡す値は、躯体断面の座標数とその座標にしています。
重力式擁壁の座標数は4つですが、応用できるように10座標まで渡すことができるようにしました。
また、受け取った値を変数に格納しますが、座標の方は配列宣言により変数を10個作成し、それに格納することにしています。これにより、
今後のコードが楽になると思います。配列の変数は
メンバー関数コードのつづきです。
表で示した座標法をコードで現わしたら、多分画像のとおりになるのでは無いかと思います。
かなり不安です。
最後に、計算された面積を他のクラスに届けるための関数を作成します。
この中身は、単純で「return」文で計算結果を届けます。以上で座標計算用のクラスは完了です。
躯体自重の算定
まず、フォーム画面のレイアウトを決めます。
ツールの「menuStrip」を画面に配置し、そこに「ファイル」、「計算」および「参考値」を入力します。
さらに、「計算」の下に「計算実行」を追加し、このボタン?が押された時に処理を開始することにします。
「計算実行」に自動的に付与される名前は長くて面倒なので、名前を変更します。
「計算実行」を選択して、そのプロパティの「(Name)」を「calcRun」にします。
「計算実行」をダブルクリックして、コードを書く画面にします。
まずは、各入力完了フラグがすべて「true」であるか確認する処理を書きます。
一つでも「true」でなければ処理を中止するようにします。
突然ですがここで修正をします。
「button_Click3」イベントの最後に「btn3end」を「true」にするコートを追加します。
すみません。忘れていました。
あっちこっち移動して大変申し訳ないですが、変数宣言をしてなかったので、この段階でします。
いつもの、メインクラスの上の箇所(上層)で変数宣言をします。
宣言する変数は、躯体断面積、躯体重量およびX方向の躯体重心位置の3つにします。
やっと、「計算実行」クリックイベントのコードに戻ります。
別に作成した座標法のクラスを使用するためのコードを書きます。
インスタンスまで終われば、このクラスを使用できるので、求めたい擁壁断面の座標数(四角なので4)と各座標値を送り面積を計算します。
面積が求まりましたので、いよいよ擁壁重量の計算です。
とはいっても、奥行きは1mとして今後計算していきますので、求めた面積に比重を掛けるだけです。
躯体重心の算定
次に擁壁断面のX軸方向での重心位置を求める必要があります。
これもまた計算方法の理屈はわかりませんが、以前、例で示した10✕7の四角形で現すと画像の計算をする必要があります。
画像の例は、当然X方向の重心は5という答えはわかると思いますので、この計算方法が合っていることが確認できると思います。
重心の計算もメインコードに書くとさらにごちゃごちゃになるので、別クラスを用意してそこで計算するようにします。
それでは、新しいクラスを追加したいと思います。
ソリューションエクスプローラーの「重力式擁壁」のところで右クリックします。
そして、「追加」→「新しい項目」を選択します。
「クラス」を選択し、名前を入力します。
名前の先頭文字は大文字にする必要があります。今回は「CenterCalc.cs」としました。
名前を入力したら「追加」ボタンを押します。
最初にメンバー変数、メンバー関数を定義します。
今回も、メンバー変数は重心を格納する1つだけになります。
メンバー関数は「InValue」という関数名にしてます。この関数に渡す値も、躯体断面の座標数とその座標にします。
重力式擁壁の座標数は4つですが、応用できるように8座標まで渡すことができるようにしました。
メンバー関数コードのつづきです。
表で示した計算をしています。かなり複雑になってしまいました。
最後に、計算された重心を他のクラスに届けるための関数を作成します。
「計算実行」クリックイベントのコードに戻ります。
先程作成した重心計算のクラスを使用するためのコードを書きます。
インスタンスまで終われば、このクラスを使用できるので、求めたい擁壁断面の座標数(四角なので4)と各座標値を送り重心を計算します。
Step6
いよいよ計算(擁壁にかかる土圧の算定)
試行くさび法について
擁壁にかかる土圧を求める方法として、試行くさび法というものがあります。
擁壁にかかる土圧を「主働土圧合力」というそうですが、これは画像に示す式で計算できます。
ただ、式中のωがやっかいで、ωは「仮定したすべり面と水平面のなす角度」になります。
つまり、角度ωを任意に変化させてPを計算する(Pの最大値を求める)必要があります。このように試行錯誤的に計算するので「試行くさび法」と
呼ぶみたいです。
計算の全体的な流れ
今回の計算では背面形状を最大で4点入力できるようにしています。
そのため、角度ωを任意に変化させてPを計算する場合、その背面形状の変化に合わせて計算する必要があります。
よって、まず背面形状の各変化点(画像ではA)での角度(ω)を知る必要があります。
計算方法としては、画像に示すとおり、tanの逆三角関数で求めます。
変化点での角度(ω)の計算をするため「計算実行」クリックイベントのコードに戻ります。
まず、今後のコードを楽に書くために配列を宣言して、擁壁と背面の座標値を格納します。
最初から配列を使用しておけばこのような手間が無くなっていたのですが、今更、前に戻って書き換えるのも大変なのでこのまま進めます・・・すみません。
これも最初からしておけば良かったのですが、背面形状の変化点数を取得します。
すでに「inDatanum」という変数に文字として変化点数の内容を格納していますが、文字だと今後面倒なので数字の変数を用意します。
今回は、「switch」文で場合分けし変化点数を変数に格納しました。
画像は背面変化点での崩壊角(ω)の計算をするコードです。
まず、配列を宣言してから、それに求めた崩壊角を格納します。
また、今後、崩壊角を90°からスタートし、1°づつ減らしてPの最大値を求めますので、最高でも崩壊角は90°までとします。
そのため、配列の0番目は90°用に使用します。その際、C#ではラジアン計算になるのでラジアン変換をしています。
次の崩壊角は1番目からの格納になりますので、新たに変数を設けています。
主働土圧合力Pを求める上で、あと未知数なのは背面土重量Wだけになります。
背面土重量は、奥行き1mで設定しているので、面積が求まれば決まります。
上記のとおり、背面土の変化点で計算方法が変わるので、画像に示すとおり、変化点ごとの範囲内でそれぞれ面積計算
を行うようにしていきます。
上の内容をコードで書くと画像のとおりになると思います。
「radOmegaW」変数は、角度をラジアン変換した値を格納します。ただ、書く場所を間違えています。正解はfor文の下になります。
先程は、画像の図はA点~E点で表記していましたが、コードの説明では1点目~4点目と表記しています。
整合性が無く誠に、申し訳ありません。
A点~B点までの範囲の場合
崩壊線がA点からB点までは、画像に示すとおり、3点(緑丸)の座標がわかれば座標法により面積計算できます。
ただし、躯体の2点は既知ですが、背面形状ラインと崩壊線との交点は計算する必要があります。
4点の座標から交点を求める計算式は画像のとおりになるようです。
なぜ、こうなるかわかりませんが、この式を使用します。
交点を求めるため4点の座標を整理します。
崩壊線の座標は、コードのとおり、擁壁右下の端部から角度ωで延びる線になりますので、座標は自ずと決まります。
また、確実に背面ラインと交差するようX座標をプラス100mという設定にしています。
もう一つの線は、擁壁右上から背面変化点の一つ目になるので、既知の座標が使えます。
交点の計算は、別クラスで行うこととします。
クラス名を「IntersectionCalc」として、新しいクラスを用意します。
最初にメンバー変数、メンバー関数を定義します。
今回のメンバー変数は交点のX、Y座標をを格納する2つの変数を用意します。
メンバー関数は「SetValue」という関数名にしてます。この関数に渡す値はメインクラスで先程整理した座標値になります。
交点の計算です。
式が長いだけで特に言うことはありません。
最後に、計算された交点を他のクラスに届けるための関数を作成します。
今回は、座標X、Yを返したいので、関数を2つ定義しています。
早速、交点の計算クラスを使用します。
メインクラスの「計算実行」イベントコードの続きです。
コードは画像のとおりです。
特にこれまでと変わりありません。
交点の座標が求まりましたので面積の計算をします。
面積の計算は、コードを省略できるので以前使用した座標法クラスを使用します。
今回は、擁壁の2点と交点の3つの値を送り、その計算結果を返してもらいます。
最後にその面積に単位体積重量を掛けて背面土の重量が求まります。
上載荷重の合計を計算をします。
上載荷重があれば、その値にX方向の長さを掛けるだけになります。
主働土圧合力計算用の変数を宣言していませんでした。
いつもどおり、上層に宣言します。
主働土圧合力の計算をします。
計算コードは画像のとおりです。
次に最大値の記録を行います。
ただ、その前に、最大値を格納する変数(宣言済み)の初期設定をしていませんでした。
「計算実行」イベントの最初に各変数の初期値を0にするコードを追加します。
これで、「計算実行」ボタンを押すたびに初期化が実施されます。
あちこち跳んで申し訳ありませんが、主働土圧合力の計算コードの下に戻ります。
ここで、最大値の記録を行います。
計算された主働土圧合力が前回の値より大きければ値を入れ替えるという単純なコードになります。
B点~C点までの範囲の場合
崩壊線がB点からC点までは、画像に示すとおり、4点(緑丸)の座標がわかれば座標法により面積計算できます。
その他は、A点~B点の計算と同様の考え方になります。
計算過程はA点~B点の計算と同じなので、A点~B点の計算コードをコピペして、画像の赤丸の箇所だけ変更しています。
コードが長いので、画像は、前半部分になります。
後半部分です。
こちらも、変更部分は赤丸の箇所になります。
C点~D点までの範囲の場合
崩壊線がC点からD点までは、画像に示すとおり、5点(緑丸)の座標になります。
これも同様に計算を行います。
画像の赤丸の箇所だけ変更しています。
D点~E点までの範囲の場合
崩壊線がD点からE点までは、画像に示すとおり、6点(緑丸)の座標になります。
これも同様に計算を行います。
画像の赤丸の箇所だけ変更しています。
これで、やっと主働土圧合力の計算が完了です。
主働土圧合力の作用位置の計算
主働土圧合力自体は求められましたが、まだ、それが作用する位置(画像の緑表示のX、Y)は計算できていません。
計算方法は、Y方向を先に求め。X方向はYから三角関数で求めることができます。
X方向の位置は、擁壁左下の角が基点になります。
作用位置X、Yの計算式は画像のとおりになるようです。
詳しい内容はわかりませんが、理解せずに使います。
作用位置の計算コードになります。
入力場所は、最後に計算することにしたいので「計算実行」イベントの一番下になります。
Step7
いよいよ計算(擁壁に作用する荷重)
これまで擁壁に作用する荷重を計算してきました。
求めた荷重は、画像のとおり土圧と自重です。
ここまでくるのにかなりのコードを書いてきましたが、この2つの荷重しか求められていないのです。(涙)
それはさておき、今度は、この求めた荷重を次の計算が行えるようにX方向とY方向とモーメントに分解・整理する必要があります。
まずは、X方向の水平力とY方向の鉛直力を求めます。
擁壁の自重は、すでに鉛直方向なのでO.Kです。後は、主働土圧合力をそれぞれの方向に分解します。
ただ、分解方法が単純ではなくまず「主動土圧係数」なるものを求めて、それをX方向とY方向に三角関数で分解します。
次に、モーメントを求めます。
なぜ、モーメントを求めるかというと、擁壁の転倒に係る力を知る必要があるからのようです。
モーメントは、擁壁左下端を基点として求めるようです。
最初に計算結果を格納する変数を宣言します。
宣言場所は、上層で行うようにしました。
実際の計算コードになります。
これで、作用する荷重の整理ができました。
Step8
いよいよ計算(転倒に対する検討)
擁壁の転倒に対する検討は、モーメントの作用位置がどこに位置するかで判断するようです。
画像でいうと中心線からの離れeになります。
このeが底盤幅Bの1/6以内(常時)に無ければならないようです。
eの計算式は画像に示しているとおりです。
いつもどおり、安定計算結果を格納する変数を宣言します。
本当は、合力の作用位置eだけで良いのですが、後々面倒なので、そのほかの安定計算用の変数も一緒に宣言しておきます。
合力の作用位置eの計算になります。
後は、判定をするのですが、判定表示をするフォームを別に作ろうと思うので、ここでは行わないことにしました。なので、転倒に関する計算は完了です。
Step9
いよいよ計算(滑動に対する検討)
擁壁の滑動に対する検討は、安全率Fsを求め、その値が常時で1.5を下回らないという条件になるようです。
安全率を求める計算式は、画像のとおりになります。
この式の中にCBという変数がありますが、擁壁底面と地盤との間にコンクリートや砕石等がある場合は0つまり考慮
しないことになっているようです。
通常擁壁を施工する場合、均しコンクリートや基礎砕石を施工しますので、今回の計算では考慮しないことにします。
滑動に対する安全率を求めるコードになります。
変数は、すでに宣言しているfSを使用します。
Step10
いよいよ計算(支持に対する安定の照査)
地盤が擁壁を支持できるかの照査は、画像にあるq1もしくはq2の大きな方が、地盤の許容支持力以下であるかの確認になります。
ただし、q1およびq2は条件によって計算式が変わるようですが、転倒に対する安定が確保されていれば、画像の計算式で良いようです。
鉛直地盤反力度の計算になります。
q1及びq2を計算して大きな方を変数quに格納しています。
Step11
いよいよ計算(部材の安全性の照査)
ここでは、擁壁自体が土圧に対して安全であるかの照査を行います。
断面照査をする箇所は擁壁底面(基部)と擁壁の中間部にしています。
また、擁壁に作用する荷重は、画像のとおりで基部における作用荷重は算出済ですが、中間部は計算していないので
画像の式により計算して求めます。
照査内容は、作用するモーメントに対して、コンクリートの引張応力度が許容値内であることと、
作用するせん断力に対して、コンクリートのせん断応力度が許容値内であるかの確認になります。
部材照査用の変数を宣言します。
いつもどおり上層で宣言します。
部材の照査の計算です。
これでやっと、「計算実行」ボタンのコードをすべて書き終えたと思います。
次は、この計算結果の出力と判定を表示するフォームを作りたいと思います。
Step12
計算結果と判定の表示
計算結果と判定の表示用に新しいフォームを追加します。
ソリューションエクスプローラーの下の「重力式擁壁」を右クリックして「追加」を選択し、[新しい項目」を選びます。
その中の「フォーム」を選びます。
名前はデフォルトの「Form2」のままにします。
「Form2」の画面をデザインします。
画面の中のt1、t2・・・は「textBox」のことを指しています。
「Form2」のテキストボックスは、「Form1」から操作できるようにしておきます。
「Form2」の各テキストボックスの「Modifiers」を「Public」にします。
「Form2」の表示を変えるラベルも同様に「Modifiers」を「Public」にします。
「Form1」内のコードに戻ります。
まず、フォーム用の変数を宣言します。変数名は「f2」としました。
次に、フォームのインスタンスです。「Form1_Load」イベント内に書きます。
計算結果と判定を「form2」に表示するべく、「計算実行」イベントにコードを追記します。
続きのコードになります。
まだ、あります。
これで終わりです。
最後に「Form2」を表示する命令文を書いています。
実行してみます。
無事、表示されました。
実行してみて気づきましたが、まだ「閉じる」ボタンのコードを書いていませんでした。
初めて「Form2」にコードを書きます。
「閉じる」ボタンをダブルクリックし、コードが書ける画面を表示させます。
あとは、フォームを閉じる命令文の「this.Close();」と書けば完了です。
やっと、念願の試行くさび法による擁壁計算ができましたが、びっくりするほどここまでに時間がかかりました。
ここで終わりたいとこですが、もう一踏ん張りして、ソフトを仕上げていこうと思います。
Step13
崩壊線の表示
まずは、変数を宣言します。
段取りが悪いので、事前にしておけば良かったのですが、描画用の表示倍率と崩壊線と背面形状との交点は
各イベントで算出しているにもかかわらず、上層で変数宣言していないため、「計算実行」イベント内では
使用できない状況です。
なので、改めて、変数宣言し値を取得することにします。
変数は画像に示すとおり3つになります。
画面は、Form1画面の「背面形状の決定」の「入力完了」ボタンのクリックイベントコードの最後になります。
ここで、描画用の表示倍率を取得します。
「計算実行」ボタンイベントに戻ります。
最大値の計算の箇所に、「dispIX = istXc;」と「 dispIY = istYc;」を追加します。これにより、主働土圧合力の最大値の
時が崩壊線と背面形状の交点が取得できます。
交点が取得できれば、後は描画するだけになります。コードは画像のとおりになります。
画像は実行画面です。
簡素ですが、崩壊線が表示できています。
Step14
参考値の表示
上載荷重
フォーム画面のメニューバーの「参考値」に「上載荷重」を追加します。
相変わらず自動に付与される名前は長いので、名前(Name)を変更します。
名前は「topLoadM」としました。
「上載荷重」をダブルクリックしてコードが書ける画面を開きます。
クリックイベントになっているので、そこにメッセージボックスで上載荷重の参考値を表示するようにします。
コンクリートの単位体積重量
フォーム画面のメニューバーの「参考値」に「コンクリートの単位体積重量」を追加します。
名前を「coWeightM」に変更します。
「コンクリートの単位体積重量」をダブルクリックしてコードが書ける画面を開きます。
クリックイベントになっているので、そこにメッセージボックスでコンクリートの単位体積重量の参考値を表示するようにします。
土の単位体積重量
フォーム画面のメニューバーの「参考値」に「背面土の単位体積重量」を追加します。
名前を「soilWeightM」に変更します。
今回はメッセージボックスを使わず、フォームで参考値を表示するようにします。
ソリューションエクスプローラー上で右クリックし、追加のフォームを選択します。
フォームを選択状態で、名前を変更します。 名前は「SoilWeight」としました。
画面デザインです。
参考値の表示と「閉じる」ボタンを作成しています。
「閉じる」ボタンが押された場合のコードを追加します。
単純に、このフォームを閉じる内容になっています。 これで、このフォームの作業は終了になります。
メインフォームに戻り、「背面土の単位体積重量」をダブルクリックしてコードが書ける画面を開きます。
クリックイベントになっているので、そこに先程のフォームを表示するようにします。
まず、フォーム用の変数の宣言と同時にインスタンスします。
そして、フォームを表示するコードを追記します。
土の内部摩擦角
フォーム画面のメニューバーの「参考値」に「背面土の内部摩擦角」を追加します。
名前を「SoilAngleM」に変更します。
ここもメッセージボックスを使わず、フォームで参考値を表示するようにします。
ソリューションエクスプローラー上で右クリックし、追加のフォームを選択します。
フォームを選択状態で、名前を変更します。 名前は「SoilAngle」としました。
画面デザインです。
参考値の表示と「閉じる」ボタンを作成しています。
「閉じる」ボタンが押された場合のコードを追加します。
メインフォームに戻り、「背面土の内部摩擦角」をダブルクリックしてコードが書ける画面を開きます。
そして、フォームを表示するコードを追記します。
摩擦係数
フォーム画面のメニューバーの「参考値」に「滑動摩擦係数」を追加します。
名前を「cFrictionM」に変更します。
ここもメッセージボックスを使わず、フォームで参考値を表示するようにします。
ソリューションエクスプローラー上で右クリックし、追加のフォームを選択します。
フォームを選択状態で、名前を変更します。 名前は「CoefficientFriction」としました。
画面デザインです。
参考値の表示と「閉じる」ボタンを作成しています。
「閉じる」ボタンが押された場合のコードを追加します。
メインフォームに戻り、「滑動摩擦係数」をダブルクリックしてコードが書ける画面を開きます。
そして、フォームを表示するコードを追記します。
Step15
その他の表示
地盤の許容支持力と粘着力
フォーム画面のメニューバーの「その他」を追加し、これに「地盤の許容支持力」を追加します。
名前は「soilAFM」としました。
フォーム画面のメニューバーの「その他」に「地盤の粘着力」を追加します。
名前を「soilCM」に変更します。
それぞれメッセージボックスを表示するようにします。
Step16
画面のレイアウトの調整等
ここでは、以下の内容をしました。詳細は割愛します。
・テキストボックスの表示を右寄せ
・フォームの最大化を制限
・ソフト起動時に画面を中央表示
。フォームサイズを固定
。フォームの表示名の変更
「入力完了」ボタンを押したときに、ちゃんと押されたかわかるようにしたいので、押されたらボタンの表示色を変更するようにしたい思います。
各「入力完了」ボタンのコードの最後に「button1.BackColor = Color.Gold;」を追加します。
Step17
入力データの保存と読み込み
せっかくなので、入力したデータの保存や読み込みをできるようにしたいと思います。
まずは、フォームデザインです。
メニューバーの「ファイル」に「新規作成」を追加します。
名前は、「newFileM」にしました。
次に、メニューバーの「ファイル」に「開く」を追加します。
名前は、「fileOpenM」にしました。
続いて、メニューバーの「ファイル」に「上書き保存」を追加します。
名前は、「FileSaveM」にしました。
続いて、メニューバーの「ファイル」に「名前を付けて保存」を追加します。
名前は、「fileNewSaveM」にしました。
最後に、メニューバーの「ファイル」に「終了」を追加します。
名前は、「softEndM」にしました。
次に、メツールボックスから「openFileDialog」と「saveFileDialog」を選択し、フォームにドラックアンドドロップし フォームに貼り付けます。
メインフォームのコードに移り、「using」を追加します。
コードは、「using System.IO;」になります。
これは、ファイルの読み書きをする場合に追加するようです。
メインフォームのコード上部で、まずファイルのパスを格納する変数を宣言します。
変数名は、「fPathdat」にしました。
変数宣言ができたので、最初は「名前を付けて保存」の制御をしたいと思います。
「名前を付けて保存」をダブルクリックして、コードの書ける画面にします。
そこに、画像のとおりのコードを入力します。内容は以下のとおりになります。
・「SaveFileDialog sfd=new SaveFileDialog();」はセーブダイアログをインスタンスし、sfdという変数に格納しています。
・「sfd.Title = "名前を付けてファイルを保存する";」は、ダイアログに表示するタイトル名の設定になります。
・「sfd.Filter = "CSVファイル|*.csv|すべてのファイル|*.*";」は、今回はCSV形式のファイルで保存したいので初期設定にCSVを指定しています。
・「sfd.FileName = "csv_name.csv";」は、とりあえずのファイル名です。
・「var dResult=sfd.ShowDialog();」は、実際にセーブダイアログを表示する命令文になります。また、変数「dResult」に格納しています。
実際に実行してみます。
画像のとおり、見慣れたウィンドウが表示されます。
コードに戻ります。
最初にif文を書いています。
これは、先程のセーブダイアログで「保存」ボタン、コード上では「OK」ボタンが押された場合のみ、以後の内容を実行するとしています
以降の内容は以下のとおりとなります。
・「string fPath=sfd.FileName;」は、セーブダイアログで選択したパスとファイル名を取得します。パスは絶対パスを取得します。
・「StreamWriter sw=new StreamWriter(fPath,false);」は、ファイルに保存する機能をインスタンスしています。ここで、[false」は、
保存方法を「上書き」とする設定ということになります。なので一度閉じて再度書く場合は、「上書き」になります。
・「sw.WriteLine(string.Format("{0},{1},{2},{3}",textBox1.Text,textBox2.Text
,textBox3.Text,textBox4.Text));」は、ファイルに保存したい内容を実際に書く制御文になります。
・「sw.Close();」は、書き終わったら必ず閉じる必要があるようで、その閉じる文になります。
・「this.fPathdat = fPath;」は、「上書き保存」で使えるようにパスとファイル名を保持するようにしています。
保存をしたので、当たり前ですが入力内容は最新の保存内容と一致します。
このことを示すために、「各テキストボックスの内容は最新の状態ですよ」ということをします。
実際のコードは、各テキストボックスのプロパティ「Modified」を「false」にします。
保存されたデータを見てみます。
思ったとおりに保存されていました。
一安心です。
今度は、「上書き保存」のコードを書きます。
まず、上書きするためには、保存先のパスとファイル名が既知である必要があります。
なので、if分で変数「fPathdat」が「null」つまり未指定の場合は、「名前を付けて保存」に移行するようにしています。
パスとファイル名が既知であれば、保存作業をします。
保存するコードは「名前を付けて保存」のコードと同じになります。
保存されたので、最新状態です。
なので、テキストボックスの「Modified」を「false」にします。
次は、「新規作成」のコードを書きます。
この場合は、各テキストボックスの入力データを空白にします。なので、その段階で入力されている値は消去されます。
そのため、まず、メッセージを表示し、入力データの扱いを決めるようにしました。
最初に、各テキストボックスの値に変更があるか知る必要があります。
これは、if文で各テキストボックスのいずれかの「Modified」が「true」かどうか確認します。
「true」であれば、メッセージボックスを表示し、その後の扱いを選択できるようにします。
「キャンセル」の場合は処理を抜けるようにし、「Yes」の場合は、「上書き保存」に移行するようにしています。
上記の処理により、遠慮なく消せる状態になったのでの、各テキストボックスの値を消去します。
また、「入力完了」フラグとそのボタンの色を初期状態に戻します。
最後に、各テキストボックスの「Modified」を「false」にして、さらに、パスとファイル名も未選択にします。
以上で、「新規作成」は完了になります。
最後は「開く」のコードを書きます。
最初のコードは「新規作成」とまったく同じになります。
ここから、かなり苦労しました。
まず、「var oResult=openFileDialog1.ShowDialog();」でオープンダイアログを表示します。
次に、ファイルを選択して、「OK」であれば「string oPath=openFileDialog1.FileName;」で
パスとファイル名を変数「oPath」に格納します。
最後に「StreamReader sr=new StreamReader(oPath);」で読み込み機能をインスタンスします。
ここからは、実際の読み込みです。
「ReadLine()」はデータを1行ずつ読み込む関数になります。
今回は、6行データがあるので、6回「ReadLine()」する必要があります。
次に読み込んだデータを分解します。
分解方法は、「.Split(',')」になります。
1行にあるデータ数はバラバラなので、配列の変数を利用してそこに格納します。
配列の変数に格納したら、その値をそれぞれのテキストボックスに格納します。
最後に、テキストボックスの「Modified」を「false」にします。
また、ボタンの設定を元に戻します。
Step18
最後まで悩んだExcel出力
これをやると、あまりにも膨大なコードを書かないといけないので、最後まで悩みましたが、ここまで
頑張ってきたので、最後の締めと思い、決心しました。
まずは、フォームデザインです。
画像のとおりメニューバーに追加することにし、名前を「eOutput」に変更しました。
次にエクセルの機能を使えるようにします。
ソリューションエクスプローラーの参照上で右クリックし「参照の追加」を選択します。
「COM」を選択し、「Micorosoft Excel --- Object Library」を選択し「OK」ボタンを押します。
設定の追加が完了したら、Form1のコードの初めに下記内容を追加します。
「using Excel = Microsoft.Office.Interop.Excel;」
これで、エクセルの操作が可能になります。
フォームのメニューバーのファイル・エクセル出力をダブルクリックします。
そうすると、コードが書ける画面になりますので、画像のとおりエクセルに出力するコードを入力します。
コードは、
Excel.Application excelApp = new Excel.Application();
Excel.Workbooks excelBooks = excelApp.Workbooks;
Excel.Workbook excelBook = excelBooks.Add();
Excel.Worksheet sheet = excelBook.Worksheets["sheet1"];
excelApp.Visible = true;
になります。おまじないみたいなものです。
予期せぬエラーが発生してもソフトが強制終了しないように処理します。
「try~catch」文をあらかじめ書いておきます。
ここからは、エクセル出力のコードを記載します。
地獄のロードの始まりです。
まだ、元気に入力中です。
まだまだ!!
がんばれ!!
一度休憩をしています。
気合だ!!
気合いだ!気合いだ!!
・・・・
・・・・・・・
今日はここまでします。
さあ、頑張るぞ!
もう、つらい・・・
あ~~~
う~~~
しなければ良かった。
もう少し・・・
あとちょっと
完了!!!!!!!!!!!!!!
いくら暇でもかなりしんどい。終わって良かった。(涙)
Step19
実際に計算してみる
ついに完成したので、実際に使ってみたいと思います。
まずは、入力データを入れていきます。
そして、「計算実行」ボタンを押してみます。
NGの部分がありますが、しっかり計算できています。合っているかわかりませんが・・・
ここで、許容支持力を100kN/m2にしていますが、この確認を以前作成したソフトで計算します。
また、今回は、常時のみの計算しか作成していません。理由は、あまりにもしんどいことと、
擁壁の場合、8m以下で、常時の計算がしっかりできていれば地震時の計算を省略できるみたいなのでしませんでした。(完全ないいわけです)
擁壁計算で求めた結果を「地盤の許容支持力計算」に入力し、支持地盤の確認をしてみます。
ここで、擁壁計算で使用する値は、「V」と「H」と「eB」と「q」と「B」になります。
また、奥行きは必ず1mにします。(擁壁計算では奥行きを1mとして計算しているため)
結果は、画像のとおりです。擁壁の場合、常時で安全率は3になるようで、この場合だと、鉛直荷重16.06kNに
対して支持力は2.36kNしかなく、NGになります。すなわち地盤改良等が必要になります。
おいさんが学生時代からどうしてもしたかった重力式擁壁の安定計算を今回は挑戦しようと思います。
「なぜ、今更この計算をするの?」や「あたためすぎでしょ」といったご意見もあると思いますが、 実際には計算方法がぼんやりわかってもできませんでした。
なぜかというと、重力式擁壁の計算は、「試行くさび法」という繰り返し計算を必要とし、プログラムのスキルと ある程度の数学の知識がないと実現不可能な内容だったからです。
ただ、現在おいさんの趣味はこれしかないので、時間をかけてじっくりやっていこうと思い今回挑戦することにしました。