GDI +を使用してスケーラブルなベクターグラフィックを描画していますが、mousemoveでhitttestを実行する必要があります。私が見たすべての例では、変換なしでモデル空間=ワールド空間を使用しています。問題の簡単な例を次に示します。
Imports System.Drawing.Drawing2D
Public Class Form1
Private myrect As New GraphicsPath
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
' The rectangle's centre is at 30,10. Move to origin to rotate
e.Graphics.TranslateTransform(-30, -10, Drawing2D.MatrixOrder.Append)
e.Graphics.RotateTransform(45, Drawing2D.MatrixOrder.Append)
' Move it back, 50x50 away from the origin
' (80,60 because we moved -30,-10 to rotate)
e.Graphics.TranslateTransform(80, 60, Drawing2D.MatrixOrder.Append)
e.Graphics.DrawPath(New Pen(Brushes.Black, 2), myrect)
' ...loads more painting, many paths, many varying transformations
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
' Make a rectangle 60x20 with top-left corner at the origin
myrect.AddLine(0, 0, 60, 0)
myrect.AddLine(60, 0, 60, 20)
myrect.AddLine(60, 20, 0, 20)
myrect.CloseFigure()
' ...loads more shapes created here
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
' Pretend that all the drawing stuff above happened some unspecified time ago,
' in different assembly, written by a martian, in some other vile language.
' Obviously, his "e.graphics" has long since been garbage-collected.
If myrect.IsVisible(e.Location) Then
' Works when moving over the path at the origin, ignores transforms.
Debug.WriteLine("Over the rectangle at " & e.Location.ToString)
End If
End Sub
End Class
これは(マウスが赤く動く)を生成します
IsVisibleは、長方形が変換前にあった原点の近くでキックインします。
OnPaintでグラフィックスを使用していれば、それを使用して変換をヒットテストできることは知っていますが、黄金律には「グラフィックスを保存しない」と書かれています。
どんな提案でも大歓迎です。
事後分析:記録として、Vincentの回答の実装は次のとおりです。これはうまく機能します。
Imports System.Drawing.Drawing2D
Public Class Form1
Private myrect As New GraphicsPath
Private mytransform As Matrix
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
' The rectangle's centre is at 30,10. Move to origin to rotate
e.Graphics.TranslateTransform(-30, -10, Drawing2D.MatrixOrder.Append)
e.Graphics.RotateTransform(45, Drawing2D.MatrixOrder.Append)
' Move it back, 50x50 away from the origin
' (80,60 because we moved -30,-10 to rotate)
e.Graphics.TranslateTransform(80, 60, Drawing2D.MatrixOrder.Append)
e.Graphics.DrawPath(New Pen(Brushes.Black, 2), myrect)
mytransform = e.Graphics.Transform
' ...loads more painting, many paths, many varying transformations
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
' Make a rectangle 60x20 with top-left corner at the origin
myrect.AddLine(0, 0, 60, 0)
myrect.AddLine(60, 0, 60, 20)
myrect.AddLine(60, 20, 0, 20)
myrect.CloseFigure()
' ...loads more shapes created here
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
mytransform.Invert()
Dim mouseat() As Point = {e.Location}
mytransform.TransformPoints(mouseat)
If myrect.IsVisible(mouseat(0)) Then
' Works when moving over the path at the origin, ignores transforms.
Debug.WriteLine("Over the rectangle at " & e.Location.ToString)
End If
End Sub
End Class