0

我正在创建一个飞镖评分程序(在我的飞镖室中使用我自己),并希望用户能够单击飞镖板图片的不同区域来注册投掷的飞镖。

这个程序可以调整大小,所以当用户改变程序窗口大小时,飞镖板的图片可以改变它的大小。

我使用多边形列表(pointF-arrays)来映射每个区域并运行一些计算以查看鼠标单击是否在多边形区域内,但是当图片框调整大小时如何正确缩放这些多边形?我的多边形经过硬编码,以特定尺寸映射图片的飞镖区域。

在此处输入图像描述

编辑:在 Olivier Jacot-Descombes 给出非常出色的回答之后,我使用 GetScaledPoint 函数修复了缩放,该函数将鼠标指针 x 和 y 值转换为与原始图片大小匹配的值,从而可以轻松检查原始多边形中的命中. 如果有人感兴趣,我已经在下面的代码中编辑了解决方案。在此示例中,Picture1 是飞镖板的图片(例如http://quizmasters.biz/Pub%20Genius/Darts/Gfx/Dartboard_05.jpg),设置为 sizemode=stretch 和 docking=fill。

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 回答