I'm making an application that draws a circle when given the inputs of the Diameter and the Center Point of the Circle's X
and Y
via. a TextBox
inside a PictureBox.
When I run the application and put in a constant X and Y but slowly increase/decrease the diameter of the circle, the circle starts randomly moving in position even though the X and Y positions are constant. Sometimes, if I refresh the PictureBox
when any of the variables were not changed (X Pos, Y Pos, and Diameter), the circles moves for no reason at all even though nothing was changed...
This is code to reproduce:
These variables were already declared:
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
PictureBox
's Paint
event
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
It is worth noting that the PictureBox
is refreshed by clicking a button with the PictureBox1.Refresh()
command.
How can I fix this so that the Input of the Center Point and the X/Y values will result in a correct and constant answer every time?
EDIT:
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:
Dim beginSCircleXPos As Single Dim beginSCircleYPos As Single
Dim sCircleXPos As Single
Dim sCircleYPos As Single
Dim sCircleDiameter As Single
Dim sCenterPointX As Single
Dim sCenterPointY As Single
I didn't look too closely at your code. I still had the code that I provided to answer your previous question so I used that as a basis and just modified it as I would do it myself. I used a Timer
to repaint the PictureBox
once every second to make it a bit simpler. This is what I ended up with:
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.