C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

■103817 / 18階層)  Visual Basicで簡易CADを作成
□投稿者/ 魔界の仮面弁士 (3883回)-(2025/08/05(Tue) 18:02:32)
No103815 (shiro さん) に返信
> pointListからwallListに変えました。
> Private wallList As New List(Of Wall)
その方が分かりやすいので良いと思います。


> startPoint、endPointとWallクラスでエラーが出ます。
いわゆるコンパイルエラーというやつですね。

前回 ( No103812 ) でも指摘させていただきましたが、「変数のスコープと寿命」に関して
Visual Basic の言語機能として習得しきれていない印象を受けました。


> '耐力壁
> Case "wall"
>  startPoint As New Wall(SnapToGrid(e.Location))

As 句は、変数宣言時に型を明示するためのものです。

startPoint は、MouseDown イベントで書き込まれ、Paint イベントで読まれる値
endPoint は、MouseMove/MouseUp イベントで書き込まれ、Paint イベントで読まれる値
ですよね。そのほか、isPlacing もそうですね。

つまり、これらの変数は『複数のイベントで使われる変数』なのですから、
これらの変数は「ローカル変数」ではなく「フィールド変数」でなければなりません。
ローカル変数だと、変数の寿命がプロシージャー単位(Sub や Function ごと)になってしまいます。


さて、ローカル変数における
  Dim a As New Foo(b)
という記述は、Visual Basic では
  Dim a As Foo = New Foo(b)
と完全に同じです。
これらは、変数の宣言と同時に、その初期値を設定するためのコードですよね。

宣言済みのクラス変数に対して、そのインスタンスを割り当てる場合、
宣言済みの「Dim a As Foo」あるいは「Priavate a As Foo」への代入のために
  a = New Foo(b)
と書くことはできますが
  a As New Foo(b)
と書くことはできません。As は変数宣言時に型を指定するためのものだからです。

そのため、現在の
> startPoint As New Wall(SnapToGrid(e.Location))
> endPoint As New Wall(SnapToGrid(e.Location))
という記述は、コンパイルエラーになってしまっているということです。
複数のイベントで使われる変数は、Form1 直下にローカル変数として宣言しましょう。


ただ、startPoint や endPoint という名から想像するに、
それらは壁そのものではなく、
壁の端を表す位置情報に過ぎないはずです。つまり、
  Private startPoint As Wall
  Private endPoint As Wall
といった「壁オブジェクト」(Wall クラス)ではなく、
  Private startPoint As Point
  Private endPoint As Point
といった「位置オブジェクト」(Point 構造体)であるはずなのです。


MouseDown で決まるのは壁の始端位置なので、「startPoint = SnapToGrid(e.Location)」とします。
MouseMode/MouseUp では壁の終端位置なので、「endPoint = SnapToGrid(e.Location)」とします。
いずれの場合も、位置情報が更新されたので、「PictureBox1.Invalidate()」で再描画を依頼します。

また、MouseUp のタイミングでは、始端と終端の両方が揃ったことになりますので、
これでようやく「壁」を建てることできるようになります。両端が確定したので、
  Dim newWall As New Wall(startPoint, endPoint) '新しい壁を準備
  wallList.Add(newWall) 'それを壁一覧に加える
を行うことで、Paint イベントに壁情報を渡せるようになります。


……とはいえ、上記の改修を行うと、今度は New Wall(〜) を呼び出す部分で、
また別のコンパイルエラー(引数の数が違っているので)になってしまうはずです。


そもそも、壁の位置は (X,Y) が一つだけあっても決定できません。
当然、(X1,Y1)と(X2,Y2) が必要なわけです。そのための修正を行いましょう。

ついでに、剛性値も「既定値(2.5)」または「任意値」の両方に対応させちゃいましょうか。


'=== 案1 ===
Public Class Wall
    Private Shared LastIndex As Integer = 0
    Private Const DefaultStiffnessValue As Double = 2.5

    Public ReadOnly Property Index As Integer
    Public Property StartPoint As Point
    Public Property EndPoint As Point
    Public Property Stiffness As Double

    Public Sub New(startPoint As Point, endPoint As Point)
        Me.New(startPoint, endPoint, DefaultStiffnessValue)
    End Sub

    Public Sub New(startPoint As Point, endPoint As Point, stiffness As Double)
        LastIndex += 1
        Me.Index = LastIndex
        Me.StartPoint = startPoint
        Me.EndPoint = endPoint
        Me.Stiffness = stiffness
    End Sub
End Class


'=== 案2 ===
Public Class Wall
    Private Shared LastIndex As Integer = 0
    Private Const DefaultStiffnessValue As Double = 2.5

    Public ReadOnly Property Index As Integer
    Public Property StartPoint As Point
    Public Property EndPoint As Point
    Public Property Stiffness As Double

    Public Sub New(startPoint As Point, endPoint As Point, Optional stiffness As Double = DefaultStiffnessValue)
        LastIndex += 1
        Me.Index = LastIndex
        Me.StartPoint = startPoint
        Me.EndPoint = endPoint
        Me.Stiffness = stiffness
    End Sub
End Class


これにより、
  Dim newWall As New Wall(startPoint, endPoint)
  wallList.Add(newWall)
あるいは、両者をまとめて
  wallList.Add(New Wall(startPoint, endPoint))
と書けるようになります。また、剛性値を別の値とするために
  wallList.Add(New Wall(startPoint, endPoint, 2.2))
といった指定も可能となっています。


Paint イベントの描画については、
 For Each w In WallList
  e.Graphics.DrawLine(pen7, w.StartPoint, w.EndPoint)
 Next
になります。一つの Wall インスタンスで始点と終点の両方を管理しているため、
従来の Step 2 な For ループを使う必要がなく、処理が簡潔になります。


なお、上記では Wall クラスの座標情報を 2 つの Point で表していますが、
元のソースに従って、X1, Y1, X2, Y2 の 4 つの Integer で表現することもできるでしょう。
どちらが良いかはお好みで。


> csvファイルへの出力は、壁の始点(X,Y)、終点(X,Y)、剛性と出力したいです。
> Type	Index	 X1	 Y1	 X2	 Y2	Stiff
> W   	1    	280	 40	360	 40	  2.5
> W   	2    	280	120	360	120	  2.5

Type=W が壁を意味するデータで
Type=C が柱を意味する行データなのですよね。
柱用の CSV と壁用の CSV で別ファイルになるのでしょうか?

もしも一つのファイルにするのなら、壁と柱で列数が動的に変化するのは、ちょっと不自然かもしれませんね。
列数可変な CSV も世の中にはありますが、ヘッダー付き CSV で行ごとに列数が異なるケースは稀ですし。

案1) ヘッダー行(今回は、"Type,Index," で始まる行)が、ファイル先頭だけでなく文中にも現れ、そこから列数が切り替る
案2) どちらも7列構成にするが、柱の時は先頭4列だけを使い、未使用列には空のデータが入る(空列のためのカンマが続く形になる)
案3) CSV の代わりに、レコードごとに構造を混ぜられる形式(JSON や XML など)を採用する



<ひとりごと>

建築構造体としての柱というニュアンスであれば、Pillar クラスではなく Column クラスの方が単語的に望ましいかな…。
でも Column だと、グリッドや CSV などの「Row/Column」の意味に混同されそうで、命名的に悩んでしまった。

Column  ⇒ 柱、あるいは建築物の中で装飾的・構造的に並んでいる縦の柱
Pillar  ⇒ 建物の主要構造を支える支柱、記念碑や大黒柱などといった中心的存在あるいは意匠的に独立した支柱
Pier   ⇒ 建築・土木分野の専門用語で「柱状の構造物」「基礎・橋脚・大型の柱」を指す
Post   ⇒ 支柱・杭、小さい柱や看板の支え
Pole   ⇒ 細長い棒・支柱、電信柱や旗竿など
Stanchion⇒ 鉄パイプなどの支柱・枠、工事現場の柵や支柱
Support ⇒ 支えとしての支柱、構造体のサポート部材
Beam   ⇒ 横向きの梁、水平な構造体

方眼上に配置するための柱なので、GridColumn とか? こちらは WPF の Grid.Column を連想してしまいそう。

StructuralColumn クラスという名前にすれば明確にはなるけれど、それだと Wall に比べて名前が冗長すぎるか。

Pier であれば、Pillar と Column の中間的なニュアンスとなり、Row/Column との混同も避けられるけれど、
そもそも専門用語過ぎて伝わらないだろうなぁ…。(一般語としての Pier は、桟橋・埠頭の意味で使われる)


</ひとりごと>

編集キー/

前の記事(元になった記事) 次の記事(この記事の返信)
←Re[17]: Visual Basicで簡易CADを作成 /shiro →Re[19]: Visual Basicで簡易CADを作成 /shiro
 
上記関連ツリー

Visual Basicで簡易CADを作成 / shiro (25/07/25(Fri) 20:50) #103783
Re[1]: Visual Basicで簡易CADを作成 / KOZ (25/07/27(Sun) 14:35) #103784
  └ Re[2]: Visual Basicで簡易CADを作成 / shiro (25/07/28(Mon) 20:17) #103785
    ├ Re[3]: Visual Basicで簡易CADを作成 / kiku (25/07/29(Tue) 08:49) #103786
    └ Re[3]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/07/29(Tue) 14:06) #103791
      └ Re[4]: Visual Basicで簡易CADを作成 / shiro (25/07/30(Wed) 12:22) #103792
        └ Re[5]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/07/30(Wed) 15:46) #103794
          └ Re[6]: Visual Basicで簡易CADを作成 / shiro (25/07/31(Thu) 07:34) #103795
            └ Re[7]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/07/31(Thu) 10:48) #103796
              └ Re[8]: Visual Basicで簡易CADを作成 / shiro (25/08/01(Fri) 06:15) #103797
                ├ Re[9]: Visual Basicで簡易CADを作成 / kiku (25/08/01(Fri) 08:47) #103798
                │└ Re[10]: Visual Basicで簡易CADを作成 / shiro (25/08/02(Sat) 03:40) #103803
                └ Re[9]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/01(Fri) 10:46) #103800
                  ├ Re[10]: Visual Basicで簡易CADを作成 / kiku (25/08/01(Fri) 10:50) #103801
                  └ Re[10]: Visual Basicで簡易CADを作成 / shiro (25/08/02(Sat) 03:38) #103802
                    └ Re[11]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/03(Sun) 11:50) #103805
                      └ Re[12]: Visual Basicで簡易CADを作成 / shiro (25/08/04(Mon) 05:10) #103806
                        └ Re[13]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/04(Mon) 11:36) #103808
                          └ Re[14]: Visual Basicで簡易CADを作成 / shiro (25/08/04(Mon) 18:59) #103811
                            └ Re[15]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/04(Mon) 19:43) #103812
                              └ Re[16]: Visual Basicで簡易CADを作成 / shiro (25/08/05(Tue) 12:42) #103814
                                └ Re[17]: Visual Basicで簡易CADを作成 / shiro (25/08/05(Tue) 12:44) #103815
                                  └ Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/05(Tue) 18:02) #103817 ←Now
                                    └ Re[19]: Visual Basicで簡易CADを作成 / shiro (25/08/05(Tue) 19:28) #103819
                                      └ Re[20]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/05(Tue) 20:39) #103821
                                        └ Re[21]: Visual Basicで簡易CADを作成 / shiro (25/08/06(Wed) 12:22) #103822
                                          └ Re[22]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/06(Wed) 14:42) #103825
                                            ├ Re[23]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/06(Wed) 17:53) #103828
                                            │└ Re[24]: Visual Basicで簡易CADを作成 / shiro (25/08/06(Wed) 19:13) #103830
                                            │  ├ Re[25]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/06(Wed) 19:44) #103832
                                            │  │└ Re[26]: Visual Basicで簡易CADを作成 / shiro (25/08/07(Thu) 07:06) #103834
                                            │  │  └ Re[27]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/07(Thu) 12:18) #103835
                                            │  │    └ Re[28]: Visual Basicで簡易CADを作成 / shiro (25/08/07(Thu) 19:14) #103836
                                            │  │      └ Re[29]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/07(Thu) 20:25) #103837
                                            │  │        ├ Re[30]: Visual Basicで簡易CADを作成 / shiro (25/08/08(Fri) 03:34) #103838
                                            │  │        └ Re[30]: Visual Basicで簡易CADを作成 / shiro (25/08/08(Fri) 07:29) #103839
                                            │  │          └ Re[31]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/08(Fri) 09:40) #103841
                                            │  │            └ Re[32]: Visual Basicで簡易CADを作成 / shiro (25/08/09(Sat) 05:05) #103842
                                            │  │              └ Re[33]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/09(Sat) 14:24) #103843
                                            │  │                └ Re[34]: Visual Basicで簡易CADを作成 / shiro (25/08/09(Sat) 19:18) #103844
                                            │  └ Re[25]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/06(Wed) 19:53) #103833
                                            └ Re[23]: Visual Basicで簡易CADを作成 / shiro (25/08/18(Mon) 12:41) #103847
                                              └ Re[24]: Visual Basicで簡易CADを作成 / kiku (25/08/20(Wed) 15:09) #103848
                                                └ Re[25]: Visual Basicで簡易CADを作成 / shiro (25/08/20(Wed) 18:35) #103849
                                                  └ Re[26]: Visual Basicで簡易CADを作成 / kiku (25/08/21(Thu) 09:03) #103850
                                                    └ Re[27]: Visual Basicで簡易CADを作成 / shiro (25/08/21(Thu) 22:01) #103851
                                                      └ Re[28]: Visual Basicで簡易CADを作成 / kiku (25/08/22(Fri) 08:45) #103852
                                                        └ Re[29]: Visual Basicで簡易CADを作成 / shiro (25/08/22(Fri) 13:20) #103853
                                                          └ Re[30]: Visual Basicで簡易CADを作成 / kiku (25/08/22(Fri) 16:45) #103854
                                                            └ Re[31]: Visual Basicで簡易CADを作成 / shiro (25/08/22(Fri) 20:33) #103855
                                                              └ Re[32]: Visual Basicで簡易CADを作成 / kiku (25/08/25(Mon) 08:42) #103857

上記ツリーを一括表示 / 上記ツリーをトピック表示
 
上記の記事へ返信