Day11

骨組解析(後編)

Topへ

Day10へ

Day12へ

はじめに

「骨組解析」の続きです。
想像以上に困難な道で泣きが入っています。
チャレンジしなきゃ良かったと後悔していますが、ここまできたらがんばるしかないと、己を奮い立たせています。
しかし取り組み初めて早3ヶ月いつになったら終わるのだろうか。
出口の見えない迷宮にいるような心境です。

Step1

分布荷重

image

現機能では、集中荷重が部材に作用した場合の構造計算機能しかありませんでした。
しかし、実際には分布荷重も作用する場合があるため、その機能を追加する必要があります。
まずは、機能実装するための考え方なのですが、これも良くわからないながら記載しようと思います。
今回は、画像に示す分布荷重が働く場合で、赤丸で囲まれた部材(要素)について書いていきます。
この場合、部材全体にy方向の分布荷重wyが作用しており、両端にx方向の荷重wxが作用していることにしています。

image

以前説明したフックの法則を行列式で表した式を画像に表示にしています。
この中で、行列式の赤で囲んだ部分(荷重部分)に分布荷重を追加する必要がります。

image

分布荷重の追加方法は画像に示す式になるようです。
内容は全くわかりません。分布荷重を追加する場合はこのような式になるようです。
一つ注意なのは、この式は要素座標系での式ということです。なので、コードを書く際はそこに注意する必要があるようです。

image

まず、上記の式を計算結果を格納する変数(要素座標系用)を宣言します。
宣言する場所は、いつものとおり「Form1」のコード上部になります。
後で、別クラスでも使用するので「public」にしておきます。

image

さらに、別の場所で分布荷重計算用の変数を宣言します。
宣言する場所は、荷重マトリクス「fg」のコードの下になります。
宣言する変数は、座標変換マトリクス「tdl」と分布荷重の計算結果を格納する変数「fgt」(全体座標系用)になります。
ただし、今回、座標変換マトリクスはモーメントがないので画像の赤の部分の2✕2の行列部分のみになります。

image

分布荷重の計算も各部材(要素)ごとに計算していきます。なので、部材数分繰り返しをする中に各部材の荷重を計算するコードを書いていきます。
ここでも、for文で要素数分繰り返しを行うことにしています。今後は、その中にコードを追記していく形になります。
まず、画像のとおり座標変換マトリクスの計算をしています。

image

データグリッドビューから分布荷重の値を読み込みます。
読み込み方法はこれまでと同様です。

image

ここでは、まず、読み込んだ集中荷重を計算できるようにするため、要素座標系に変換しています。
次に、上述の式により分布荷重を計算しています。
計算が完了したら、また、全体座標系に戻しています。

image

最後に計算された分布荷重の行列を集中荷重で求めた「fg」行列に追加します。
これで、後の処理は同じになりますので、「Form1」の処理は完了になります。

image

「StressCalc.cs」に移動します。
なぜかわからないのですが、応力の計算結果から分布荷重分を控除する必要があるようです。
こうしないと正しい値にならないみたいです。
以上で、分布荷重のすべての処理が終了になります。

Step2

反力の計算

image

反力の計算については、「Day10」の行列式の例で説明します。
求めたい反力は、画像の例で説明すると、赤書の外力部分になります。
なので、単純に全体剛性マトリクス(tk)と変位(dg)の行列式を解けば良いだけのことになります。
ただし、現時点の全体剛性マトリクスは青い範囲の状態になっているため再計算する必要があります。
さらに、分布荷重の処理も再度必要になります。
後は、拘束条件から該当する箇所を出力すれば良いことになります。

image

反力のコード入力をしていきます。
入力していく箇所は、「計算実行」イベントの「部材の応力計算クラスの実行」の後になります。
まず、1行目で座標変換マトリクスの変数を宣言しています。(無駄な気がしますが、エラーが怖いのでもう1回作ります。)
次からは、粛々と全体剛性マトリクスの再計算をしていきます。また、要素剛性マトリックスのインスタンスも必要ない気がしますが、 やはりエラーが怖いので再度変数を作って実行しています。(実はここに行き着くまでに多くのエラーに悩まされてきています。かなりの エラー恐怖症になっているため、びびったコードになっています。ご容赦ください。)

image

全体剛性マトリクスの再計算の続きです。
前回作成したコードと同様になります。これで、全体剛性マトリクスの再計算は完了になります。

image

ここでは、全体剛性マトリクス✕変位の行列計算をします。
これにより、すべての荷重が計算されますので、反力も計算されていることになります。
ただし、分布荷重はこの時点で控除していないので、次はその処理をしていきます。

image

求めた荷重から分布荷重の控除をしています。
無駄なコードが多いような気がしますがご勘弁ください。

image

いよいよ反力の出力になりますが、その前に変数を宣言しておきます。
宣言する場所は、いつものとおり「Form1」のコード上部になります。
宣言する変数は、x方向の反力を格納する変数、y方向の反力を格納する変数及びモーメントの反力を格納する変数になります。

image

「計算実行」イベントの反力計算コードの続きに戻ります。
次は、節点ごとに拘束状態の確認をしていきます。
もし、拘束されていれば、その節点での荷重を変数に格納していきます。

image

「Form4」のデザイン画面に移動します。
ツールボックスから「DataGridView」を選択して、ドラックアンドドロップします。

image

列に項目を追加していきます。
項目は、「節点番号、x方向反力、y方向反力、曲げモーメント反力」で、 そのままヘッダーテキストに入力します。 その項目に対する列名を 「reactionNodNum、reactionXd、reactionYd、reactionMd」としました。

image

画面デザインの「DataGridView」に戻って、イベント時の設定をしていきます。
「DataGridView2」のイベントの「EditingControlShowing」をダブルクリックして、コード画面に移動します。

image

ここでは奇数行の背景色を変更します。
コードは「dataGridView3.AlternatingRowsDefaultCellStyle.BackColor = Color.AliceBlue;」にします。

image

「Form4」のロードイベントに移動します。
その中に画面のとおり変数に反力の計算結果が格納されていれば(ゼロより大きければ)その値を表示するコードを追記します。
datagridviewに計算結果を追加する命令文は前回と同様で「dataGridView3.Rows.Add」になります。
また、小数第4位で四捨五入するようにしました。
これで、反力計算関係の作業はすべて完了になります。

Step3

その他の設定

image

ここからは、計算に関係ないその他の設定をしていきます。
まず、データグリッドビューにある程度初期値を自動で表示したいと思います。
まず、「Form1」の上部の変数定期の箇所で、「トラス」か「骨組」かの状態を格納する変数を宣言します。
変数の型はboolとします。

image

次に「Form2」のコードに移動します。
画像の赤線箇所に先程宣言した変数を追記し、「トラス」の場合は「true」で「骨組」の場合は「false」にします。

image

「Form3」のデザイン画面に移動します。
画像のボタンのコードを変更し、「トラス」の場合は、断面2次モーメントを0になるように変更します。
本当は、「Form1]のデータグリッドビューも、「トラス」の場合は回転拘束を1とするコードを 書きたかったのですが、うまくできなかったので諦めました。

image

画像の赤部分、つまり断面2次モーメント部分を変更しています。
単純に「トラス」の場合は、断面2次モーメントを0にするコードになります。

image

次はコードの追加になります。今は「計算実行」ボタンを押すたびに、計算結果が追加されていました。
これでは不格好なので、一度データグリッドビューをクリアにします。
コードは、「Form4」のロードイベント内にしました。

image

ここからは、画面デザインに関する作業になります。
まず、「Form1」からしていきます。
タイトルを「骨組解析」に変更します。「プロパティ」の「Text」で変更します。

image

フォームの最大化を制限します。
フォームのプロパティの「MaximizeBox」を「False」にします。
「Form2」から「Form4」も同様の処理をします。

image

ソフト起動時に画面中央に表示するようにします。
フォームのプロパティの「StartPosition」を「CenterScreen」にします。
「Form2」から「Form4」も同様の処理をします。

image

フォームサイズを固定します。
プロパティの「FormBorderStyle」を「FixedSingle]にします。
「Form2」から「Form4」も同様の処理をします。

image

入力の参考になるように、正負の方向を表示します。
「Form1」のデザイン画面の右側に「pictureBox」を配置し、画像を表示させます。

image

見た目を良くしたいのでデータグリッドビューのヘッダーの色を変更します。
データグリッドビューの「プロパティ」の「ColumnHeadersDefaultCellStyle」をダブルクリックします。

image

CellStyleビルダーが開きますので、その画面の「BackColor」と「ForeColor」を好きな色に変更します。

image

上記で色を変更しましたが、まだ反映されません。
もう一手間必要になります。
「ソリューションエクスプローラー」の「Program.cs」の「Program」をダブルクリックします。

image

その中のコードのうち「Application.EnableVisualStyles();をコメントアウトして無効にします。
これで、やっと色が反映されます。
その他のデータグリッドビューも同様の処理をします。

image

ここからは、計算結果をエクセル等に貼り付けるのを楽にするため、クリップボードに計算結果をコピーできるようにします。
なので、「Form4」のデザイン画面に移動し、ツールボックスから「button」を配置します。

image

「button」は2つ用意し、一つは選択した行のみをコピーするボタン、もう一つはすべての行をコピーするボタンとします。
それぞれのボタンのプロパティの「Text」をその内容に変更します。

image

ボタン1をダブルクリックして、選択した行のみをクリップボードへコピーするコードを書きます。
コードは画像のとおりになります。

image

ボタン2をダブルクリックして、すべての行をクリップボードへコピーするコードを書きます。
コードは画像のとおりになります。

image

同様にデータグリッドビュー2と3についてもボタンを追加して、コード入力します。

image

「Form1」デザイン画面のメニューバーの「参照」に「拘束条件の入力方法」を追加します。
名前を「constraintsM」に変更します。

image

今回はフォームで参照を表示するようにします。
ソリューションエクスプローラー上で右クリックし、追加のフォームを選択します。

image

名前は変えずに「Form5」のまま使用します。

image

画面デザインです。
入力方法の表示と「閉じる」ボタンを作成しています。

image

閉じるボタンのコードを画像のとおりにします。

image

「Form1」に戻り、「拘束条件の入力方法」をダブルクリックしてコードが書ける画面を開きます。
クリックイベントになっているので、そこに先程のフォームを表示するようにします。
まず、フォーム用の変数の宣言と同時にインスタンスします。
そして、フォームを表示するコードを追記します。これで、参照できるようになります。

image

「Form1」デザイン画面のメニューバーの「参照」に「分布荷重の入力方法」を追加します。 名前を「distributionLoadM」に変更します。

image

新しく「Form6」を作成し、画像のとおりデザインします。
後は「拘束条件の入力方法」と同様になります。

image

「Form1」デザイン画面のメニューバーの「ファイル」に「閉じる」を追加します。
名前を「endM」に変更します。

image

閉じるのコードを画像のとおりにします。

Step4

どうする・・・グラフィック

試し書き

image

現段階で、すでに骨組み解析の機能はすべて備わっているのですが、やはりグラフィック機能があれば 見栄えがよく、使用性も向上するのは間違いないところです。
しかしながら、これに脚を踏み入れるとまたゴールがぐっと遠のくのでかなりの迷いが出ています。
ひとまずやれるところまでやってみようと思います。
ということで、骨組の表示をまずチャレンジしていこうと思います。
その前に、一度試し書きをしようと思います。
画像のとおり新規プロジェクトを作成します。(試し書きは直接骨組み解析ソフトには関係ありませんのでご注意ください。)

image

ツールボックスから「PictureBox」を選択し、「Form1」のデザイン画面にドラックアンドドロップし配置します。
配置した「PictureBox」のサイズを500✕500にします。これで、とりあえずツールの配置は完了です。

image

「Form1」デザイン画面をダブルクリックし、「Form1_Load」イベントに移動します。
まず、画像を表示する「PictureBox」の背景色を黒にしたいので、BackColorを黒にするコードを入力します。
続いて、ビットマップ画像を作成します。作成するコードは、「 Bitmap _bitmap = new Bitmap(500, 500);」 にします。

image

作成したビットマップに描画ができるコードを書きます。(画像参照)。
描画できる準備ができたので一旦画像を黒で塗りつぶします。これは、フォームロードするたびに白紙の状態にしたいためです。
あとは、実際に描画していきます。描画は「g.DrawLine()」でできますのでとりあえずラーメン構造を書いてみます。

image

とりあえずこの段階で実行してみます。
これに荷重を表示を追加したいので、このサイズ感でいいような気がします。
なお、原点は左上になります。普通のxy空間と異なりますので注意が必要です。

image

次に拘束条件の表示を使用と思います。ここでは、yのみ拘束されている条件で表示しようと思います。
今回は、関数を自作して使用します。関数名は「Const010」にしました。(ルールとして「Constx拘束y拘束z拘束」にします。)
関数の引数としては、倍率、拘束表示するx座標、拘束表示するy座標にしています。
その引数をもとに、三角部分と下線部分を作成します。三角部分はPoint変数を作成し、「System.Drawing.Drawing2D.GraphicsPath()」 というクラスを使用し、パスで図形を描画できるようにします。そして、「AddPolygon」で多角形を指定し三角形の描画を指定します。
最後に、「DrawPath」関数で実際に描画の実行をします。

image

関数ができたので、実際に使用します。
フォームロードイベントに関数を追記します。表示する箇所は左下端にしました。

image

これで実行してみます。
サイズ感としてはこれくらいでいいような気がします。

image

次は集中荷重表示をします。
今回も、関数を自作して描画をしようと思います。
関数名は「ConcentArrow」にしました。引数は拘束表示と同様になります。
中身のコードですが、とりあえず普通に線を描くコードを入力します。

image

エクスルの図形のように、先程描いた線の先端に矢印を付けます。
今回は、「System.Drawing.Drawing2D」の中の「AdjustableArrowCap」クラスを使用します。
なので、これをインスタンスし、変数に格納します。
次に、新しいPenを作成します。まず、「new Pen(Color.SkyBlue, 1)」で線の色と太さを設定します。
そして、この先端(CustomStartCap)に先程格納した矢印変数を当てます。これでスタート箇所のみ矢印が付くようになります。
最後に、描画する場合のペンをこの新しいペンに変更すれば完了になります。

image

関数ができたので、実際に使用します。
フォームロードイベントに関数を追記します。表示する箇所は左上上端にしました。

image

これで実行してみます。
しっかり描けています。大きさもこのくらいでいこうと思います。

image

今度はモーメント表示をします。
今回も、関数を自作して描画をしようと思います。
関数名は「MomentArrow」にしました。引数は拘束表示と同様になります。
中身のコードですが、今度は円弧を描くコードを入力します。
コードのイメージは線を描くイメージと同じですが、描画する時に「.DrawLine」ではなく 「.DrawArc」になります。ただこの命令文の設定が少し複雑です。

image

「.DrawArc」の入力規則は画像のとおりになるようです。
ペンの設定後は円弧の書き始めの位置(赤)、その点からの書き終わりの追加幅・高さ(紫)、円弧の書き始め角度(黄) 、その角度からの書き終わりの追加角度になります。
矢印は、スタート点に付けるようにしているので画像の位置になります。
以上のため、x1,y1はそれぞれ節点座標から-25pxづつ引くようにしています。

image

これで、フォームロードイベントにこの関数を追記し、実行してみます。
描画結果は画像のとおりです。
これで、試し書きは終わりにします。

骨組の表示

image

試し書きが終わったので、ここから本当に骨組表示の作業をしていきます。
それでは、骨組解析のプロジェクトに戻り「Form1」コード上部に変数を宣言します。宣言する変数は画像のとおりです。

image

次に描画する縮尺を決定していこうと思います。
縮尺計算は別クラスを用意してそこで計算するようにします。それでは、新しいクラスを追加したいと思います。
ソリューションエクスプローラーの「骨組解析」のところで右クリックします。
すると、画像のとおり、選択できる画面が出てきますので、「追加」→「新しい項目」を選択します。

image

「クラス」を選択し、名前を入力します。
名前の先頭文字は大文字にする必要があるようです。今回は「DrawingScale.cs」としました。
名前を入力したら「追加」ボタンを押します。

image

早速コードを書いていきます。
ここでは、まずx、y座標の最大値と最小値を取得します。
メンバー関数は、「CalcScalse(int nd)」とし、節点数「nd」を受け取り、それを新たな変数に格納します。
次に、1つめのx座標・y座標をスタートにし、最大値と最小値を求めます。

image

上述で求めた最大値から、x方向、y方向それぞれの最大長さを求めます。
この最大長さがピクチャーボックス内に収まるようにする必要があるので、x方向、y方向それぞれの縮尺は 骨組描画サイズの300px内になります。なので、300pxをそれぞれの最大長さで割ります。
最後にどちらの縮尺を採用するか決める必要があるので、その計算をしています。最終的に決定した縮尺を変数「S」に格納しています。

image

縮尺が確定したのでx座標、y座標を描画用に変換します。
ただし、y方向は下方向が正になりますので、少し計算式が変わります。
最後に、確定した縮尺をどこでも使用できるようにします。これで、このクラスの作業はすべて終了になります。

image

「Form1」のデザイン画面に移動します。
そのメニューバーに新しく項目「描画」を追加します。
さらに、「描画」下層に「骨組表示」を追加し、名前を「drawFrameM」に変更しました。

image

次に、「Form1」のコード上部に描画タイプを格納する変数を宣言します。
変数名は、「denoteType」にしました。

image

ここで、新しくフォームを作成します。
ソリューションエクスプローラー上で右クリックし、追加のフォームを選択します。

image

名前は変えずに「Form7」のまま使用します。

image

「Form7」のデザイン画面にピクチャーボックスとボタンを配置します。
ピクチャーボックスのサイズは500✕500にします。これで一旦「Form7」のデザインを終わります。

image

あちこち移動して大変申し訳ないのですが、「Form1」のコード上部に移動します。
そこに「Form7」の変数を宣言します。

image

「Form1」ロードイベントで、「Form7」をインスタンスします。

image

デザイン画面のメニューバーの「骨組表示」をダブルクリックしてコード画面に移動します。
ここでは、「Form7」を表示するためのコードを書きます。
ただし、節点座標等すべての情報が入力されていないとエラーが発生する可能性があるので、「計算実行」が完了している。 すなわち、変数「nnod1」に節点数が格納されている場合のみ「Form7」を表示するようにしました。
また、描画タイプを骨組表示とするということで、「1」を変数に格納しています。

image

それでは、「Form7」に移動し、フォームロードイベントに進みます。
試し書きで行ったとおり、ビットマップ画像を作成します。作成するコードは、「 public static Bitmap _bitmap = new Bitmap(500, 500);」 にします。
次に、グラフィックオブジェクトを作成し、最後に「PictureBox」の背景色を黒にしたいので、BackColorを黒にするコードを入力します。

image

次に先程作成した描画用の座標変換クラスを実行します。これで準備完了になるので早速描画をしていきます。
今回の描画は「骨組表示」という条件なので、あらかじめ描画タイプの条件分けをif文で行っておきます。
そしてこの中に、描画コードを入力していきます。
とりあえず、骨格を表示していきます。コードは試し書きと同様ですが、for文で要素数分繰り返し処理をしています。

image

ここからは拘束条件表示の作業を行っていきます。
拘束条件表示は別クラスを用意してそこで計算するようにします。それでは、新しいクラスを追加したいと思います。
ソリューションエクスプローラーの「骨組解析」のところで右クリックします。 すると、画像のとおり、選択できる画面が出てきますので、「追加」→「新しい項目」を選択します。

image

「クラス」を選択し、名前を入力します。 名前の先頭文字は大文字にする必要があるようです。今回は「DrawingConst.cs」としました。 名前を入力したら「追加」ボタンを押します。

image

コードの入力画面が現れますが、その前に描くうえで一つ問題があります。
画像のとおり、拘束条件によっては表示する向きを決める必要がありますが、どうしてもおじさんの頭では良い方法が浮かびませんでした。
なので、完全固定の場合は、四角とし、その他の拘束条件で向きが必要な場合は、一定方向とすることにしました。ご了承ください。

image

最初は、拘束状態の確認をし、拘束されていれば、つまり「idNum」が0の場合は拘束描画を行うことにします。
そこからは、条件分けになりますが、非常に種類が多く根気が必要ですが気合いで突破するしかありません。
まずは完全固定から行っていきます。

image

描画コードを入力する前に、一つコードを追記する必要があります。
画像のとおり、クラス上部に、「using System.Drawing;」と入力します。
クラスの場合は、デフォルトでこのシステムが設定されていないようです。

image

「LOOPEND1:;」以降のコードに戻ります。
まず、グラフィックオブジェクトの設定と拘束状態(ic1~ic3がそれぞれx,y,mに相当)の取得をします。
それから、拘束マークを描画する節点座標を取得しています。

image

画像は完全固定の場合の描画コードを現しています。
四角を描く場合は、「DrawRectangle」のいう命令文のようです。
一応、この拘束マークの大きさは一定では無く、縮尺により変更しようと思います。

image

画像はピン支持の場合のコードになります。
内容は、試し書きの場合と同様なので割愛します。ただ、縮尺の掛け方を間違えていたので修正しています。

image

画像はピンローラー支持の場合の描画コードを現しています。
ただし、ピンローラー支持はx方向と、y方向の2種類存在します。
ここでは、x方向ピンローラー支持のコードになります。

image

y方向のピンローラー支持のコードになります。
今回は、左向きと、右向きの2種類作成します。if文でマークする種類を分けています。
画像は、節点が表示画面の左側にある場合のコードになります。

image

節点が表画面の右側にある場合のy方向のピンローラー支持のコードになります。

image

最後は、回転固定ローラー支持のコードです。
画像は、x方向の回転固定ローラー支持を入力しています。

image

y方向の回転固定ローラー支持のコードになります。
これで、このクラスのコードはすべて完了になります。

image

「Form7」のコードに戻ります。
先程作成したクラスには引数に縮尺を指定していますが、現時点では、その縮尺値はできていません。
なので、新しい関数を作成して、縮尺値の計算をします。
関数名は「DenoteScals」にしました。ここで、最大の要素長さに応じて縮尺値を計算するようにしました。

image

フォームロードイベントに画像のコードを追記します。
これで、拘束マークを描画するようになりました。

image

拘束マークの表示が終わりましたので要素番号を表示しようと思います。
コードが画像のとおりになります。

image

ここからは集中荷重表示の作業を行っていきます。
集中荷重表示も別クラスを用意してそこで制御するようにします。それでは、新しいクラスを追加したいと思います。
ソリューションエクスプローラーの「骨組解析」のところで右クリックします。 すると、画像のとおり、選択できる画面 が出てきますので、「追加」→「新しい項目」を選択します。

image

「クラス」を選択し、名前を入力します。 名前の先頭文字は大文字にする必要があります。
今回は「DrawConLoad.cs」としました。 名前を入力したら「追加」ボタンを押します。

image

まず、画像のとおり、クラス上部に、「using System.Drawing;」と入力します。
次に、メンバ関数(Drawingexe)を作成します。引数には節点数と縮尺にしています。
関数内ではまず、節点座標と集中荷重値を取得するコードを入力しています。

image

また、前後して申し訳ないですが、荷重の最大値の取得をしていませんでした。
先程の繰り返し文の上にもう一つ繰り返し文を作り、最大荷重の計算をします。

image

もう一つの繰り返し文に戻ります。
最初に矢印の設定をします。その後に、x方向の集中荷重を描く制御文を書いています。
次にy方向の集中荷重を描く制御文を書いています。それぞれ、荷重が存在する場合(荷重がゼロでない)という条件の下実行するようにしています。
矢印の長さは、先程求めた荷重の最大値を利用し、長さは最大でも70pxまでとしました。

image

新しいペンを作成します。
このペンは描き終わりに矢印を表示するように用意しました。

image

y方向の描画の後に、モーメントを描画するコードを書きます。
モーメントは、正負で回転が違うので、条件分けして描画するようにしました。
これで、すべての集中荷重の描画が完了になりますので、このクラスも終了になります。

image

「Form7」フォームロードイベントに戻ります。
先程作った「DrawConLoad」クラスをインスタンスし実行するコードを追加します。

image

次は、いよいよ分布荷重です。ここまで随分作コードを書いてきていますが、骨組表示は、やっと、これで最後の項目になります。
例のごとく、新しいクラスを作成します。
ソリューションエクスプローラーの「骨組解析」のところで右クリックします。
「追加」→「新しい項目」を選択します。

image

「クラス」を選択し、名前を入力します。
今回は「DrawDistriLoad.cs」としました。 名前を入力したら「追加」ボタンを押します。

image

それでは、このクラスに分布荷重の描画コードを書こうと思っていたら、肝心の分布荷重を変数に格納していませんでした。
なので、「Form1」のコードに戻ります。(ごめんなさい。)
まずは、変数を宣言します。
変数名は、「distrix1、distriy1、distrix2、distriy2」としました。

image

「Form1」のコードの中段の箇所の分布荷重の読み込みのところで、画像のコードを追記し、先程作った変数に格納します。
これで、描画の作業に戻れます。

image

「DrawDistriLoad.cs」に戻ります。
最初に、グラフィックが使用できるように「using System.Drawing」を追記しています。
次に、メンバ関数を作成します。関数名は「DrawingExe」とし、要素数、節点数および縮尺を変数に格納しています。
その後、グラフィックオブジェクトの設定をしています。

image

次に最大荷重を求めます。
分布荷重、集中荷重の中での最大値を求めています。

image

ここから実際に分布荷重を描画する処理を行います。
まず、要素数で繰り返しを行い、その中で節点座標と分布荷重を取得します。

image

次に矢印の設定とペンの設定をしています。
そして、まずx方向の分布荷重を描画するコードを入力しています。
描画条件は、要素両端のどちらかに分布荷重が存在している場合(分布荷重がゼロでない場合)に実行するようにしました。

image

y方向の分布荷重の描画コードになります。
最後に、グラフィックオブジェクトを閉じて完了になります。
これで、このクラスは完了になりますので、「Form7」でこのクラスを実行するコードを追加していきます。

image

「Form7」のロードイベントの続きです。
ここに、先程作成したクラスをインスタンスして実行するようにします。
以上で「骨組表示」はすべて完了になります。これだけでも長かった。

せん断力の表示

image

「Form1」のデザイン画面に移動します。
メニューバーの「描画」下層に「せん断力表示」を追加し、名前を「drawShearM」に変更します。

image

デザイン画面のメニューバーの「せん断力表示」をダブルクリックしてコード画面に移動します。
ここでは、「Form7」を表示するためのコードを書きます。
ただし、節点座標等すべての情報が入力されていないとエラーが発生する可能性があるので、ここでも「計算実行」が完了している。 すなわち、変数「nnod1」に節点数が格納されている場合のみ「Form7」を表示するようにしています。
また、描画タイプをせん断力表示をするということで、「2」を変数に格納しています。

image

それでは、「Form7」に移動し、フォームロードイベントの続きにせん断力表示のコードを追記します。
まず、if文で。タイプ分けをしています。(ここでは2になります。)
その中の内容ですが、骨組表示の荷重を表示以外の内容と同様になります。

image

いよいよせん断力表示のコードになります。
せん断力表示も別クラスを用意してそこで制御するようにします。それでは、新しいクラスを追加したいと思います。
ソリューションエクスプローラーの「骨組解析」のところで右クリックします。
画像のとおり、選択できる画面 が出てきますので、「追加」→「新しい項目」を選択します。

image

「クラス」を選択し、名前を入力します。 名前の先頭文字は大文字にする必要があります。 今回は「DrawShearLoad.cs」としました。 名前を入力したら「追加」ボタンを押します。

image

まず、画像のとおり、クラス上部に、「using System.Drawing;」と入力します。
次に、メンバ関数(DrawingExe)を作成します。引数は要素数と縮尺にしています。
関数内ではまず、要素数と縮尺を変数に格納するコード、グラフィックオブジェクトを作成するコード及び 座標変換マトリクスを格納する変数を作成しています。
ここで、座標変換マトリクスを作成している理由ですが、計算結果のせん断力は要素座標系のため描画するには全体座標系の座標が必要になります。
そのため座標変換マトリクスの変数を用意しています。

image

次に、for文で要素ごとのせん断力を取得していきます。
格納する変数名は「Q1、Q2」としています。
そのご、座標変換マトリクスの計算をしています。このコードは以前にも使用していますので説明は割愛します。

image

いよいよ描画用の座標の整理と描画になります。
まず、描画用の要素両端の座標を取得します。格納する変数名は「xs、ys、xe、ye」としています。
「xs、ys」は要素左端の座標で、「xe、ye」が要素右端の座標になります。
次に、せん断力を全体座標系に変換しています。ここで1.4を掛けていますが、これはあまり意味が無く縮尺Sでは小さいので単純に1.4倍しているだけです。
その次に、このせん断力の座標を計算しています。単純に要素両端からの離れになります。
最後に描画をして終了になり、このクラスも終了になります。

image

それでは、「Form7」に移動し、フォームロードイベントの続きにせん断力クラスのインスタンスと実行コードを追記します。
これで、せん断力描画の終了になります。

曲げモーメントの表示

image

通常、分布荷重の曲げモーメント図は画像のとおり、円弧の形になります。
しかし、おっさん困ったことにこの円弧を描画するコードが全く考えつきません。
なので、円弧は諦め、分布荷重も集中荷重と同様、直線表示にします。ご了承ください。

image

これまでと同様「Form1」のデザイン画面に移動し、メニューバーの「描画」下層に「曲げモーメント表示」を追加します。
名前を「drawBendingM」に変更します。

image

デザイン画面のメニューバーの「曲げモーメント表示」をダブルクリックしてコード画面に移動します。
これまでと同様「Form7」を表示するためのコードを書きます。
やはり、節点座標等すべての情報が入力されていないとエラーが発生する可能性があるので、ここでも「計算実行」が完了している。 すなわち、変数「nnod1」に節点数が格納されている場合のみ「Form7」を表示するようにしています。
また、描画タイプを曲げモーメント表示をするということで、「3」を変数に格納しています。

image

それでは、「Form7」に移動し、フォームロードイベントの続きに曲げモーメント表示のコードを追記します。
まず、if文で。タイプ分けをしています。(ここでは3になります。)
あとはせん断力の表示以外同様の内容になります。

image

曲げモーメント表示も別クラスを用意してそこで制御するようにします。それでは、新しいクラスを追加したいと思います。
ソリューションエクスプローラーの「骨組解析」のところで右クリックします。
画像のとおり、選択できる画面 が出てきますので、「追加」→「新しい項目」を選択します。

image

「クラス」を選択し、名前を入力します。 名前の先頭文字は大文字にする必要があります。
今回は「DrawBendMoment.cs」としました。 名前を入力したら「追加」ボタンを押します。

image

コードに移ります。
内容はせん断力と同じになります。
一つ違う箇所は、曲げモーメントを全体座標系に変換するときに、マイナスを掛けています。
これは、曲げモーメント図の正の表示が要素の下に図示するため、それに対応させるための処理になります。(せん断力は要素の上が正)

image

「Form7」に移動し、フォームロードイベントの続きに曲げモーメントクラスのインスタンスと実行コードを追記します。
これで、曲げモーメント描画の終了になります。

軸力の表示

image

大変すみません。軸力まではどうしても面倒になったので軸力の表示は行わないことにしました。
イメージとしては、軸力が正の場合は圧縮側で、負の場合は引張側に力が働く感じと捉えておけば良いのではないかと思います。

細部の処理

image

フォームのタイトルを項目ごとに表示したいと思います。
コードは画像のとおりで、せん断力と曲げモーメントの箇所にも追記します。

image

「Form7」のデザイン画面に移動し、ボタンの表示名を変更します。
プロパティの「Text」を「閉じる」に変更します。

image

「閉じる」ボタンをダブルクリックし、コード画面に移動します。
「This.Close();」関数でこのフォームを終了するようにします。

image

その他、このフォームの開始表示位置や最大化の無効などの設定をします。
無理矢理ですが、これでグラフィック表示は終了にします。
中途半端になりましたが個人的には大変満足している出来になりました。

Step5

ツールストリップ

image

「Form1」のデザイン画面に戻り、フォーム上部によく見る小さなアイコンを作成しようと思います。
ツールボックスの「toolStrip」を選択し、フォーム上にドラックアンドドロップします。

image

そのまま、「Button」を選択します。

image

ボタン表示に変わりましたので、そのプロパティの「image」を変更します。
今回は、メニューバーの「計算実行」と「節点数と要素数」と「拘束条件の入力方法」と 「分布荷重の入力方法」の4つをボタン化しています。
アイコン画像はフリー素材をWebページで探して使用しています。

image

作成したボタンにコードを入力します。
それぞれのボタンをダブルクリックします。
コードは、すでに作成されているコードを転用するだけなので、その関数を指定すれば終了になります。
画像は例として「計算実行」を転用する場合のコードになります。

Step6

実行ファイルの作成

image

実行ファイル化(exe化)をしていきます。その前に、アイコンの設定をします。
画面右上のソリューションエクスプローラー内にある「ProPerties」を開きます。
その中の「アイコンとマニフェスト」に自分で作成したアイコン画像を指定します。
これをしておかないと、実行ファイルアイコンが表示されません。

image

画面中央上部にある部分を「Release」に変えます。
それから、メニューバーのビルドから「ソリューションのリビルド」を選択します。
これで、実行ファイル化が行われます。
作成された実行ファイルは、リビルド後に自動作成されている「binフォルダ」内の「Releaseフォルダ」内にあります。