ダーツ スコアリング プログラムを作成して (ダーツ ルームで自分自身を使用するため)、ユーザーがダーツ ボードの画像のさまざまな領域をクリックして、投げられたダーツを登録できるようにしたいと考えています。
このプログラムはサイズ変更可能であるため、ユーザーがプログラム ウィンドウのサイズを変更すると、ダーツ ボードの画像のサイズが変更されます。
ポリゴン (pointF-arrays) のリストを使用して各領域をマップし、計算を実行してマウス クリックがポリゴン領域内にあるかどうかを確認しますが、ピクチャ ボックスのサイズが変更されたときにこれらのポリゴンを正しくスケーリングするにはどうすればよいですか? 私のポリゴンは、特定のサイズで画像のダーツボード領域をマッピングするようにハードコーディングされています。
編集: Olivier Jacot-Descombes からの非常に素晴らしい回答の後、マウスポインターの x 値と y 値を元の画像サイズに一致する値に変換する GetScaledPoint 関数を使用してスケーリングを修正し、元のポリゴンのヒットを簡単に確認できるようにしました。 . 誰かが興味を持っている場合は、以下のコードのソリューションを編集しました。この例では、Picture1 は、sizemode=stretch および docking=fill に設定されたダーツ ボード (このようなhttp://quizmasters.biz/Pub%20Genius/Darts/Gfx/Dartboard_05.jpg ) の写真です。
Public Class DartBoard
Dim Double20 = New PointF() {New PointF(263, 78), New PointF(275, 76), New PointF(284, 76), New PointF(293, 75), New PointF(306, 75), New PointF(319, 75), New PointF(332, 76), New PointF(330, 89), New PointF(320, 88), New PointF(309, 87), New PointF(300, 87), New PointF(289, 88), New PointF(277, 89), New PointF(267, 91), New PointF(264, 78)}
Dim Triple20 = New PointF() {New PointF(279, 154), New PointF(285, 154), New PointF(293, 154), New PointF(301, 152), New PointF(306, 152), New PointF(312, 152), New PointF(314, 151), New PointF(322, 152), New PointF(320, 167), New PointF(312, 165), New PointF(304, 164), New PointF(297, 165), New PointF(289, 166), New PointF(281, 166), New PointF(277, 154), New PointF(283, 153), New PointF(291, 153), New PointF(299, 152), New PointF(308, 152), New PointF(314, 153), New PointF(322, 153)}
Private startwidth As Integer = 0
Private startheight As Integer = 0
Public Structure DartBoardAreaStruct
Public Points As Integer
Public Area() As PointF
End Structure
Dim DartBoardAreas As New List(Of DartBoardAreaStruct)
Private Sub DartBoard_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
DartBoardAreas.Add(New DartBoardAreaStruct With {.Area = Double20, .Points = 40})
DartBoardAreas.Add(New DartBoardAreaStruct With {.Area = Triple20, .Points = 60})
startwidth = PictureBox1.Width
startheight = PictureBox1.Height
End Sub
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
Dim scaledpos As PointF = GetScaledPoint(e.Location)
For Each DartBoardArea In DartBoardAreas
If Me.PolyGonHitTest(DartBoardArea.Area, scaledpos) Then
MsgBox(DartBoardArea.Points)
End If
Next
End Sub
Public Function PolyGonHitTest(ByVal polygonPoints() As PointF, ByVal mousePos As PointF) As Boolean
Dim path As New System.Drawing.Drawing2D.GraphicsPath
path.AddLines(polygonPoints)
Dim region As New Region(path)
If region.IsVisible(mousePos) Then Return True
Return False
End Function
Function GetScaledPoint(ByVal s As Point) As PointF
Dim xfactor As Double = 0
Dim yfactor As Double = 0
Dim OriginalSize As Size = New Size(startwidth, startheight)
Dim NewSize As Size = New Size(PictureBox1.Width, PictureBox1.Height)
If NewSize.Width < OriginalSize.Width Then
xfactor = OriginalSize.Width / NewSize.Width
Else
xfactor = NewSize.Width / OriginalSize.Width
End If
If NewSize.Height < OriginalSize.Height Then
yfactor = OriginalSize.Height / NewSize.Height
Else
yfactor = NewSize.Height / OriginalSize.Height
End If
Return New PointF(s.X / xfactor, s.Y / yfactor)
End Function
End Class