首页 > 解决方案 > 在 VB.NET 中用给定的大小和 X/Y POS 绘制一个圆会产生意想不到的结果

问题描述

我正在制作一个应用程序,当给定直径和圆的中心点XY通过的输入时,它会绘制一个圆。aTextBox在 PictureBox 中。

当我运行应用程序并输入恒定的 X 和 Y 但缓慢增加/减小圆的直径时,即使 X 和 Y 的位置是恒定的,圆也会开始随机移动。有时,如果我在没有更改任何变量(X Pos、Y Pos 和 Diameter)时刷新,PictureBox即使没有任何更改,圆圈也会无缘无故移动......

这是重现的代码:

这些变量已经被声明:

    Dim beginSCircleXPos As Integer 'What the user put into as the circle's center for X
    Dim beginSCircleYPos As Integer 'What the user put into as the circle's center for y

    Dim sCircleXPos As Integer 'Top-Left point of the circle in X
    Dim sCircleYPos As Integer 'Top-Left point of the circle in Y
    Dim sCircleDiameter As Integer 'The diameter that user put into.


    Dim sCenterPointX As Integer 'Variables will be updated later
    Dim sCenterPointY As String

PictureBoxPaint事件

beginSCircleXPos = TextBox1.Text
        beginSCircleYPos = TextBox2.Text

        sCircleXPos = beginSCircleXPos - sCircleDiameter / 2
        sCircleYPos = beginSCircleYPos - sCircleDiameter / 2


        sCircleDiameter = TextBox3.Text


        Using path As New GraphicsPath
            path.AddEllipse(sCircleXPos, sCircleYPos, sCircleDiameter, sCircleDiameter)
            sCenterPointX = sCircleXPos + sCircleDiameter / 2
            sCenterPointY = sCircleYPos + sCircleDiameter / 2

            Using brush As New PathGradientBrush(path)
                brush.CenterPoint = New PointF(sCenterPointX, sCenterPointY) 
                brush.CenterColor = Color.FromArgb(0, Color.Orange)
                brush.SurroundColors = {Color.Orange}
                brush.FocusScales = PointF.Empty

                e.Graphics.FillRectangle(brush, sCircleXPos, sCircleYPos, sCircleDiameter, sCircleDiameter)
            End Using
        End Using

值得注意的PictureBox是,通过单击带有PictureBox1.Refresh()命令的按钮来刷新。

我该如何解决这个问题,以便中心点的输入和 X/Y 值每次都会产生正确且恒定的答案?

编辑:

  beginSCircleXPos = Convert.ToSingle(TextBox1.Text)
        beginSCircleYPos = Convert.ToSingle(TextBox2.Text)


        sCircleXPos = beginSCircleXPos - sCircleDiameter / 2
        sCircleYPos = beginSCircleYPos - sCircleDiameter / 2


        sCircleDiameter = Convert.ToSingle(TextBox3.Text)






        Using path As New GraphicsPath
            path.AddEllipse(sCircleXPos, sCircleYPos, sCircleDiameter, sCircleDiameter)
            sCenterPointX = sCircleXPos + sCircleDiameter / 2
            sCenterPointY = sCircleYPos + sCircleDiameter / 2

            Using brush As New PathGradientBrush(path)
                brush.CenterPoint = New PointF(sCenterPointX, sCenterPointY) 
                brush.CenterColor = Color.FromArgb(0, Color.Orange)
                brush.SurroundColors = {Color.Orange}
                brush.FocusScales = PointF.Empty

                e.Graphics.FillRectangle(brush, sCircleXPos, sCircleYPos, sCircleDiameter, sCircleDiameter)
            End Using
        End Using
    ```
Variables:

将 beginSCircleXPos 调暗为单曲 将 beginSCircleYPos 调暗为单曲

Dim sCircleXPos As Single
Dim sCircleYPos As Single
Dim sCircleDiameter As Single


Dim sCenterPointX As Single
Dim sCenterPointY As Single

标签: .netvb.netgraphics2dsystem.drawing

解决方案


我没有仔细看你的代码。我仍然有我提供的代码来回答你之前的问题,所以我以此为基础,只是像我自己做的那样修改它。我用 a每秒Timer重绘PictureBox一次以使其更简单。这就是我最终的结果:

Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
    Dim centreX As Single
    Dim centreY As Single
    Dim diameter As Single

    If Single.TryParse(TextBox1.Text, centreX) AndAlso
       Single.TryParse(TextBox2.Text, centreY) AndAlso
       Single.TryParse(TextBox3.Text, diameter) Then
        Dim radius = diameter / 2.0F
        Dim bounds As New RectangleF(centreX - radius,
                                     centreY - radius,
                                     diameter,
                                     diameter)

        Using path As New GraphicsPath
            path.AddEllipse(bounds)

            Using brush As New PathGradientBrush(path) With {.CenterPoint = New PointF(centreX, centreY),
                                                             .CenterColor = Color.FromArgb(0, Color.Orange),
                                                             .SurroundColors = {Color.Orange},
                                                             .FocusScales = PointF.Empty}
                e.Graphics.FillRectangle(brush, bounds)
            End Using
        End Using
    End If
End Sub

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    PictureBox1.Invalidate()
End Sub

It seemed to work just as expected for me. If one or more of the TextBoxes didn't contain a valid number then nothing was drawn, otherwise a graded circle was drawn where and how expected. If I set the centre coordinates and then varied the diameter, the circle that was drawn maintained a constant centre but grew and shrunk as expected.

You can obviously use a Button.Click instead of a Timer.Tick if you want.


推荐阅读