DOBON.NET DOBON.NETプログラミング掲示板過去ログ

コントロール同士の重なり判定について

環境/言語:[win7 VB.NET .NET Framework4.0]
分類:[.NET]

お世話になります。

今回はコントロール同士の重なりの判定についてご教授いただければと思います。

今、作成しているプログラムでコントロールの重なりを判定して分岐させているのですが、重なりの判定の方法を調べて実行したところ、問題が出てきました。

1番目としてGraphicsPathのIsVisibleを利用してコントロールに含まれるすべての座標について判定していく方法を利用しましたが、判定するコントロールが大きくなると時間がすごくかかってしまうことがわかりました。

Dim myPath As New GraphicPath

myPath.AddRectangle(New Rectangle(Panel.Left, Panel.Top, Panel.Width, Panel.Height))
For intLx As Integer = Label.Left To Label.Left + Label.Width
 For intLy As Integer = Label.Top To Label.Top + Label.Height
  If myPath.IsVisible(intLx,intLy) Then
   処理
  End If
 Next
Next

2番目としてRectangleのContainsを使おうとしたのですが、こちらは完全に中に入っていないとTrueにならないので使えませんでした。

1番目の方法で解決はできているのですが、大きさによってかかる時間が変わってしまうので何かほかにいい方法がないものかと思っております。

どなたかいい方法をご存じではございませんか?
よろしくお願いします。
■No30749に返信(まるかじりさんの記事)
> コントロールの重なりを判定して分岐させているのですが
重なっていた場合に、どういう処理を行うのでしょうか?

重なっているかどうかが True/False として分かれば良いのか、それとも、
重なっていた場合はその重なっている領域を切り出して処理したいのか。


> For intLx As Integer = Label.Left To Label.Left + Label.Width
「To Label.Left + Label.Width」ではなく
「To Label.Right」で良いと思いますが、いずれにせよ、
1 ドットずつ調べる方法だと手間がかかりますね。


矩形同士のコントロールの重なり判定なら、
四辺の位置を調べれば分かるのではないでしょうか。


「A と B は重ならない」(A の右端が B の左端よりも左にある場合など)
A.Right  < B.Left   OrElse
B.Right  < A.Left   OrElse
A.Bottom < B.Top    OrElse
B.Bottom < A.Top


「A は B を内包する」(A の四辺すべてが B の四辺より外側にある場合)
A.Top  <= B.Top  AndAlso B.Bottom <= A.Bottom AndAlso
A.Left <= B.Left AndAlso B.Right  <= A.Right


「一部が重なる」(上記以外)
# 重なりあっている領域を計算で求めることもできそう。


※思いつきで書いただけなので、間違っているかも。


> 何かほかにいい方法がないものかと思っております。
試していないので良い方法かどうかは分かりませんが、あとは
Region クラスを使うというのは如何でしょう。

GraphicsPath.IsVisible だと、「点」の内包判定しかできませんが、
Region.IsVisible なら、「矩形」の内包判定もできそうです。
Control1.Bounds.IntersectsWith(Control1.Bounds)
でどうですか?

判定基準をクライアント領域のみとするなら
Bounds => ClientRectangle
とすれば良いかと思います。
返答ありがとうございます。

>魔界の仮面弁士さん
説明足らずで申し訳ありません。
T/F判定が必要でした。

>「A と B は重ならない」(A の右端が B の左端よりも左にある場合など)
こちらの方法で判定できました。
参考にさせていただきます。

>Region.IsVisible なら、「矩形」の内包判定もできそうです。
Region.IsVisibleでも実現させることができました。
こちらも参考にさせていただきます。

>shuさん
>Control1.Bounds.IntersectsWith(Control1.Bounds)
こちらの方法でも実現することができました。
参考にさせていただきます。

プログラムを始めて1年ほどですが、まだまだ知らないことがたくさんあると痛感しました。
ご教授くださった方々、ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板