• 締切済み

VB2010 面積算出

panelを用いた図形の作成を行っております。 コード Public Class Form1 Dim p1 As Integer 'Panel1のカウンター Dim p2 As Integer 'Panel2のカウンター Dim p3 As Integer 'Panel3のカウンター Dim p1size As Single 'Panel1の面積 Dim p2size As Single 'Panel2の面積 Dim p3size As Single 'Panel3の面積 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Shown Dim p1clnt As Drawing.Size = Panel1.ClientSize Dim p2clnt As Drawing.Size = Panel2.ClientSize Dim p3clnt As Drawing.Size = Panel3.ClientSize p1size = p1clnt.Width * p1clnt.Height p2size = p2clnt.Width * p2clnt.Height p3size = p3clnt.Width * p3clnt.Height Panel4.AllowDrop = True End Sub Private Sub Panel1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown, Panel2.MouseDown, Panel3.MouseDown sender.DoDragDrop(sender, DragDropEffects.Move) End Sub Private Sub Panel4_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Panel4.DragDrop Dim srsPnl As Panel = e.Data.GetData(GetType(Panel)) Dim dstPnl As New Panel dstPnl.Size = srsPnl.Size Dim dropp1 As Integer = srsPnl.Size.Width * srsPnl.Size.Height If dropp1 = p1size Then p1 += 1 ElseIf dropp1 = p2size Then p2 += 1 ElseIf dropp1 = p3size Then p3 += 1 End If dstPnl.Location = Panel4.PointToClient(CursorPosition) 'New Point(e.X, e.Y) dstPnl.BackColor = srsPnl.BackColor AddHandler dstPnl.MouseDown, AddressOf dstPnl_MouseDown AddHandler dstPnl.MouseMove, AddressOf dstPnl_MouseMove Panel4.Controls.Add(dstPnl) End Sub Private Sub Panel4_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Panel4.DragEnter If e.Data.GetDataPresent(GetType(Panel)) Then e.Effect = DragDropEffects.Move End If End Sub Private previousPos As Point Private Sub dstPnl_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown previousPos = CursorPosition() End Sub Private Sub dstPnl_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) If e.Button = Windows.Forms.MouseButtons.Left Then Dim nowPos As Point = CursorPosition() DirectCast(sender, Panel).Left += nowPos.X - previousPos.X DirectCast(sender, Panel).Top += nowPos.Y - previousPos.Y Console.WriteLine(nowPos.X & "-" & previousPos.X) previousPos = nowPos End If End Sub Function CursorPosition() As Point Return New Point(CInt(Cursor.Position.X / 10) * 10, CInt(Cursor.Position.Y / 10) * 10) End Function Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim ans As Single ans = (p1 * p1size + p2 * p2size + p3 * p3size) * 0.0001 TextBox1.Text = ans End Sub End Class 上記のコードは、GroupBox内のpanelをpanel4へ移動させて図形を作成するものです。 移動させたpanelの数を数えて、全体の面積を算出させているのですが、 作成させた図形の右側1/4の面積だけ(左側1/4,下側1/4といった風に)の面積を算出させることは可能でしょうか? 画像 ※図形は任意  重複なし(panel同士) 1m2   (青) 3枚 0.25m2 (赤) 5枚 0.09m2 (黄) 5枚 計 4.7m2 となっています。 この作成した図形の緑色で着色した部分の面積を出したいと考えております。 もしお時間等ありましたら、お力添えをいただけると嬉しく思います。 どうかよろしくお願いします。

みんなの回答

  • keitaaan
  • ベストアンサー率0% (0/0)
回答No.18

こんばんは 突然の割り込み失礼します。 私も今同じようなことをしていてここにたどり着きました。 ここに書かれてあるコードを試してみました。 「heit = hmax(hmax.Count - 1) - hmin(0) '図形のheightの最大値を求める」 のところで 「インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。 パラメーター名: index」 という表示がでてしまいます。 Visual Basicを始めたばかりの初心者なのでわからないことばかりです。 これをどう解決すればいいのか教えていただきたいです。 よろしくお願いいたします。 最後に、私の質問なのにここの回答欄を使ってしまい、申し訳ありません。 もし気に障るなら削除していただいても構いません。

回答No.17

こんにちは 区切りが悪くてページ数が増えてしまいました、 >下1/4に関しては問題なく実行することができます。 良かったです。 >上1/4、右1/4、左1/4に関しては今まで触れていないのですが、 先に、上1/4を片付けましょう。 同様の方法で右1/4、左1/4も計算できます。 >button2をクリックしたら上1/4の面積が出せる >ということは可能なのでしょうか? 追加してみました。 メソッドで対応してますので、少し機能が悪いですね。クラスの作成の学習が終わったら、クラス化してください。(ゆっくり学習してください。) >undoでのカウンターをどのようにすればよいのか。 >というこの前の状態でとまっております。 先日紹介していただいたサイトを見て思い立ったところがありますので、時間のあるときにundoのスレッドの方に記入してみます。 1m2   (青)  0.25m2 (赤)  0.09m2 (黄)  上記は算出した面積の比率から算出できますね。 なるべく共通で使えるコードはメソッド化しましたが、もう少し工夫すればもっと短く出来ると思います。 ちょっとコードが長くなってしまいましたので、正しく計算されるかわかりません。 実験をしてください。問題がある場合は修正するか返信をお願いします。 '上1/4の線の座標より上の面積を求めるメッソド Private Sub calucup() '上1/4の線の座標より上か線をまたいでいるPanelをリストにする For Each pnl As Control In Panel4.Controls If pnl.Size = New Size(pn1, pn11) Then '上1/4の線をまたいでいるPanelの判断 If upline < pnl.Location.Y + pn11 AndAlso upline >= pnl.Location.Y Then '面積の計算 areaup.Add((upline - pnl.Location.Y) * pn1) '上1/4の線をまたいでいるPanelのリストにAddする arup.Add(pnl) ElseIf upline > pnl.Location.Y + pn11 Then '上1/4の線の座標より上の判断 '面積の計算 areaup.Add(pnl.Width * pnl.Height) End If ElseIf pnl.Size = New Size(pn2, pn2) Then '上1/4の線をまたいでいるPanelの判断 If upline < pnl.Location.Y + pn2 AndAlso upline >= pnl.Location.Y Then '面積の計算 areaup.Add((upline - pnl.Location.Y) * pn2) '上1/4の線をまたいでいるPanelのリストにAddする arup.Add(pnl) ElseIf underline > pnl.Location.Y + pn2 Then '上1/4の線の座標より上の判断 '面積の計算 areaup.Add(pnl.Width * pnl.Height) End If ElseIf pnl.Size = New Size(pn3, pn3) Then '上1/4の線をまたいでいるPanelの判断 If upline < pnl.Location.Y + pn3 AndAlso upline >= pnl.Location.Y Then '面積の計算 areaup.Add((upline - pnl.Location.Y) * pn3) '上1/4の線をまたいでいるPanelのリストにAddする arup.Add(pnl) ElseIf upline > pnl.Location.Y + pn3 Then '上1/4の線の座標より上の判断 '面積の計算 areaup.Add(pnl.Width * pnl.Height) End If End If Next '上1/4の線の座標より上の面積を求めます。 Dim mensekiup As Integer For Each pntotal As Integer In areaup mensekiup += pntotal Next MsgBox("上1/4の線をまたいでいるPanelの数は" & vbNewLine & arup.Count & "枚です。" & _ vbNewLine & "上1/4の線の座標より上の面積は" & mensekiup & "です。") 'リストのクリア arclr() End Sub 'リストのクリアメッソド Private Sub arclr() hmin.Clear() hmax.Clear() arsiz.Clear() areadown.Clear() areaup.Clear() arunder.Clear() arup.Clear() End Sub End Class 以上です。

回答No.16

5通目 '下3/4の線の座標より下の面積を求めるメッソド Private Sub calucunder() '下3/4の線の座標より下か線をまたいでいるPanelをリストにする For Each pnl As Control In Panel4.Controls If pnl.Size = New Size(pn1, pn11) Then '下3/4の線をまたいでいるPanelの判断 If underline < pnl.Location.Y + pn11 AndAlso underline >= pnl.Location.Y Then '面積の計算 areadown.Add((pnl.Location.Y + pn11 - underline) * pn1) '下3/4の線をまたいでいるPanelのリストにAddする arunder.Add(pnl) ElseIf underline < pnl.Location.Y Then '下3/4の線の座標より下の判断 '面積の計算 areadown.Add(pnl.Width * pnl.Height) End If ElseIf pnl.Size = New Size(pn2, pn2) Then '下3/4の線をまたいでいるPanelの判断 If underline < pnl.Location.Y + pn2 AndAlso underline >= pnl.Location.Y Then '面積の計算 areadown.Add((pnl.Location.Y + pn2 - underline) * pn2) '下3/4の線をまたいでいるPanelのリストにAddする arunder.Add(pnl) ElseIf underline < pnl.Location.Y Then '下3/4の線の座標より下の判断 '面積の計算 areadown.Add(pnl.Width * pnl.Height) End If ElseIf pnl.Size = New Size(pn3, pn3) Then '下3/4の線をまたいでいるPanelの判断 If underline < pnl.Location.Y + pn3 AndAlso underline >= pnl.Location.Y Then '面積の計算 areadown.Add((pnl.Location.Y + pn3 - underline) * pn3) '下3/4の線をまたいでいるPanelのリストにAddする arunder.Add(pnl) ElseIf underline < pnl.Location.Y Then '下3/4の線の座標より下の判断 '面積の計算 areadown.Add(pnl.Width * pnl.Height) End If End If Next '下3/4の線の座標より下の面積を求めます。 Dim mensekidown As Integer For Each pntotal As Integer In areadown mensekidown += pntotal Next MsgBox("下3/4の線をまたいでいるPanelの数は" & vbNewLine & arunder.Count & "枚です。" & _ vbNewLine & "下3/4の線の座標より下の面積は" & mensekidown & "です。") 'リストのクリア arclr() End Sub 続く

回答No.15

4通目 '上下共通メソッド Private Sub floor() '追加した各PanelのY座標(高さ)をリストにする For Each cntrl As Control In Panel4.Controls hmin.Add(cntrl.Location.Y) Next 'ここから '高さの最少値(座標)を求めるループ Dim cnt As Integer 'リストの数 cnt = hmin.Count 'リストの数 Dim uptp As Integer '大きい値 Dim downtp As Integer '入れ替え前の下の要素 Dim lp1 As Integer 'ループカウンター Dim lp2 As Integer 'ループカウンター '高さの最小値(座標)を求めるループ バブルソート For lp1 = 1 To cnt For lp2 = 0 To cnt - 1 - lp1 If hmin(lp2) > hmin(lp2 + 1) Then uptp = hmin(lp2) '入れ替え前の上の値 downtp = hmin(lp2 + 1) '入れ替え前の下の値 hmin(lp2) = downtp '入れ替え後の上の値 hmin(lp2 + 1) = uptp '入れ替え後の下の値 End If Next Next 'ここまではバブルソート関係 '高さの最大値を求めるループ  + pn1 + pn2 + pn3は移動したPanelの下端 'の座標を取得するためです。 For Each ocntrl As Control In Panel4.Controls If ocntrl.Size = New Size(pn1, pn11) Then '変更箇所 hmax.Add(ocntrl.Location.Y + pn11) '変更箇所 ElseIf ocntrl.Size = New Size(pn2, pn2) Then hmax.Add(ocntrl.Location.Y + pn2) ElseIf ocntrl.Size = New Size(pn3, pn3) Then hmax.Add(ocntrl.Location.Y + pn3) End If arsiz.Add(ocntrl.Size) Next 'ここから '高さの最大値を求めるループ  Dim dtcnt As Integer 'リストの数 dtcnt = hmax.Count 'リストの数 Dim uptmp As Integer '大きい値 Dim downtmp As Integer '入れ替え前の下の要素 Dim upsiz As Size Dim downsiz As Size Dim l1 As Integer 'ループカウンター Dim l2 As Integer 'ループカウンター 'バブルソート For l1 = 1 To dtcnt For l2 = 0 To dtcnt - 1 - l1 If hmax(l2) > hmax(l2 + 1) Then uptmp = hmax(l2) '入れ替え前の上の値 downtmp = hmax(l2 + 1) '入れ替え前の下の値 hmax(l2) = downtmp '入れ替え後の上の値 hmax(l2 + 1) = uptmp '入れ替え後の下の値 upsiz = arsiz(l2) '入れ替え前の上の値 downsiz = arsiz(l2 + 1) '入れ替え前の下の値 arsiz(l2) = downsiz '入れ替え後の上の値 arsiz(l2 + 1) = upsiz '入れ替え後の下の値 End If Next Next 'ここまではバブルソート関係 Dim heit As Integer heit = hmax(hmax.Count - 1) - hmin(0) '図形のheightの最大値を求める upline = heit * 1 / 4 + hmin(0) '上1/4の線の座標 underline = heit * 3 / 4 + hmin(0) '下3/4の線の座標 'テスト用のライン Dim space As New Bitmap(Panel4.Width, Panel4.Height) 'Class picturに値を渡す gragh.pant(space, Panel4.Width, Panel4.Height, hmin(0), heit, underline, upline) 'Panel4に線を描画 Panel4.BackgroundImage = gragh.spc End Sub

回答No.14

3通目 Dim arsiz As New List(Of Size) '各PanelのSizeのリスト Dim hmin As New List(Of Integer) '各Panelの高さのリスト(座標)最小値 Dim hmax As New List(Of Integer) '各Panelの高さのリスト(座標)最大値 Dim gragh As New pictur 'Class picturのインスタンス Dim areadown As New List(Of Integer) '下3/4の面積を計算したPanelのリスト Dim areaup As New List(Of Integer) '上1/4の面積を計算したPanelのリスト Dim arunder As New List(Of Panel) '下3/4の線の座標より下か線をまたいでいるPanelのリスト Dim arup As New List(Of Panel) '上1/4の線の座標より下か線をまたいでいるPanelのリスト Dim upline As Decimal '上1/4の線の座標 Dim underline As Decimal '下3/4の線の座標 '下3/4の線の座標より下の面積を求める Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim ans As Single ans = (p1 * p1size + p2 * p2size + p3 * p3size) * 0.0001 TextBox1.Text = ans 'メソッド化 floor() '下3/4の線の座標より下の面積を求めるメッソド calucunder() End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click 'メソッド化 floor() '上1/4の線の座標より下の面積を求めるメッソド calucup() End Sub

回答No.13

2通目 Class Form1側 Public Class Form1 Const pn1 As Integer = 50 'Panel1に固定 Const pn11 As Integer = 100 '変更箇所 Const pn2 As Integer = 100 'Panel2に固定 Const pn3 As Integer = 150 'Panel3に固定 Dim p1 As Integer 'Panel1のカウンター Dim p2 As Integer 'Panel2のカウンター Dim p3 As Integer 'Panel3のカウンター Dim p1size As Single 'Panel1の面積 Dim p2size As Single 'Panel2の面積 Dim p3size As Single 'Panel3の面積 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Shown 'Panelサイズを設定 Panel1.Size = New Size(pn1, pn11) Panel2.Size = New Size(pn2, pn2) Panel3.Size = New Size(pn3, pn3) Dim p1clnt As Drawing.Size = Panel1.ClientSize Dim p2clnt As Drawing.Size = Panel2.ClientSize Dim p3clnt As Drawing.Size = Panel3.ClientSize p1size = p1clnt.Width * p1clnt.Height p2size = p2clnt.Width * p2clnt.Height p3size = p3clnt.Width * p3clnt.Height Panel4.AllowDrop = True End Sub Private Sub Panel1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown, Panel2.MouseDown, Panel3.MouseDown sender.DoDragDrop(sender, DragDropEffects.Move) End Sub Private Sub Panel4_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Panel4.DragDrop Dim srsPnl As Panel = e.Data.GetData(GetType(Panel)) Dim dstPnl As New Panel dstPnl.Size = srsPnl.Size Dim dropp1 As Integer = srsPnl.Size.Width * srsPnl.Size.Height If dropp1 = p1size Then p1 += 1 ElseIf dropp1 = p2size Then p2 += 1 ElseIf dropp1 = p3size Then p3 += 1 End If dstPnl.Location = Panel4.PointToClient(CursorPosition) 'New Point(e.X, e.Y) dstPnl.BackColor = srsPnl.BackColor AddHandler dstPnl.MouseDown, AddressOf dstPnl_MouseDown AddHandler dstPnl.MouseMove, AddressOf dstPnl_MouseMove Panel4.Controls.Add(dstPnl) End Sub Private Sub Panel4_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Panel4.DragEnter If e.Data.GetDataPresent(GetType(Panel)) Then e.Effect = DragDropEffects.Move End If End Sub Private previousPos As Point Private Sub dstPnl_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown previousPos = CursorPosition() End Sub Private Sub dstPnl_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) If e.Button = Windows.Forms.MouseButtons.Left Then Dim nowPos As Point = CursorPosition() DirectCast(sender, Panel).Left += nowPos.X - previousPos.X DirectCast(sender, Panel).Top += nowPos.Y - previousPos.Y Console.WriteLine(nowPos.X & "-" & previousPos.X) previousPos = nowPos End If End Sub Function CursorPosition() As Point Return New Point(CInt(Cursor.Position.X / 10) * 10, CInt(Cursor.Position.Y / 10) * 10) End Function 続く

回答No.12

1通目 Class pictur側 Public Class pictur Private _spc As Bitmap 'Bitmapの作成 Public Sub pant(sp As Bitmap, panlw As Integer, pankh As Integer, hmin As Integer, ht As Integer, underlin As Decimal, uplin As Decimal) Dim g As Graphics = Graphics.FromImage(sp) Dim pb As New Pen(Color.Black, 1) Dim pr As New Pen(Color.Red, 3) '線を5本引く For i As Integer = 0 To 4 g.DrawLine(pb, 0, hmin + CInt(ht / 4) * i, panlw, hmin + CInt(ht / 4) * i) Next '赤い線を引く g.DrawLine(pr, 0, CInt(uplin), panlw, CInt(uplin)) '上1/4の線 g.DrawLine(pr, 0, CInt(underlin), panlw, CInt(underlin)) '下3/4の線 g.Dispose() _spc = sp End Sub 'Bitmapオブジェクトの読み込み Public ReadOnly Property spc() As Bitmap Get Return _spc End Get End Property End Class 続く

回答No.11

続きです。 下記のようにすると、 Panelのサイズをいろいろ変更しても対応できますね。 Dim pn1 As Integer Dim pn11 As Integer pn1 = Panel1.Width pn11 = Panel1.Width 先回のURLを見て思いましたが、UNDOの件は解決されましたか? 先回のURLの内容からすると、画像を前回の状態にすればいいのかな~なんておもいました。 もし解決していなければ、そちらのスレッドでサンプルを掲載します。 できるかな~? 'バブルソート For l1 = 1 To dtcnt For l2 = 0 To dtcnt - 1 - l1 If hmax(l2) > hmax(l2 + 1) Then uptmp = hmax(l2) '入れ替え前の上の値 downtmp = hmax(l2 + 1) '入れ替え前の下の値 hmax(l2) = downtmp '入れ替え後の上の値 hmax(l2 + 1) = uptmp '入れ替え後の下の値 upsiz = arsiz(l2) '入れ替え前の上の値 downsiz = arsiz(l2 + 1) '入れ替え前の下の値 arsiz(l2) = downsiz '入れ替え後の上の値 arsiz(l2 + 1) = upsiz '入れ替え後の下の値 End If Next Next 'ここまではバブルソート関係 Dim heit As Integer Dim line As Decimal '図形のheightの最大値を求める heit = hmax(hmax.Count - 1) - hmin(0) '下3/4の線の座標 line = heit * 3 / 4 + hmin(0) Label1.Text = "高さの座標最大値は" & hmax(hmax.Count - 1) & " " & "その時の図形のheightは" & _ arsiz(arsiz.Count - 1).Height & vbNewLine & "図形の座標最小値は" & hmin(0) & " " & "合成された図形の最大幅は" & heit & " " & "下3/4の線の座標は" & line 'テスト用のライン Dim space As New Bitmap(Panel4.Width, Panel4.Height) 'Class picturに値を渡す gragh.pant(space, Panel4.Width, Panel4.Height, hmin(0), heit, line) 'Panel4に線を描画 Panel4.BackgroundImage = gragh.spc '下3/4の線の座標より下か線をまたいでいるPanelをリストにする For Each pnl As Control In Panel4.Controls If pnl.Size = New Size(pn1, pn11) Then '変更箇所 '下3/4の線をまたいでいるPanelの判断 If line < pnl.Location.Y + pn11 AndAlso line >= pnl.Location.Y Then '面積の計算 area.Add((pnl.Location.Y + pn11 - line) * pn1) '変更箇所 '下3/4の線の座標より下か線をまたいでいるPanelのリストにAddする arlne.Add(pnl) ElseIf line < pnl.Location.Y Then '下3/4の線の座標より下の判断 '面積の計算 area.Add(pnl.Width * pnl.Height) End If ElseIf pnl.Size = New Size(pn2, pn2) Then '下3/4の線をまたいでいるPanelの判断 If line < pnl.Location.Y + pn2 AndAlso line >= pnl.Location.Y Then '面積の計算 area.Add((pnl.Location.Y + pn2 - line) * pn2) '下3/4の線の座標より下か線をまたいでいるPanelのリストにAddする arlne.Add(pnl) ElseIf line < pnl.Location.Y Then '下3/4の線の座標より下の判断 '面積の計算 area.Add(pnl.Width * pnl.Height) End If ElseIf pnl.Size = New Size(pn3, pn3) Then '下3/4の線をまたいでいるPanelの判断 If line < pnl.Location.Y + pn3 AndAlso line >= pnl.Location.Y Then '面積の計算 area.Add((pnl.Location.Y + pn3 - line) * pn3) '下3/4の線の座標より下か線をまたいでいるPanelのリストにAddする arlne.Add(pnl) ElseIf line < pnl.Location.Y Then '下3/4の線の座標より下の判断 '面積の計算 area.Add(pnl.Width * pnl.Height) End If End If Next '下3/4の線の座標より下の面積を求めます。 Dim menseki As Integer For Each pntotal As Integer In area menseki += pntotal Next MsgBox("下3/4の線の座標より下か線をまたいでいるPanelの数は" & vbNewLine & arlne.Count & "枚です。" & _ vbNewLine & "下3/4の線の座標より下の面積は" & menseki & "です。") 'リストのクリア hmin.Clear() hmax.Clear() arsiz.Clear() area.Clear() arlne.Clear() End Sub End Class 以上です、あってるかな~? 間違っていましたらごめんなさい。

TMYMS
質問者

補足

毎回親切にありがとうございます。 これで下1/4に関しては問題なく実行することができます。 上1/4、右1/4、左1/4に関しては今まで触れていないのですが、 同様のコードbutton2をクリックしたら上1/4の面積が出せる ということは可能なのでしょうか? undoでのカウンターをどのようにすればよいのか。 というこの前の状態でとまっております。

回答No.10

続きです。 Dim arsiz As New List(Of Size) '各PanelのSizeのリスト Dim hmin As New List(Of Integer) '各Panelの高さのリスト(座標)最小値 Dim hmax As New List(Of Integer) '各Panelの高さのリスト(座標)最大値 Dim gragh As New pictur 'Class picturのインスタンス Dim area As New List(Of Integer) '面積を計算したPanelのリスト Dim arlne As New List(Of Panel) '下3/4の線の座標より下か線をまたいでいるPanelのリスト Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim ans As Single ans = (p1 * p1size + p2 * p2size + p3 * p3size) * 0.0001 TextBox1.Text = ans '追加した各PanelのY座標(高さ)をリストにする For Each cntrl As Control In Panel4.Controls hmin.Add(cntrl.Location.Y) Next 'ここから '高さの最少値を求めるループ Dim cnt As Integer 'リストの数 cnt = hmin.Count 'リストの数 Dim uptp As Integer '大きい値 Dim downtp As Integer '入れ替え前の下の要素 Dim lp1 As Integer 'ループカウンター Dim lp2 As Integer 'ループカウンター '高さの最小値を求めるループ バブルソート For lp1 = 1 To cnt For lp2 = 0 To cnt - 1 - lp1 If hmin(lp2) > hmin(lp2 + 1) Then uptp = hmin(lp2) '入れ替え前の上の値 downtp = hmin(lp2 + 1) '入れ替え前の下の値 hmin(lp2) = downtp '入れ替え後の上の値 hmin(lp2 + 1) = uptp '入れ替え後の下の値 End If Next Next 'ここまではバブルソート関係 '高さの最大値を求めるループ  + pn1 + pn2 + pn3は移動したPanelの下端 'の座標を取得するためです。 For Each ocntrl As Control In Panel4.Controls If ocntrl.Size = New Size(pn1, pn11) Then '変更箇所 hmax.Add(ocntrl.Location.Y + pn11) '変更箇所 ElseIf ocntrl.Size = New Size(pn2, pn2) Then hmax.Add(ocntrl.Location.Y + pn2) ElseIf ocntrl.Size = New Size(pn3, pn3) Then hmax.Add(ocntrl.Location.Y + pn3) End If arsiz.Add(ocntrl.Size) Next 'ここから '高さの最大値を求めるループ  Dim dtcnt As Integer 'リストの数 dtcnt = hmax.Count 'リストの数 Dim uptmp As Integer '大きい値 Dim downtmp As Integer '入れ替え前の下の要素 Dim upsiz As Size Dim downsiz As Size Dim l1 As Integer 'ループカウンター Dim l2 As Integer 'ループカウンター 続く

回答No.9

こんばんは もうだいぶ日にちも経ちましたので、「既に時遅し」でしょうか? >お忙しいにもかかわらず、お時間を割いていただき恐縮です。 お気遣い有難うございます。 >この部分はどのように変更すればよいのでしょうか? サンプルを修正しました。わかりづらいコードですね。 既に解決済みかもしれませんが、念のために修正したサンプルを掲載します。 Button1_Clickプロシージャでしか使わないリストは、Button1_Clickプロシージャの上に移動しました。 最初から掲載しますので、3回位に分かれると思います。 「Class pictur」は変更しませんので掲載しません。 Public Class Form1 Const pn1 As Integer = 50 'Panel1に固定 Const pn11 As Integer = 100 '変更箇所 Const pn2 As Integer = 100 'Panel2に固定 Const pn3 As Integer = 150 'Panel3に固定 Dim p1 As Integer 'Panel1のカウンター Dim p2 As Integer 'Panel2のカウンター Dim p3 As Integer 'Panel3のカウンター Dim p1size As Single 'Panel1の面積 Dim p2size As Single 'Panel2の面積 Dim p3size As Single 'Panel3の面積 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Shown 'Panelサイズを設定 Panel1.Size = New Size(pn1, pn11) Panel2.Size = New Size(pn2, pn2) Panel3.Size = New Size(pn3, pn3) Dim p1clnt As Drawing.Size = Panel1.ClientSize Dim p2clnt As Drawing.Size = Panel2.ClientSize Dim p3clnt As Drawing.Size = Panel3.ClientSize p1size = p1clnt.Width * p1clnt.Height p2size = p2clnt.Width * p2clnt.Height p3size = p3clnt.Width * p3clnt.Height Panel4.AllowDrop = True End Sub Private Sub Panel1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown, Panel2.MouseDown, Panel3.MouseDown sender.DoDragDrop(sender, DragDropEffects.Move) End Sub Private Sub Panel4_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Panel4.DragDrop Dim srsPnl As Panel = e.Data.GetData(GetType(Panel)) Dim dstPnl As New Panel dstPnl.Size = srsPnl.Size Dim dropp1 As Integer = srsPnl.Size.Width * srsPnl.Size.Height If dropp1 = p1size Then p1 += 1 ElseIf dropp1 = p2size Then p2 += 1 ElseIf dropp1 = p3size Then p3 += 1 End If dstPnl.Location = Panel4.PointToClient(CursorPosition) 'New Point(e.X, e.Y) dstPnl.BackColor = srsPnl.BackColor AddHandler dstPnl.MouseDown, AddressOf dstPnl_MouseDown AddHandler dstPnl.MouseMove, AddressOf dstPnl_MouseMove Panel4.Controls.Add(dstPnl) End Sub Private Sub Panel4_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Panel4.DragEnter If e.Data.GetDataPresent(GetType(Panel)) Then e.Effect = DragDropEffects.Move End If End Sub Private previousPos As Point Private Sub dstPnl_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown previousPos = CursorPosition() End Sub Private Sub dstPnl_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) If e.Button = Windows.Forms.MouseButtons.Left Then Dim nowPos As Point = CursorPosition() DirectCast(sender, Panel).Left += nowPos.X - previousPos.X DirectCast(sender, Panel).Top += nowPos.Y - previousPos.Y Console.WriteLine(nowPos.X & "-" & previousPos.X) previousPos = nowPos End If End Sub Function CursorPosition() As Point Return New Point(CInt(Cursor.Position.X / 10) * 10, CInt(Cursor.Position.Y / 10) * 10) End Function 次に続く