- ベストアンサー
VB2010で図形の面積を算出する方法
- VisualBasic2010のPanelを使用して図形を作成し、その面積を算出する方法について調査しました。
- Panelの面積を設定する方法や頂点座標の取得法について調べた結果、情報が見つかりませんでした。
- 図形の面積を算出するためには別の方法を検討する必要があります。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
こんばんは とりあえずカウンターの方法で、対策してみました。 但し、こんな方法ではダメですよね。? >使用したPanelの面積を足し合わせて、作成した図形の面積を算出させる。 >図形(重複はない) の条件です。 Buttonを追加してClickイベントで取得しています。 Public Class Form1 Dim p1 As Integer 'Panel1のカウンター Dim p2 As Integer 'Panel2のカウンター Dim p3 As Integer 'Panel3のカウンター Dim p1size As Integer 'Panel1の面積 Dim p2size As Integer 'Panel2の面積 Dim p3size As Integer 'Panel3の面積 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Shown 'GroupBoxにあるPanelの面積を求める 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 Panel1.DoDragDrop(Panel1, DragDropEffects.Move) End Sub Private Sub Panel2_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel2.MouseDown Panel2.DoDragDrop(Panel2, DragDropEffects.Move) End Sub Private Sub Panel3_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel3.MouseDown Panel3.DoDragDrop(Panel3, 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 'eで取得した値から面積を求める Dim dropp1 As Integer = srsPnl.Size.Width * srsPnl.Size.Height 'GroupBoxにあるPanelの面積とeで取得した値から求めた面積を比較 If dropp1 = p1size Then p1 += 1 'Panelと比較した結果 ElseIf dropp1 = p2size Then p2 += 1 'Pane2と比較した結果 ElseIf dropp1 = p3size Then p3 += 1 'Pane3と比較した結果 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(sender As System.Object, e As System.EventArgs) Handles Button1.Click Dim ans As Integer ans = p1 * p1size + p2 * p2size + p3 * p3size MsgBox("Panel1は " & p1 & " 枚です。" & vbNewLine & "Panel2は " & p2 & " 枚です。" & vbNewLine & "Panel3は " & p3 & " 枚です。" & vbNewLine & "総面積は " & ans & " です。") End Sub End Class やっぱりこれじゃダメかな~ ダメな場合はお手数ですが再度返信をお願いします。
その他の回答 (5)
- nag0720
- ベストアンサー率58% (1093/1860)
横入り失礼します。 #3さんのコードでは、面積でどのパネルをドロップしたかを判断していますので、画面上の面積を正しく計算する必要があります。 これを、面積ではなくて直接パネルそのもので判断すれば、面積の計算は不要になります。 つまり、 'eで取得した値から面積を求める Dim dropp1 As Integer = srsPnl.Size.Width * srsPnl.Size.Height 'GroupBoxにあるPanelの面積とeで取得した値から求めた面積を比較 If dropp1 = p1size Then p1 += 1 'Panelと比較した結果 ElseIf dropp1 = p2size Then p2 += 1 'Pane2と比較した結果 ElseIf dropp1 = p3size Then p3 += 1 'Pane3と比較した結果 End If この部分を、つぎのように変更します。 If srsPnl Is Panel1 Then p1 += 1 ElseIf srsPnl Is Panel2 Then p2 += 1 ElseIf srsPnl Is Panel3 Then p3 += 1 End If こうしておけば、 Dim p1size As Single 'Panel1の面積 Dim p2size As Single 'Panel2の面積 Dim p3size As Single 'Panel3の面積 Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load p1size = 2.5 p2size = 5 p3size = 10 Panel4.AllowDrop = True End Sub というように、p1size,p2size,p3sizeを自由に設定しても問題ありません。 (グローバル変数にせずに、結果を表示するときに設定してもいいでしょう) Dim ans As Single の変更も忘れずに。
お礼
回答ありがとうございます。 おかげで問題を解決することができました。 BAではなくすみません。
- 田中 裕之(@bybalsendercase)
- ベストアンサー率88% (56/63)
こんばんは、お返事ありがとうございます。 全文を拝見させて頂きました。 >Panel1,Panel2,Panel3のサイズを任意に決めることが出来るのではないかと考えたのですが、不可能なのでしょうか? さすがですね、私には考えつきませんでした。 よ~く考えると(本当はあまり考えてません)Panelはデザイナー画面で貼り付けると思いますので、可能かもしれません。 但し、大きさが小さいのでその問題をどのように解決するかだと思います。 面積が大きければ、ある程度、例えばp3size =50位あればいいのですが。 問題は、今日から金曜日の夜までPCに触る機会がありませんので、本格的に考えるのは来週になってしまいます。 おそらくここまで、情報が揃いましたので、他の方が良い回答をしてくださると思います。 その前に、TMYMSさんがご自分で解決できそうですね。 万が一解決されていませんでしたら、またお会いできますね。 そのようなわけで大変申し訳ありませんが、しばらくTMYMSさんとお話ができません(残念
お礼
また質問をさせていただくことがあるかもしれません。その時はよろしくお願いいたします。
- 田中 裕之(@bybalsendercase)
- ベストアンサー率88% (56/63)
お返事ありがとうございます。 少々問題がありまして(私の読解力不足)再度情報を頂けないでしょうか。 問題点1 >p1size =2.5 これですと、多分少数点になりますね。 p1sizeは四角の面積ですので、p1size=縦×横 の計算式になると思います。 例えば、p1size =2.5にするには、縦が1とすると、横は2.5になりますね。 Panelをデザイナー画面でSize変更する場合は、おそらくピクセル数で変更すると思いますので(詳しいことはわかりません) 縦の1は問題ありませんが、横の2.5はエラーになると思います。 また、プログラムで Panel1.Size = New Size(2.5, 1) としても、少数点はRoundが動作して2.5は2に変換されてしまうと思います。 問題点2 >p1size =2.5 >p2size =5 >p3size =10 上記のサイズですと、図形が小さくて見えなくなってしまいます。 もしかして、センチメートルのことでしょうか? 画面上私のPCの設定では、ピクセル数を4倍するとほぼ指定した大きさになりますが、PCの画像設定は各々違いますので画面上で正確に実寸にするには、少々時間がひつようです。 どこかのサイトに詳しく解説されていると思いますが、現状ではURLがわかりません。 問題点3 問題点1でも触れましたが、四角の面積は縦と横の数値が必要ですので、縦もしくは横のどちらか一方を決定しなければ p1size =2.5、p2size =5、p3size =10を算出できませんので、縦もしくは横のどちらか一方を決めて頂けないでしょうか? Panelの表示もできないと思います。(ここが1番重要ですね、Panelを貼り付けると必ず、縦と横の数値が決定されますね) 例 Panel1.Size = New Size(x, 1) Yは1で決定されてますので、Xは面積から求めることができます。 Panel1.Size = New Size(x, Y) XとYが両方わからない場合は、Panel1のSizeは決定できませんね。 私の文章の書き方が悪いですから、わかりづらいと思いますが出来る範囲で結構ですので情報を頂けるとうれしいです。
補足
回答ありがとうございます。 初めに回答して頂いたコードを Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click '各Panelの幅と高さを取得 Dim psize1 As Drawing.Size = Panel1.ClientSize Dim psize2 As Drawing.Size = Panel2.ClientSize Dim psize3 As Drawing.Size = Panel3.ClientSize Dim ans1 As Single 'Panel1の面積 Dim ans2 As Single 'Panel2の面積 Dim ans3 As Single 'Panel3の面積 Dim total As Single '各Panelの面積の合計 ans1 = 2.5 ans2 = 5 ans3 = 10 total = ans1 + ans2 + ans3 MsgBox.Show("面積は " & total & " です。") End Sub End Class と書き換えるとtotalが17.5と表示され 'eで取得した値から面積を求める Dim dropp1 As Integer = srsPnl.Size.Width * srsPnl.Size.Height 'GroupBoxにあるPanelの面積とeで取得した値から求めた面積を比較 If dropp1 = p1size Then p1 += 1 'Panelと比較した結果 ElseIf dropp1 = p2size Then p2 += 1 'Pane2と比較した結果 ElseIf dropp1 = p3size Then p3 += 1 'Pane3と比較した結果 End If のDim dropp1 As Integer = srsPnl.Size.Width * srsPnl.Size.Heightを Dim dropp1 As single = 2.5と置き換え、 p1size = 2.5 p2size = 5 p3size = 10とした場合 Panel4にDragDropされたすべてのPanelのサイズが2となり、Panel1,Panel2,Panel3をそれぞれ一つずつPanel4へ移動した場合、 Panel1は 3 枚です。 Panel2は 0 枚です。 Panel3は 0 枚です。 総面積は 7.5 です。 と表示されるため、Panel1,Panel2,Panel3のサイズを任意に決めることが出来るのではないかと考えたのですが、不可能なのでしょうか?
- 田中 裕之(@bybalsendercase)
- ベストアンサー率88% (56/63)
こんばんは 補足情報ありがとうございます。 今まで外出中で、PCをやっと起動しました。 返信の時間を見ましたら、「あらびっくり!」、あまりの返信の速さで慌てて回答してます。 思いつきで回答してますので、あまり当てになりませんが、ザ~っとコードを見ましたところ、この場合はカウンター処理ではダメでしょうか? こんな安易なことではダメですよね。 それと、表示はMsgBoxにするのでしょうか? それともlabel? それとも? すいません、少しずつ詰めて行けば、何とかなりそうですね、他の方も良い回答をしてくださると思います。
- 田中 裕之(@bybalsendercase)
- ベストアンサー率88% (56/63)
こんにちは ご質問の内容からすると、単純な問題ではないですね。 とりあえず、単純な例のサンプルを掲載しますので、どこがどのようにTMYMSさんの目的と違うのか教えていただけると、嬉しいです。 また、他の方が回答するヒントになると思います。 >使用したPanelの面積を足し合わせて、作成した図形の面積を算出させる。 こちらの方法で作成しました。 Public Class Form1 Private Sub f1() Handles MyBase.Shown '各Panelの幅と高さを取得 Dim psize1 As Drawing.Size = Panel1.ClientSize Dim psize2 As Drawing.Size = Panel2.ClientSize Dim psize3 As Drawing.Size = Panel3.ClientSize Dim ans1 As Integer 'Panel1の面積 Dim ans2 As Integer 'Panel2の面積 Dim ans3 As Integer 'Panel3の面積 Dim total As Integer '各Panelの面積の合計 ans1 = psize1.Width * psize1.Height ans2 = psize2.Width * psize2.Height ans3 = psize3.Width * psize3.Height total = ans1 + ans2 + ans3 MsgBox("面積は " & total & " です。") End Sub End Class 情報、よろしくお願いします。
補足
回答ありがとうございます。 画像では、Panel1,Panel2,Panel3を一つずつ用いて図形を作成しておりますが 実際は Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Panel4.AllowDrop = True End Sub Private Sub Panel1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown Panel1.DoDragDrop(Panel1, DragDropEffects.Move) End Sub Private Sub Panel2_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel2.MouseDown Panel2.DoDragDrop(Panel2, DragDropEffects.Move) End Sub Private Sub Panel3_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel3.MouseDown Panel3.DoDragDrop(Panel3, 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 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 とコードを書いており、任意に図形を作成することができるようになっています。よって組み合わせは無限にあるのです。 Panel4上にあるPanel1,Panel2,Panel3すべての面積を出したいです。
補足
こんばんは 親切かつ丁寧な回答ありがとうございます。 まさに私がやりたいと思っていたことですが、 p1size = p1clnt.Width * p1clnt.Height p2size = p2clnt.Width * p2clnt.Height p3size = p3clnt.Width * p3clnt.Height を p1size =2.5 p2size =5 p3size =10 というように変えたいです。 Dim X As IntegerをDim X As Single と置き換えれば可能なのですが、 'eで取得した値から面積を求める Dim dropp1 As Integer = srsPnl.Size.Width * srsPnl.Size.Height 'GroupBoxにあるPanelの面積とeで取得した値から求めた面積を比較 If dropp1 = p1size Then p1 += 1 'Panelと比較した結果 ElseIf dropp1 = p2size Then p2 += 1 'Pane2と比較した結果 ElseIf dropp1 = p3size Then p3 += 1 'Pane3と比較した結果 End If この部分はどのように置き換えたらよいでしょうか? 丸投げで大変申し訳ないのですが、お力添えをいただけると嬉しく思います。 どうかよろしくお願いいたします。