## analog clock

BasicCoder2
Posts: 3586
Joined: Jan 01, 2009 7:03
Location: Australia

### analog clock

Code: Select all

`Const Pi = 4 * Atn(1)Dim Shared As Double TwoPi = 8 * Atn(1)Dim Shared As Double RtoD = 180 / Pi   ' radians * RtoD = degreesDim Shared As Double DtoR = Pi / 180   ' degrees * DtoR = radiansscreenres 500,500,32color rgb(0,0,0),rgb(255,255,255):cls  ' black ink, white paperdo    screenlock    cls    dim as double dx1,dy1,dx2,dy2    dim as double px,py    px = 250    py = 250    dim as double angle    for i as double = 0 to 360 step 360\60        angle = 180 - i        dx1 = sin(angle*DtoR)*90        dy1 = cos(angle*DtoR)*90        dx2 = sin(angle*DtoR)*99        dy2 = cos(angle*DtoR)*99        line (px+dx1,py+dy1)-(px+dx2,py+dy2),rgb(0,0,0)    next i         for i as double = 0 to 360 step 360\12        angle = 180 - i        dx1 = sin(angle*DtoR)*85        dy1 = cos(angle*DtoR)*85        dx2 = sin(angle*DtoR)*99        dy2 = cos(angle*DtoR)*99        line (px+dx1,py+dy1)-(px+dx2,py+dy2),rgb(0,0,0)    next i        for i as double = 30 to 360 step 360\12        angle = 180 - i        dx1 = sin(angle*DtoR)*75        dy1 = cos(angle*DtoR)*75        draw string (px+dx1-4,py+dy1-4), str(i/30)    next i     dim as string cTime,ampm    dim as integer hours,minutes,seconds    ctime = TIME    ampm = "AM"    hours = VAL(LEFT(ctime, 2))    IF hours > 12 THEN        ampm = "PM"        hours = hours - 12    END IF    IF hours = 0 THEN hours = 12    minutes = VAL(MID(ctime, 4, 2))    seconds = VAL(RIGHT(ctime, 2))    circle (px,py),99,rgb(0,0,0)    circle (px,py),5,rgb(0,0,0),,,,f        angle = 180-seconds*6    dx1 = sin(angle*DtoR)*90    dy1 = cos(angle*DtoR)*90    line (px,py)-(px+dx1,py+dy1),rgb(255,0,0)' second hand        angle = 180-hours*30    dx1 = sin(angle*DtoR)*50    dy1 = cos(angle*DtoR)*50    line (px,py)-(px+dx1,py+dy1),rgb(0,0,255)' hour hand         angle = 180-minutes*6    dx1 = sin(angle*DtoR)*70    dy1 = cos(angle*DtoR)*70    line (px,py)-(px+dx1,py+dy1),rgb(0,255,255)' minutes hand         locate 2,2    print hours;" : ";minutes;" : ";seconds     screenunlock        sleep 2loop until multikey(&H01)sleep`
BasicCoder2
Posts: 3586
Joined: Jan 01, 2009 7:03
Location: Australia

### Re: analog clock

This is my attempt to imitate dodicat's pendulum clock...

Code: Select all

`Const Pi = 4 * Atn(1)Dim Shared As Double TwoPi = 8 * Atn(1)Dim Shared As Double RtoD = 180 / Pi   ' radians * RtoD = degreesDim Shared As Double DtoR = Pi / 180   ' degrees * DtoR = radiansscreenres 640,500,32color rgb(0,0,0),rgb(255,255,255):cls  ' black ink, white paperdim as double dx1,dy1,dx2,dy2dim as double px,pydim as double sAngle,nAngle,angledim as double now1    do    screenlock    cls    'compute px,py position    nAngle = sin(sAngle*DtoR)*200    nAngle = nAngle\6    px = sin(nAngle*DtoR)*350+320    py = cos(nAngle*DtoR)*350+10    line (320,10)-(px,py),rgb(0,0,0)    circle (px,py),5,rgb(0,0,0)    sAngle = sAngle + 6    if sAngle = 360 then sAngle = 0            for i as double = 0 to 360 step 360\60        angle = 180 - i + nAngle        dx1 = sin(angle*DtoR)*90        dy1 = cos(angle*DtoR)*90        dx2 = sin(angle*DtoR)*99        dy2 = cos(angle*DtoR)*99        line (px+dx1,py+dy1)-(px+dx2,py+dy2),rgb(0,0,0)    next i         for i as double = 0 to 360 step 360\12        angle = 180 - i        angle = angle + nAngle        dx1 = sin(angle*DtoR)*85        dy1 = cos(angle*DtoR)*85        dx2 = sin(angle*DtoR)*99        dy2 = cos(angle*DtoR)*99        line (px+dx1,py+dy1)-(px+dx2,py+dy2),rgb(0,0,0)    next i        for i as double = 30 to 360 step 360\12        angle = 180 - i + nAngle        dx1 = sin(angle*DtoR)*75        dy1 = cos(angle*DtoR)*75        draw string (px+dx1-4,py+dy1-4), str(i/30)    next i     'get hours, minutes and seconds    dim as string cTime,ampm    dim as integer hours,minutes,seconds    ctime = TIME    ampm = "AM"    hours = VAL(LEFT(ctime, 2))    IF hours > 12 THEN        ampm = "PM"        hours = hours - 12    END IF    IF hours = 0 THEN hours = 12    minutes = VAL(MID(ctime, 4, 2))    seconds = VAL(RIGHT(ctime, 2))    circle (px,py),99,rgb(0,0,0)    circle (px,py),5,rgb(0,0,0),,,,f        'draw seconds hand    angle = 180-seconds*6 + nAngle    dx1 = sin(angle*DtoR)*90    dy1 = cos(angle*DtoR)*90    line (px,py)-(px+dx1,py+dy1),rgb(255,0,0)        'draw hours hand    angle = 180-hours*30 + nAngle    dx1 = sin(angle*DtoR)*50    dy1 = cos(angle*DtoR)*50    line (px,py)-(px+dx1,py+dy1),rgb(0,0,255)        'draw minutes hand    angle = 180-minutes*6 + nAngle    dx1 = sin(angle*DtoR)*70    dy1 = cos(angle*DtoR)*70    line (px,py)-(px+dx1,py+dy1),rgb(0,255,255)        locate 2,2    print hours;" : ";minutes;" : ";seconds; "  ";ampm    screenunlock        while timer < now1 + 0.05    wend    now1 = timer        sleep 2loop until multikey(&H01)sleep`
MrSwiss
Posts: 3604
Joined: Jun 02, 2013 9:27
Location: Switzerland

### Re: analog clock

Hello BasicCoder2,

My observations are as follows:
why Double's as loop counters (Long's do the trick, integer stepping)?
why the unnecessary divisions (waste of resources)?
the hour hand isn't moving (looks unusual at: 11:59:59 specially), it jumps (could not figure out the cause)
AMPM missing in digital time string
String formatting (digital time string)
Why the ultra short Sleep-Time?

Code: Select all

`Const Pi = 4 * Atn(1)Dim Shared As Double TwoPi = 8 * Atn(1)Dim Shared As Double RtoD = 180 / Pi   ' radians * RtoD = degreesDim Shared As Double DtoR = Pi / 180   ' degrees * DtoR = radiansscreenres 280,280,32color rgb(0,0,0),rgb(255,255,255):cls  ' black ink, white paperdo   screenlock   cls   dim as double dx1,dy1,dx2,dy2   dim as double px,py   px = 140   py = 140   dim as double angle   for i as long = 0 to 360 step 60   ' 360\60      angle = 180 - i      dx1 = sin(angle*DtoR)*90      dy1 = cos(angle*DtoR)*90      dx2 = sin(angle*DtoR)*99      dy2 = cos(angle*DtoR)*99      line (px+dx1,py+dy1)-(px+dx2,py+dy2),rgb(0,0,0)   next i      for i as long = 0 to 360 step 30   ' 360\12      angle = 180 - i      dx1 = sin(angle*DtoR)*85      dy1 = cos(angle*DtoR)*85      dx2 = sin(angle*DtoR)*99      dy2 = cos(angle*DtoR)*99      line (px+dx1,py+dy1)-(px+dx2,py+dy2),rgb(0,0,0)   next i      for i as long = 30 to 360 step 30   ' 360\12      angle = 180 - i      dx1 = sin(angle*DtoR)*75      dy1 = cos(angle*DtoR)*75      draw string (px+dx1-4,py+dy1-4), str(i/30)   next i   dim as string cTime,ampm,cHour,cMinute,cSecond   dim as integer hours,minutes,seconds   ctime = TIME   ampm = "AM"   hours = VAL(LEFT(ctime, 2))   IF hours > 12 THEN      ampm = "PM"      hours = hours - 12   END IF   IF hours = 0 THEN hours = 12   minutes = VAL(MID(ctime, 4, 2))   seconds = VAL(RIGHT(ctime, 2))   circle (px,py),99,rgb(0,0,0)   circle (px,py),3,RGB(0,0,0),,,,f   ' Begin - Time string formating   If hours < 10 then      cHour = " "+str(hours)   Else      cHour = str(hours)   EndIf   If minutes < 10 then      cMinute = "0"+str(minutes)   Else      cMinute = str(minutes)   EndIf   If seconds < 10 then      cSecond = "0"+str(seconds)   Else      cSecond = str(seconds)   EndIf   ' End - Time string formating   angle = 180-seconds*6   dx1 = sin(angle*DtoR)*90   dy1 = cos(angle*DtoR)*90   line (px,py)-(px+dx1,py+dy1),rgb(255,0,0)' second hand   angle = 180-hours*30   dx1 = sin(angle*DtoR)*50   dy1 = cos(angle*DtoR)*50   line (px,py)-(px+dx1,py+dy1),rgb(0,0,255)' hour hand      angle = 180-minutes*6   dx1 = sin(angle*DtoR)*70   dy1 = cos(angle*DtoR)*70   line (px,py)-(px+dx1,py+dy1),rgb(0,255,255)' minutes hand      locate 2,2   ' add ampm to concatenated string   print cHour+":"+cMinute+":"+cSecond+" "+ampm   screenunlock      sleep 250,1Loop until multikey(&H01)sleep `
BasicCoder2
Posts: 3586
Joined: Jan 01, 2009 7:03
Location: Australia

### Re: analog clock

@MrSwiss,

The reason for the double variables in the loop counters was because in the original program the angle variable was the loop counter which in the past caused failures if it was an integer due to the trig functions using floating point numbers. There must be some automatic type reassignment taking place with, angle = 180 - i.

As for the sleep command I have no idea why it is even needed, something to do with the program not hogging the cpu I think.
Just a pain as far as I am concerned. If I don't plonk sleep in the loop the program behaves erratically.

Didn't notice the hour hand not moving will have to check it out.

The divisions were there while I was figuring out what the value should be i just didn't change it. Also they do flag how the value is determined.

MrSwiss
Posts: 3604
Joined: Jun 02, 2013 9:27
Location: Switzerland

### Re: analog clock

@BasicCoder2,
BasicCoder2 wrote:As for the sleep command I have no idea why it is even needed, something to do with the program not hogging the cpu I think.

Yes that's correct, it's a tradeoff between freeing CPU (the aim is: as much as possible) and agility to ESC key press.
250 seems to be a good compromise (in this case).
fxm
Posts: 9927
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

### Re: analog clock

Modifying the condition of loop end to detect the click of window close button:
Loop until multikey(&H01) or inkey=chr(&HFF)+"k"
fxm
Posts: 9927
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

### Re: analog clock

Some improvements (IMHO):
- hour hand is continuously moving like that of minutes and seconds (60 steps instead of 12),
- one buffer graphic image is created containing the clock background (only the image copy is in the loop),
- [screenlock..screenunlock] is only around the graphic drawing part,
- condition of loop end modified to detect the click of window close button.

Code: Select all

`Const Pi = 4 * Atn(1)Dim Shared As Double TwoPi = 8 * Atn(1)Dim Shared As Double RtoD = 180 / Pi   ' radians * RtoD = degreesDim Shared As Double DtoR = Pi / 180   ' degrees * DtoR = radiansscreenres 280,280,32color rgb(0,0,0),rgb(255,255,255):cls  ' black ink, white paperdim as any ptr pclock = imagecreate(280,280,rgb(255,255,255),32)dim as double dx1,dy1,dx2,dy2dim as double px,pypx = 140py = 140dim as double anglefor i as long = 0 to 360 step 60    ' 360\60    angle = 180 - i    dx1 = sin(angle*DtoR)*90    dy1 = cos(angle*DtoR)*90    dx2 = sin(angle*DtoR)*99    dy2 = cos(angle*DtoR)*99    line pclock, (px+dx1,py+dy1)-(px+dx2,py+dy2),rgb(0,0,0)next ifor i as long = 0 to 360 step 30    ' 360\12    angle = 180 - i    dx1 = sin(angle*DtoR)*85    dy1 = cos(angle*DtoR)*85    dx2 = sin(angle*DtoR)*99    dy2 = cos(angle*DtoR)*99    line pclock, (px+dx1,py+dy1)-(px+dx2,py+dy2),rgb(0,0,0)next ifor i as long = 30 to 360 step 30   ' 360\12    angle = 180 - i    dx1 = sin(angle*DtoR)*75    dy1 = cos(angle*DtoR)*75    draw string pclock, (px+dx1-4,py+dy1-4), str(i/30)next icircle pclock, (px,py),99,rgb(0,0,0)circle pclock, (px,py),3,RGB(0,0,0),,,,fdo    dim as string cTime,ampm,cHour,cMinute,cSecond    dim as integer hours,minutes,seconds        ctime = TIME    ampm = "AM"    hours = VAL(LEFT(ctime, 2))    IF hours > 12 THEN        ampm = "PM"        hours = hours - 12    END IF    IF hours = 0 THEN hours = 12    minutes = VAL(MID(ctime, 4, 2))    seconds = VAL(RIGHT(ctime, 2))    ' Begin - Time string formating    If hours < 10 then        cHour = " "+str(hours)    Else        cHour = str(hours)    EndIf    If minutes < 10 then        cMinute = "0"+str(minutes)    Else        cMinute = str(minutes)    EndIf    If seconds < 10 then        cSecond = "0"+str(seconds)    Else        cSecond = str(seconds)    EndIf    ' End - Time string formating    screenlock    put (0,0),pclock,pset    angle = 180-(hours+minutes/60)*30    dx1 = sin(angle*DtoR)*50    dy1 = cos(angle*DtoR)*50    line (px,py)-(px+dx1,py+dy1),rgb(0,0,255)' hour hand       angle = 180-minutes*6    dx1 = sin(angle*DtoR)*70    dy1 = cos(angle*DtoR)*70    line (px,py)-(px+dx1,py+dy1),rgb(0,255,255)' minutes hand       angle = 180-seconds*6    dx1 = sin(angle*DtoR)*90    dy1 = cos(angle*DtoR)*90    line (px,py)-(px+dx1,py+dy1),rgb(255,0,0)' second hand    locate 2,2    ' add ampm to concatenated string    print cHour+":"+cMinute+":"+cSecond+" "+ampm        screenunlock       sleep 250,1Loop until multikey(&H01) or inkey=chr(&HFF)+"k"imagedestroy pclock`
BasicCoder2
Posts: 3586
Joined: Jan 01, 2009 7:03
Location: Australia

### Re: analog clock

fxm wrote:Some improvements (IMHO):
- hour hand is continuously moving like that of minutes and seconds (60 steps instead of 12),
- one buffer graphic image is created with the clock background (only the image copy is in the loop),
- [screenlock..screenunlock] is only around the graphic drawing part,
- condition of loop end modified to detect the click of window close button.

I did in fact use a buffer graphic image of the clock face to start with as I was interested in using a real image of a pocket watch swinging on a chain. The clock hands were also going to be actual images.

Looking at my analog clock in the kitchen the minute and hour hands do move "continuously", that is, one increment per second. The increments of the seconds hand are obvious because of the distance it moves with each click of the clock as it ratchets the gears one step at a time either by an internal pendulum or an electronic oscillator. Looking at the kitchen clock I can just make out the little jumps of the minutes hand with each larger movement of the seconds hand. The minutes hand does not suddenly jump when the seconds hand has completed its revolution.

Here is my latest draft using suggested mods:

Code: Select all

`Const Pi = 4 * Atn(1)Dim Shared As Double TwoPi = 8 * Atn(1)Dim Shared As Double RtoD = 180 / Pi   ' radians * RtoD = degreesDim Shared As Double DtoR = Pi / 180   ' degrees * DtoR = radiansscreenres 280,280,32color rgb(0,0,0),rgb(255,255,255):cls  ' black ink, white paperdim as any ptr pclock = imagecreate(280,280,rgb(255,255,255),32)dim as double dx1,dy1,dx2,dy2dim as double px,pypx = 140py = 140dim as double anglefor i as long = 30 to 360 step 30    angle = 180 - i    dx1 = sin(angle*DtoR)*75    dy1 = cos(angle*DtoR)*75    draw string pclock, (px+dx1-4,py+dy1-4), str(i/30)next ifor i as long = 0 to 360 step 6    angle = 180 - i    dx1 = sin(angle*DtoR)*92    dy1 = cos(angle*DtoR)*92    dx2 = sin(angle*DtoR)*97    dy2 = cos(angle*DtoR)*97    line pclock, (px+dx1,py+dy1)-(px+dx2,py+dy2),rgb(0,0,0)next ifor i as long = 0 to 360 step 30    angle = 180 - i    dx1 = sin(angle*DtoR)*85    dy1 = cos(angle*DtoR)*85    dx2 = sin(angle*DtoR)*99    dy2 = cos(angle*DtoR)*99    line pclock, (px+dx1,py+dy1)-(px+dx2,py+dy2),rgb(0,0,0)next icircle pclock, (px,py),97,rgb(0,0,0)circle pclock, (px,py),99,rgb(0,0,0)circle pclock, (px,py),3,RGB(0,0,0),,,,fdo    dim as string cTime,ampm,cHour,cMinute,cSecond    dim as integer hours,minutes,seconds        ctime = time    ampm = "AM"    hours = val(left(ctime, 2))    if hours > 12 then        ampm = "PM"        hours = hours - 12    end if    IF hours = 0 then hours = 12    minutes  = val(mid(ctime, 4, 2))    seconds  = val(right(ctime, 2))    ' Begin - Time string formating    If hours < 10 then        cHour = " "+str(hours)    Else        cHour = str(hours)    EndIf    If minutes < 10 then        cMinute = "0"+str(minutes)    Else        cMinute = str(minutes)    EndIf    If seconds < 10 then        cSecond = "0"+str(seconds)    Else        cSecond = str(seconds)    EndIf    ' End - Time string formating    screenlock    put (0,0),pclock,pset    angle = 180-(hours+minutes/60)*30    dx1 = sin(angle*DtoR)*50    dy1 = cos(angle*DtoR)*50    line (px,py)-(px+dx1,py+dy1),rgb(0,0,255)' hour hand       angle = 180-(minutes+seconds/60)*6    dx1 = sin(angle*DtoR)*80    dy1 = cos(angle*DtoR)*80    line (px,py)-(px+dx1,py+dy1),rgb(0,255,255)' minutes hand       angle = 180-seconds*6    dx1 = sin(angle*DtoR)*90    dy1 = cos(angle*DtoR)*90    line (px,py)-(px+dx1,py+dy1),rgb(255,0,0)' second hand    locate 2,2    ' add ampm to concatenated string    print cHour+":"+cMinute+":"+cSecond+" "+ampm        screenunlock       sleep 250,1Loop until multikey(&H01) or inkey=chr(&HFF)+"k"imagedestroy pclock`
Last edited by BasicCoder2 on Apr 14, 2015 23:03, edited 1 time in total.
MrSwiss
Posts: 3604
Joined: Jun 02, 2013 9:27
Location: Switzerland

### Re: analog clock

... there are many ways to kill a cat:

The movement of the various clock hands depends on the electrics/mechanics involved, e.g.:
The well known SBB/CFF Clock (Swiss Railroads Clock, also licensed by Apple) works the other way round:
Seconds - always (driven by sinc. motor that needs approx. 59 Sec/360°, then stops until, see below)
Minute - jump, electrical impulse=1/2 rotation on very simplistic Anker motor (takes place, to start Seconds motor again)
Hour - jump small, mechanically linked to Minutes, by gears.
Those Clocks are controlled by a master-clock that sends an impulse (48VDC) once a minute ...
My home town sports plenty of those (just without Seconds hand), at almost every Tram-/Buss- stop.
The most common size is diameter = 0.6 m (~2 feet).
I3I2UI/I0
Posts: 90
Joined: Jun 03, 2005 10:39
Location: Germany