| ■103808 / ) |
Re[13]: Visual Basicで簡易CADを作成 |
□投稿者/ 魔界の仮面弁士 (3879回)-(2025/08/04(Mon) 11:36:03)
|
■No103806 (shiro さん) に返信 > 柱は四角形で、 「四角形」だと、「凹四角形」や「平行四辺形」も含まれてしまうので、 より正確には「長方形」という表現になりますね。
現状の柱は、Point 構造体ではなく Rectangle 構造体で管理されているわけですが、 広義の意味の「四角形」を表そうとしたら、Rectangle ではなく、 「4 つの Point」を用いる方が良いでしょう。 https://www.umayadia.com/vbsample/VBdotNet-Samples201/Sample279WinFormDrawPolygon.htm
一方、柱が長方形(正方形)に限定されており、斜めに配置する事も無いのであれば 一つの壁を「4 個の Point」で扱うより、「単一の Rectangle」の方が管理しやすいですよね?
であれば同様に壁についても「2 個の Point」ではなく単一のオブジェクトで扱った方が 分かりやすくなるとは思います、クラスや構造体を自作できるだけの経験を積み重ねれば。
> 壁はPointで線を繋ぐ逆の処理をし、 幾つか疑問が。
a)柱を配置しないと、壁を描けない仕様でしょうか? あるいは先に壁を描いた後、両端に柱が建つという手順もあるのでしょうか?
b)もしも壁の両端が柱と接触していなければならないという条件なのだとしたら 柱を撤去した場合、それに付随する壁も一緒に削除されるべきということになりますか?
c)一本の柱に複数の壁が接触している可能性がありますか? 一つの柱交点から複数の壁が伸びるイメージで(「╋」「┗」「┫」「*」など)
もしも壁の両端に柱が必須であるがゆえに、柱の撤去と共に壁も取り去る必要があるのだとしたら。
柱を削除する際には、削除する柱に接するすべての壁を列挙して、 柱のみならず、接する壁すべても併せて RemoveAt しないといけないでしょうね。
そうして、柱(snappedRectangles)やpointList(壁)の情報を変化させた後は、 再描画を依頼するために、いつもの『PictureBox1.Invalidate()』を呼び出します。
これによって、 > 再度、図形を描かせるということでしょうか。 のための Paint イベントが発生することになります。
あるいは、「柱に接していない壁も配置できる」ルールだが、本来は柱が必要であるというのなら、 接していない壁を別の色で描画したい、といったニーズも出てくるかもしれません。そうした場合も、 ・位置算出処理(マウス操作あるいはCSV読み取り)で、壁ごとの状態や色情報を記録し、Invalidate を呼び出す ・Paint イベントで、既に算出済みの柱や壁の情報を読み取り、適切な位置と色で描いていく という方針には変わりないでしょうね。
> 今までsubだけでデータの入出力はcsvやテキストで実施していました。 > 柱は四角形で、壁はPointで線を繋ぐ逆の処理をし、再度、図形を描かせるということでしょうか。
もちろん、Sub だけで開発することも可能ですが、 できれば Function や Property についても学んでいった方が良いでしょう。
今回の「壁や柱の情報を保持している CSV」の具体的な内容が分からないので 具体的なコードは書けませんが:
柱と壁を別々に管理するのではなく、No103796 のような統一的な継承実装にしておくと、 Friend Function LoadFromCSV(csvPath As String) As List(Of DrawingObjectBase) のようなメソッドを作り込むことができ、今後、 ・剛性を5kN/m固定とせず、基準剛性の異なる厚壁/薄壁の追加 ・壁や柱以外のアイテムを新設 など、管理情報が増えた場合にも保守しやすいコードになりますよ。
イメージコード:
'描画アイテム全てを管理しているコレクション Private drawItems As New List(Of DrawingObjectBase)()
'CSV ファイル読み込みボタン Private Sub Button1_Click(…… If OpenFileDialog1.ShowDialog() = DialogResult.Cancel Then Return 'CSVファイルが選択されなかった End If
'CSV を読み込み Dim newItems As List(Of DrawingObjectBase) = LoadFromCSV(OpenFileDialog1.FileName) If newItems IsNot Nothing Then '読み込んだデータに基づいて再描画 Me.drawItems = newItems PictureBox1.Invalieda() End If End Sub
Private Sub PictureBox1_Paint(…… For Each drawItem In drawItems drawItem.Draw(e.Graphics) '柱も壁もすべて、このメソッドを呼ぶだけで描画される Next : : End Sub
|
|