アプリ版:「スタンプのみでお礼する」機能のリリースについて

VisualBasic2010において、複数のPanelを用いて任意に図形を作成さたのですが、その作成させた図形(重複はない)の面積を算出したいと考えております。


使用したPanelの面積を足し合わせて、作成した図形の面積を算出させる。
座標を取得して面積を算出させる。

このどちらかの方法で作成させた図形の面積を算出できるのではないかと思うのですが、
Panelの面積を設定するにはどのようなコードを用いたらよいのかわからず、面積を足し合わせることができない。
頂点座標の取得法がわからない。
ため面積を算出することができません。
いろいろと調べてみたのですが、わかりませんでした。

もしお時間等ありましたら、お力添えをいただけると嬉しく思います。

どうかよろしくお願いします。

「VB2010において面積の算出」の質問画像

A 回答 (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


やっぱりこれじゃダメかな~ ダメな場合はお手数ですが再度返信をお願いします。

この回答への補足

こんばんは
親切かつ丁寧な回答ありがとうございます。
まさに私がやりたいと思っていたことですが、

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
この部分はどのように置き換えたらよいでしょうか?
丸投げで大変申し訳ないのですが、お力添えをいただけると嬉しく思います。
どうかよろしくお願いいたします。

補足日時:2012/09/30 00:52
    • good
    • 0

横入り失礼します。



#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
の変更も忘れずに。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
おかげで問題を解決することができました。
BAではなくすみません。

お礼日時:2012/10/01 03:07

こんばんは、お返事ありがとうございます。




全文を拝見させて頂きました。


>Panel1,Panel2,Panel3のサイズを任意に決めることが出来るのではないかと考えたのですが、不可能なのでしょうか?
さすがですね、私には考えつきませんでした。
よ~く考えると(本当はあまり考えてません)Panelはデザイナー画面で貼り付けると思いますので、可能かもしれません。
但し、大きさが小さいのでその問題をどのように解決するかだと思います。
面積が大きければ、ある程度、例えばp3size =50位あればいいのですが。


問題は、今日から金曜日の夜までPCに触る機会がありませんので、本格的に考えるのは来週になってしまいます。
おそらくここまで、情報が揃いましたので、他の方が良い回答をしてくださると思います。
その前に、TMYMSさんがご自分で解決できそうですね。


万が一解決されていませんでしたら、またお会いできますね。



そのようなわけで大変申し訳ありませんが、しばらくTMYMSさんとお話ができません(残念
    • good
    • 0
この回答へのお礼

また質問をさせていただくことがあるかもしれません。その時はよろしくお願いいたします。

お礼日時:2012/10/01 03:10

お返事ありがとうございます。




少々問題がありまして(私の読解力不足)再度情報を頂けないでしょうか。


問題点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のサイズを任意に決めることが出来るのではないかと考えたのですが、不可能なのでしょうか?

補足日時:2012/09/30 17:10
    • good
    • 0

こんばんは




補足情報ありがとうございます。
今まで外出中で、PCをやっと起動しました。
返信の時間を見ましたら、「あらびっくり!」、あまりの返信の速さで慌てて回答してます。


思いつきで回答してますので、あまり当てになりませんが、ザ~っとコードを見ましたところ、この場合はカウンター処理ではダメでしょうか?

こんな安易なことではダメですよね。


それと、表示はMsgBoxにするのでしょうか?
それともlabel?
それとも?


すいません、少しずつ詰めて行けば、何とかなりそうですね、他の方も良い回答をしてくださると思います。
    • good
    • 0

こんにちは




ご質問の内容からすると、単純な問題ではないですね。

とりあえず、単純な例のサンプルを掲載しますので、どこがどのように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すべての面積を出したいです。

補足日時:2012/09/29 15:54
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!