- PR -

Region.Intersectの結果が空であるかをGraphicsオブジェクトを使わずに判断する方法

1
投稿者投稿内容
ジブ
大ベテラン
会議室デビュー日: 2005/09/22
投稿数: 135
投稿日時: 2005-10-18 11:45
こんにちは。

現在、お絵描きソフト用のクラスライブラリを作っているのですが
ヒットテストでリージョンのIntersectメソッドが使えないか検討しています。

複雑なパスを持つ描画クラスに対して、マウスで指定した四角形と交わる部分があるかの
判断にリージョンのIntersectが使えそうということで、
一応Intersectで得られたリージョンを色を変えて画面に書くことはできました。

そこで問題となるのが、ではその描画クラスは四角形と交わる部分がないということを
目で見てではなく、プログラム上で知ろうとした場合
IsEmptyメソッドが用意されているわれですが、引数にGraphicsオブジェクトを渡さなければなりません。

ヒットテストのメソッドへの引数にGraphicsオブジェクトは用意していないため
IsEmptyメソッドを使うとなると、ヒットテスト用のインタフェースの変更が必要になるため
影響範囲が広くなるので、できればGraphicsオブジェクトを使用せずに判断できないか
考えているところです。

ちょっと私が見た範囲では、うまく使えそうなものが見当たらないので
どなたかご存知な方がいらっしゃいましたら、教えてください。

もしかしたらGraphicPathオブジェクトの関連で似たようなことができればよいように思い
探してみたのですが、こちらにはIntersectに相当するようなものもなさそうでした。

よろしくお願いいたします。
ジブ
大ベテラン
会議室デビュー日: 2005/09/22
投稿数: 135
投稿日時: 2005-10-18 12:43
どうも、自分で読んでもイメージがつかめないので
簡単なサンプルを書いてみました。

フォームにピクチャーボックスを貼り付けて

コード:

    Private _linePath As New System.Drawing.drawing2d.GraphicsPath(Drawing2D.FillMode.Winding)
    Private _MyRegion As New System.Drawing.Region
    Private _AndRegion As Region
    Private _hit As Boolean

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim textsizef As SizeF
        Dim g As Graphics = PictureBox1.CreateGraphics

        _linePath.AddLines(New Point() {New Point(50, 30), New Point(140, 200), New Point(300, 100)})

        Dim linePath As System.Drawing.drawing2d.GraphicsPath = _linePath.Clone
        linePath.Widen(Pens.Black)                  'パスをアウトラインで閉じる。

        _MyRegion = New Region(linePath)

        linePath.Dispose()
    End Sub

    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        Dim g As Graphics = e.Graphics

        If _hit Then
            g.DrawPath(Pens.Tomato, _linePath)
        Else
            g.DrawPath(Pens.Black, _linePath)
        End If

        If Not _rect.IsEmpty Then
            g.DrawRectangle(Pens.LightGreen, _rect)
        End If

        If Not _AndRegion Is Nothing Then
            g.FillRegion(Brushes.Red, _AndRegion)
        End If
    End Sub

    Private _MouseDown As Boolean
    Private _StartPos As Point
    Private _rect As Rectangle

    Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
        _MouseDown = True
        _StartPos = New Point(e.X, e.Y)
        _hit = False
    End Sub

    Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        If _MouseDown Then
            _rect = New Rectangle(_StartPos.X, _StartPos.Y, e.X - _StartPos.X, e.Y - _StartPos.Y)

            If Not _AndRegion Is Nothing Then _AndRegion.Dispose()
            _AndRegion = _MyRegion.Clone
            _AndRegion.Intersect(_rect)

            PictureBox1.Invalidate()
        End If
    End Sub

    Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp

        _rect = New Rectangle(_StartPos.X, _StartPos.Y, e.X - _StartPos.X, e.Y - _StartPos.Y)

        If Not _AndRegion Is Nothing Then _AndRegion.Dispose()
        _AndRegion = _MyRegion.Clone
        _AndRegion.Intersect(_rect)

        If _AndRegion.IsEmpty(PictureBox1.CreateGraphics) Then  ' <===== ここをなんとかしたい
            _hit = False
        Else
            _hit = True
        End If

        _MouseDown = False
        _rect = Nothing
        _AndRegion.Dispose()
        _AndRegion = Nothing

        PictureBox1.Invalidate()

    End Sub



で、マウスでドラッグすると、動きが見えます。

If _AndRegion.IsEmpty(PictureBox1.CreateGraphics) Then

の部分で、Graphicsオブジェクトを使わずにすめば助かるのですが。


1

スキルアップ/キャリアアップ(JOB@IT)