0

ダーツ スコアリング プログラムを作成して (ダーツ ルームで自分自身を使用するため)、ユーザーがダーツ ボードの画像のさまざまな領域をクリックして、投げられたダーツを登録できるようにしたいと考えています。

このプログラムはサイズ変更可能であるため、ユーザーがプログラム ウィンドウのサイズを変更すると、ダーツ ボードの画像のサイズが変更されます。

ポリゴン (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
4

1 に答える 1

1

簡単で迅速な解決策は、ポリゴンを変更せずにマウス座標をスケーリングすることです。たとえば、0.0f と 1.0f の間のポリゴン座標を持ち、マウス座標を次のようにスケーリングできます。

xScaled As Single = e.X/DartBoardArea.Width
yScaled As Single = e.Y/DartBoardArea.Height
scaledPos As PointF = new PointF(xScaled, yScaled)
于 2011-09-29T14:59:56.367 に答える