Const CLEARANCE As Integer = 10
Const MIN_DIAMETER As Integer = 50
Const DEGREES_PER_HOUR As Integer = 30
Const DEGREES_PER_MINUTE As Integer = 6
Const DEGREES_PER_SECOND As Integer = 6
Private ReadOnly hourPen As Pen = Pens.Black
Private ReadOnly minutePen As Pen = Pens.Blue
Private ReadOnly secondPen As Pen = Pens.Red
Private Function GetHourAngle(currentTime As Date) As Single
Return (currentTime.Hour Mod 12 + (currentTime.Minute + CSng(currentTime.Second / 60)) / 60) * DEGREES_PER_HOUR
End Function
Private Function GetMinuteAngle(currentTime As Date) As Single
Return (currentTime.Minute + CSng(currentTime.Second / 60)) * DEGREES_PER_MINUTE
End Function
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
Dim diameter = Math.Max(MIN_DIAMETER,
Math.Min(PictureBox1.Width,
PictureBox1.Height) - 2 * CLEARANCE)
'Ensure that the diameter is an odd number so there is a definite centre.
diameter = If(diameter Mod 2 = 0, diameter + 1, diameter)
With e.Graphics
'Draw the clock outline.
.DrawEllipse(Pens.Black, CLEARANCE, CLEARANCE, diameter, diameter)
'Shift the origin to the centre of the circle to make it easy to draw radial lines.
.TranslateTransform(CLEARANCE + diameter \ 2 + 1, CLEARANCE + diameter \ 2 + 1)
'Draw the hour and minute increments.
For a = DEGREES_PER_MINUTE To 360 Step DEGREES_PER_MINUTE
.RotateTransform(DEGREES_PER_MINUTE)
If a Mod DEGREES_PER_HOUR = 0 Then
'Hour markers are the length of the clearance.
.DrawLine(hourPen, 0, CLEARANCE - diameter \ 2, 0, -diameter \ 2)
Else
'Minute markers are the half the length of the clearance.
.DrawLine(minutePen, 0, (CLEARANCE - diameter) \ 2, 0, -diameter \ 2)
End If
Next
Dim currentTime = Date.Now
Dim hourAngle = GetHourAngle(currentTime)
Dim minuteAngle = GetMinuteAngle(currentTime)
Dim secondAngle = currentTime.Second * DEGREES_PER_SECOND
Dim fullHandLength = diameter \ 2 - CLEARANCE
'The hands are drawn vertically upward in relation to the transformed coordinate system so the Y coordinate of the end-point is negative.
'Draw the minute hand first.
.RotateTransform(minuteAngle)
.DrawLine(minutePen, 0, 0, 0, -fullHandLength)
.RotateTransform(-minuteAngle)
'Draw the hour hand over the minute hand.
.RotateTransform(hourAngle)
.DrawLine(hourPen, 0, 0, 0, -fullHandLength \ 2)
.RotateTransform(-hourAngle)
'Draw the second hand over all others.
.RotateTransform(secondAngle)
.DrawLine(secondPen, 0, 0, 0, -fullHandLength)
.RotateTransform(-secondAngle)
End With
End Sub
Private Sub PictureBox1_SizeChanged(sender As Object, e As EventArgs) Handles PictureBox1.SizeChanged
PictureBox1.Invalidate()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
PictureBox1.Invalidate()
End Sub