Greetings, I need help with basic cloak, which counts how many times will small and big pointer on the cloak cover each other, with first one starting at 12 cloak.

I have idea of how to do it, but I can not realize it, so if you guys have some example or some tips I will be grateful.

Cloak doesnt have to be displayed in visual way, just code which counts pointers and number of times they cover each other, I believe its 11 times, but program has to show result.

Thanks in advance.

Recommended Answers

All 23 Replies

do you mean a clock that counts every time the minute hand is over the hour hand?

if so... your answer should actually be 12

Any way, just for a giggle. Here's some classic clock maths. Copy and paste this code into your form. The forms title will count the number of times the second hand goes over the minute hand. The minute hand and hour hand sweep. If you want the second hand to sweep you'll need to pass milliseconds. I've used variables instead of just equations so you can hopefully get an idea of whats going on.

Just to save even more time. to do what I think you want to do... All you need to do is increment your HandOverCounter every time the second = minute or minute = hour depending on which hand over hand you want to count.

Public Class Form1

    Dim tmr As Timer
    Dim B As Bitmap
    Dim TickOver As Integer

    Private Sub Form1_Load(sender As Object, e As EventArgs) _
    Handles MyBase.Load

        tmr = New Timer
        tmr.Interval = 1000

        AddHandler tmr.Tick, AddressOf DrawClock

        tmr.Start()
    End Sub

    Private Sub DrawClock(sender As Object, e As EventArgs)

        DrawHands(Now.Hour, Now.Minute, Now.Second)

    End Sub

    Private Sub DrawHands(HourVal As Single, MinuteVal As Single, _
    SecondVal As Single)


        Dim Pi As Single
        Dim X As Single
        Dim Y As Single

        Dim SecondAngle As Long
        Dim MinuteAngle As Long
        Dim HourAngle As Long

        'This simply increments when the second hand is over _
        the minute hand
        If SecondVal = MinuteVal Then TickOver += 1

        Dim ClockDiamiter As Single
        Dim ClockPos As Single

        ClockDiamiter = 90
        ClockPos = ClockDiamiter + 10

        B = New Bitmap(200, 200)
        Dim G As Graphics = Graphics.FromImage(B)

        Pi = 3.14159265 / 180

        'Draw The Clock Seconds Points
        For i As Integer = 0 To 360 Step 6
            X = ClockDiamiter * Math.Cos(i * Pi)
            Y = ClockDiamiter * Math.Sin(i * Pi)
            B.SetPixel(ClockPos + X, ClockPos + Y, Color.Black)
        Next i

        'Draw The Clocks Hours Points
        For i As Integer = 0 To 360 Step 30
            X = ClockDiamiter * Math.Cos(i * Pi)
            Y = ClockDiamiter * Math.Sin(i * Pi)
            G.FillRectangle(Brushes.Red, ClockPos + X - 1, _
            ClockPos + Y - 1, 2, 2)
        Next i

        'Get the angles of out hands from a degrees perspective
        SecondAngle = (360 / 60) * (SecondVal - 15)
        MinuteAngle = (360 / 60) * (MinuteVal - (15 - (1 / 60 * SecondVal)))
        HourAngle = (360 / 12) * (HourVal - (3 - (1 / 60 * MinuteVal)))

        'Draw The Hour Hand using pi
        X = (ClockDiamiter / 1.4) * Math.Cos(HourAngle * Pi)
        Y = (ClockDiamiter / 1.4) * Math.Sin(HourAngle * Pi)
        G.DrawLine(Pens.Red, ClockPos, ClockPos, ClockPos + X, _
        ClockPos + Y)

        'Draw The Minute Hands using pi
        X = ClockDiamiter * Math.Cos(MinuteAngle * Pi)
        Y = ClockDiamiter * Math.Sin(MinuteAngle * Pi)
        G.DrawLine(Pens.Blue, ClockPos, ClockPos, ClockPos + X, _
        ClockPos + Y)

        'Draw The Seconds Hand using pi
        X = ClockDiamiter * Math.Cos(SecondAngle * Pi)
        Y = ClockDiamiter * Math.Sin(SecondAngle * Pi)
        G.DrawLine(Pens.Black, ClockPos, ClockPos, ClockPos + X, _
        ClockPos + Y)

        Me.Text = TickOver

        Me.BackgroundImage = B

        G.Dispose()
        System.GC.Collect()

    End Sub


End Class

e791f8f1df68d4a36701b4d4cea9ab4d

Note: this isn't the most effective way to draw on to the form, just a quick example.

Thanks for your example, this is a bit too complicated for me, even tho you said its simple.

I can't explain drawing part and some part of the code, so that would probably get me into trouble.

I can try to get from your code, some part and use it for mine, but I still can't figure out which part of code is counting how many times small ticker which displays hours, and big ticker which displays minutes will cover each other, I assume this add 1 whenever seconds and minutes ticker is at same spot, but I need actual number 11, or 12 to be displayed. and seconds are not important in my case

'This simply increments when the second hand is over _
        the minute hand
        If SecondVal = MinuteVal Then TickOver += 1

Ok. Well if your not too fussed about the accuracy of the physical hands you could simply do

If Now.Minute = Now.Hour x 5 then OverCounter +=1

This is basically iterating every time the minute hand goes over the specific hour segment of the clock. This could be made even more accurate by only incrementing when the minute hand is on the same 60th segment as the hour hand or even more accurate over the same 360th segment.

Make sure though, if you are using Now, you covert the 24hr hour to a 12hr hour.

Alright, now its more clear to me, so I can delete graphic part? I am not sure yet, which function I will need and which one I can remove. Does now.hour and now.minute works fine without rest of the code, or I need to define max hours or something, I need only one full circle, 12 hours, and number of big and small pointer covering each other, so I need some loop, I don't need counter to go to infinity like += everytime, but for one circle only from 12 to 12

Public Class Form1
    Dim tmr As Timer
    Dim B As Bitmap
    Dim TickOver As Integer
    Private Sub Form1_Load(sender As Object, e As EventArgs) _
    Handles MyBase.Load
        tmr = New Timer
        tmr.Interval = 1000
        AddHandler tmr.Tick, AddressOf DrawClock
        tmr.Start()
    End Sub
    Private Sub DrawClock(sender As Object, e As EventArgs)
        DrawHands(Now.Hour, Now.Minute, Now.Second)
    End Sub

    If Now.Minute = Now.Hour x 5 then OverCounter +=1

Is this for a school project? If it is I'll provide you with the solution but make it into a kind of tutorial to help you understand exactly whats going on. I'll provide you with a much more basic graphical representation too if you like.

yes, for school, thanks for your help, I am really grateful

I need just numbers, graphic is just a bonus. If I can make it simple to understand and explain then why not.

Program should do just simple math, and count pointers, professor told me its 11 times they cover each other, like on 13:05, 14:10, 15:15, I think and so on from 12 AM to 12 PM, with first one starting at 12

Ok so starting at 12 isn't being counted as hands over each other... i suppose if you start at 12 and end at 12 technically they're over each other 13 times. Im sorry but 11 just isnt right, you'd have to start at 12:01 and end at 11:59 for 11 counts.

I told professor its 13 also, and he corrected me with 11,

he said first one starting at 12, so thats 1, then 13:05 is 2 and so on

Sorry its 12 if you count the the stary and end podition. Its only 11 if you dont count the start position.

Ignore previous post about it 13

I think its not that much important, as long as program is working, lets do it for 1 to be on starting point where both pointers are on 12, and then count until small pointer wich shows hours, reach 12 again, thats one circle, and program stops

Ok. Though thinking about it there is only 11. 12:00 is the start point 11:59 is the end point there are 60 minutes in an hour but they go from 0 to 59. 0 can't be the start and end of the same hour otherwise therd be 61 minutes in an hour.

I'll have the solution for yoy in a few hours.

great, thanks a lot

OK, here's the basic solution that you wanted. I have included 2 Methods. Each method provides the same results, but one is timed using a Timer (Method 2) and the other is a simple Do - Loop (Method 1).

I've included the Do-Loop so you have all the code you need in one place, however it will lock up your form.

To copy and paste this code directly you need to add a label and two buttons to your form.

Public Class Form1

    '#####################################Solution Objects
    'The Timer Object That Will Provide
    'You With A Tick
    Private ClockTimer As Timer

    'Your Clock Object That will hold the time
    Private Clock As DateTime

    'The End Time
    Private EndTime As DateTime

    'Hands Over Counter
    Private HandsOverCount As Int16
    '##################################END SOLUTION OBJECTS


    '###################THIS CODE NOT NEEDED FOR METHOD 1
    Private Sub Form1_Load(sender As Object, e As EventArgs) _
    Handles MyBase.Load

        'Initiate A New Timer
        ClockTimer = New Timer

        'Add A Handler For The Tick Event
        'Every Time The Timer Ticks It Calls the "ClockTick" Routine
        AddHandler ClockTimer.Tick, AddressOf ClockTick

    End Sub
    '###################END THIS CODE NOT NEEDED FOR METHOD 1

    '###################################METHOD 1
    'Start The Simple Do-Loop Example
    Private Sub Button2_Click(sender As Object, e As EventArgs) _
    Handles Button2.Click

        SelfContainedSample()

    End Sub

    'This is a standalone version in a loop. It will give you
    'the same results as the example above but all the elements you need
    'are in one place. Rmember though, running this directly will lock
    'up your windows form until completion.
    Private Sub SelfContainedSample()

        ClockTimer.Stop()

        HandsOverCount = 0
        Clock = New DateTime(1, 1, 1, 0, 0, 0)
        EndTime = New DateTime(1, 1, 1, 11, 59, 0)

        Do

            'If The Clock Has Reached The End Time Then Exit The loop
            If Clock = EndTime Then Exit Do

            'Iterate The Clock 1 Minute
            Clock = Clock.AddMinutes(1)

            'Check To See If The Minute Hand Is Over
            'The Hour Segment Of The Clock
            If Clock.Minute = Clock.Hour * 5 Then
                HandsOverCount += 1
            End If

            'Display The Results In A Label (Hour:Minute Hands Over:N)
            Label1.Text = Clock.Hour.ToString("00") & ":" & _
           Clock.Minute.ToString("00") & " Hands Over:" _
           & HandsOverCount.ToString("00")

            Me.Refresh()
            Threading.Thread.Sleep(10)

        Loop

    End Sub
    '###################################END METHOD 1


    '##############################################METHOD 2
    'Start Your Timer Tick Example
    Private Sub Button1_Click(sender As Object, e As EventArgs) _
    Handles Button1.Click

        'Stop The Timer If It IS Running
        ClockTimer.Stop()

        'Set The Timer's Tick Interval
        'This Value Is In MilliSeconds So If You Wanted
        '1 Tick Every Second You Would Set This To 1000
        ClockTimer.Interval = 10

        'Reset The Counter
        HandsOverCount = 0

        'Set The Clocks Start Time
        'Year,Month,Day,Hour,Minute,Second
        Clock = New DateTime(1, 1, 1, 0, 0, 0)

        'Set The Clocks End Time Time
        'Year,Month,Day,Hour,Minute,Second
        EndTime = New DateTime(1, 1, 1, 11, 59, 0)

        'What is important to note here is that the time runs from 00:00 to 11:59
        'I think what your professor is tryning to demonstrate here is how things
        'like arrays work. You may create an array with 10 elements but their
        'indexes wont be from 1 to 10, they are from 0 to 9. Much like this
        'clock scenario. If we allowed this routine to run from 00:00 to 12:00
        'You would actually be incorrect. As with a clock you wouldn't start from 1
        'and go through to 12 you wouldn't or can't with an array. An array with 12
        'elments runs from 0 to 11. If you try and access element 12 you will get an 
        'error

        'Start The Timer Ticking
        ClockTimer.Start()

    End Sub

    Private Sub ClockTick(sender As Object, e As EventArgs)

        'If The Clock Has Reached The End Time Then Stop
        If Clock = EndTime Then
            ClockTimer.Stop()
            Exit Sub
        End If

        'Iterate The Clock 1 Minute
        Clock = Clock.AddMinutes(1)

        'Check To See If The Minute Hand Is Over
        'The Hour Segment Of The Clock
        If Clock.Minute = Clock.Hour * 5 Then
            HandsOverCount += 1
        End If

        'Display The Results In A Label (Hour:Minute Hands Over:N)
        Label1.Text = Clock.Hour.ToString("00") & ":" & _
            Clock.Minute.ToString("00") & " Hands Over:" _
            & HandsOverCount.ToString("00")

    End Sub
    '########################################################END METHOD 2

End Class

As you can see when the routine has finished. the time is 11:59 and the count is 11

56a55136285a7b0cf522f822f7acdcb4

Nice, I think I get it now, I dont get complete code yet, but I will soon, I try program now and put comments on my language, so I can see if I can explain every part of code.

This is most important part I guess

If Clock.Minute = Clock.Hour * 5 Then
            HandsOverCount += 1

Thanks a lot for your help, I will get back to you with result

I tried selfcontained method and I have button2 and label1 and I got error in

ClockTimer.Stop()

error is: Object reference not set to an instance of an object.

or maybe thats because program locks until its finished, but do I have to wait 12 hours to finish?

second method worked great

Can you explain to me this part

'This Value Is In MilliSeconds So If You Wanted
        '1 Tick Every Second You Would Set This To 1000
        ClockTimer.Interval = 10

If I make it to count seconds, result would be same, but it will be needed longer time to finish or?

ClockTimer.Stop()

error is: Object reference not set to an instance of an object.

Apologies, delete this line of code.

'This Value Is In MilliSeconds So If You Wanted
'1 Tick Every Second You Would Set This To 1000
ClockTimer.Interval = 10

If I make it to count seconds, result would be same, but it will be needed longer time to finish or?

Again correct. This is the delay mechanism between counts for method 2 used purely to slow the incrementing down so you can see what is happening. In Method 1 the delay mechanism is the Threading.Thread.Sleep(10) where 10 is also milliseconds. If you remove this from method 1 the routine would complete before you could blink

and how program add 1 minute to clock that fast, if its in miliseconds? I used method 2, and I get result of 11 in few seconds, its improvizing 12 hours right?

and can I use Dim for variables instead of Private, because I always used dim in previous work

Yes dim will work.

OK. you need to remove the connection between the timer and the actual clock. try this.

Every time The ClockTick is called the routine is adding one minute onto the clock time.

The timer is only the frequency of "How Often Is The ClockTick Routine Called"

changing the timer interval only increases or decreases time between calls to the ClockTick routine.

The ClockTick routine counts in minutes not seconds.

So:

If we set the Timers interval to 10, every 10 milliseconds, one minute will be added to the clock.

If we set the timer interval to 1000, every second, one minute will be added to the clock.

If you wanted the clock to represent a realtime scenario you would set the Timer interval to 60000 (60 seconds). This means every minute the ClockTick routine is called and the clock minute is incremented by 1.

I get it, I thought same, 10 miliseconds are good, no one wants to wait that long to see result.

I will just change private to dim.

Thanks a lot for your help, I hope you get something from "thumbs up" and solving complete question alone

That's great to hear. My biggest piece of advice for you is remeber you have an undo button, many many undos. Don't be afraid to change and play with code and monitor the results... if you brake it, use undo.

I do get something from helping. Not only do I learn next time to be much clearer and accurate in my responses, I get satisfaction in knowing I've helped someone. Simple as that.

commented: Right on. +12
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.