Author Topic: Analog Clock  (Read 5358 times)

0 Members and 1 Guest are viewing this topic.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Analog Clock
« on: June 21, 2019, 03:37:50 pm »
Hi all,

I just made this analog clock today. I've wanted to make one for around 30 years and could never figure it out. So today I found an old QBasic version I had from probably the 1990's or so so I tried to research that a bit again. It was from a guy named Chris Procter who put it online back then. So I simplified the code a lot and updated it using the QB64 _DELAY command. Thank you Chris, wherever you are, for these math equations! I put it on my website, but here is the code below as well. If you wish to see other programs I've made, my website is here: http://ken.x10host.com/qb64/

So here it is, my brand new shiny analog clock that after 30 years I finally could make:

Code: QB64: [Select]
  1. 'This is my first analog clock!
  2. 'Thank you to someone named Chris Procter who put a QBasic clock online around 20 years ago or so.
  3. 'I used some of his math to make this clock.
  4. 'This clock was updated and simplified a lot using the QB64 _DELAY command.
  5. 'This was made by Ken G. and is freeware.
  6. _TITLE "Analog Clock"
  7. CIRCLE (325, 225), 182, 15
  8. go:
  9. _LIMIT 500
  10. hours = TIMER \ 3600
  11. minutes = TIMER \ 60 - hours * 60
  12. seconds = (TIMER - hours * 3600 - minutes * 60)
  13. 'Seconds
  14. s = (60 - seconds) * 6 + 180
  15. LINE (325, 225)-(x, y), 0
  16. x = INT(SIN(s / 180 * 3.141592) * 180) + 325
  17. y = INT(COS(s / 180 * 3.141592) * 180) + 225
  18. LINE (325, 225)-(x, y), 15
  19. 'Minutes
  20. m = 180 - minutes * 6
  21. LINE (325, 225)-(xx, yy), 0
  22. xx = INT(SIN(m / 180 * 3.141592) * 180) + 325
  23. yy = INT(COS(m / 180 * 3.141592) * 180) + 225
  24. LINE (325, 225)-(xx, yy), 15
  25. 'Hours
  26. h = 360 - hours * 30 + 180
  27. LINE (325, 225)-(xxx, yyy), 0
  28. xxx = INT(SIN(h / 180 * 3.141592) * 100) + 325
  29. yyy = INT(COS(h / 180 * 3.141592) * 100) + 225
  30. LINE (325, 225)-(xxx, yyy), 15
  31. GOTO go:
  32.  
  33.  

« Last Edit: June 21, 2019, 04:17:17 pm by SierraKen »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Analog Clock
« Reply #1 on: June 21, 2019, 04:52:14 pm »
Here's the same clock as yours, Ken, except I've modified it to use a SUB to draw the hands for us.  I've noticed you don't make use of SUB/FUNCTIONs in your code much, so I thought I'd take a moment and help highlight the difference for you, so you can see how much more efficient your coding can become, once you get used to using them in your projects.

Code: QB64: [Select]
  1. _TITLE "Analog Clock"
  2.  
  3.     CLS
  4.     CIRCLE (325, 225), 182, 15
  5.     _LIMIT 1
  6.     hours = TIMER \ 3600
  7.     minutes = TIMER \ 60 - hours * 60
  8.     seconds = (TIMER - hours * 3600 - minutes * 60)
  9.     DrawHand (60 - seconds) * 6 + 180, 180 'Second hand
  10.     DrawHand 180 - minutes * 6, 180 'Minute hand
  11.     DrawHand 360 - hours * 30 + 180, 100 'Hour hand
  12.     _DISPLAY
  13.  
  14. SUB DrawHand (value, scale)
  15.     X = INT(SIN(value / 180 * 3.141592) * scale) + 325
  16.     Y = INT(COS(value / 180 * 3.141592) * scale) + 225
  17.     LINE (325, 225)-(X, Y), 15
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Analog Clock
« Reply #2 on: June 21, 2019, 05:54:50 pm »
Wow Ron that's incredible! I like how you did all the lines. I don't really understand the math part but I may update my clock someday.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Analog Clock
« Reply #3 on: June 21, 2019, 06:03:06 pm »
SMcNeill, that is really amazing. I was never taught SUB's because I took the old BASIC programming classes in the 1980's and they didn't have those back then. That was back when each line was numbered as well lol. In 1995 some people on comp.lang.basic.misc newsgroup taught me the difference between those and QBasic and I took it from there. I've seen many SUB's over the years but I only vaguely understand them. I've always thought they were kinda like GOSUB/RETURN's or GOTO's. But just a tiny bit. Every time I program I work from top to bottom or in paths that the computer would read. That is why I never really got past BASIC languages, because they are not structured really in paths but more in "all of this happens at once" or something. lol But what I can tell about SUB's are that they are lines of code that can be called up in other places in the program when needed. I suppose that can be handy when a program needs the same code more than once and doesn't have to use IF/THEN's using variables to figure out when code is needed. I might learn it someday, thanks.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Analog Clock
« Reply #4 on: June 21, 2019, 06:25:58 pm »
Ken — you’ve been using SUBs and FUNCTIONs since the first time you started programming back in 95.  ;)

All a SUB is, is a basic routine which you decide you need to repeat multiple times in your code.

In your original, you use several in-built SUBs — CLS, CIRCLE, LINE, _LIMIT, _DELAY.

CLS is basically just a routine which clears the screen.  Circle just draws a circle where you specify.  You could write your own routines and do the exact same things, if you wanted to — and that’s all a SUB is.

For example:

Code: QB64: [Select]

And, to do the same with your own SUB:

Code: QB64: [Select]
  1. FOR I = 1 TO 10
  2. ClearScreen
  3.  
  4. SUB ClearScreen
  5. LOCATE 1,1 ‘start at the very top corner
  6. FOR I = 1 TO 100
  7. PRINT SPACE$(_WIDTH)print enough blank lines to erase the screen
  8. LOCATE 1,1 ‘move the print position back to the top left corner
  9.  

SUBs basically just say, “Repeat this process when needed”, while allowing the programmer the flexibility to customize their own routines and easily move them into other programs as needed.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Analog Clock
« Reply #5 on: June 21, 2019, 07:47:36 pm »
WOW that is so cool, thanks! I will try it soon.

I just improved the looks of my clock, I experimented with the math and made little circles all around the clock and also made it look better.

Code: QB64: [Select]
  1. 'This is my first analog clock!
  2. 'Thank you to someone named Chris Procter who put a QBasic clock online around 20 years ago or so.
  3. 'I used some of his math to make this clock.
  4. 'This clock was updated and simplified a lot using the QB64 _DELAY command.
  5. 'This was made by Ken G. and is freeware.
  6. _TITLE "Analog Clock"
  7. CIRCLE (327, 225), 184, 15
  8. CIRCLE (325, 225), 215, 15
  9. LOCATE 2, 41: PRINT "12"
  10. LOCATE 15, 16: PRINT "9"
  11. LOCATE 15, 66: PRINT "3"
  12. LOCATE 27, 41: PRINT "6"
  13. go:
  14. _LIMIT 500
  15. FOR sc = 1 TO 60
  16.     ss = (60 - sc) * 6 + 180
  17.     x2 = INT(SIN(ss / 180 * 3.141592) * 180) + 5
  18.     y2 = INT(COS(ss / 180 * 3.141592) * 180) + 5
  19.     x2 = x2 + 323
  20.     y2 = y2 + 220
  21.     CIRCLE (x2, y2), 3, 15
  22. NEXT sc
  23. hours = TIMER \ 3600
  24. minutes = TIMER \ 60 - hours * 60
  25. seconds = (TIMER - hours * 3600 - minutes * 60)
  26. 'Seconds
  27. s = (60 - seconds) * 6 + 180
  28. LINE (325, 225)-(x, y), 0
  29. x = INT(SIN(s / 180 * 3.141592) * 180) + 325
  30. y = INT(COS(s / 180 * 3.141592) * 180) + 225
  31. LINE (325, 225)-(x, y), 15
  32. 'Minutes
  33. m = 180 - minutes * 6
  34. LINE (325, 225)-(xx, yy), 0
  35. xx = INT(SIN(m / 180 * 3.141592) * 180) + 325
  36. yy = INT(COS(m / 180 * 3.141592) * 180) + 225
  37. LINE (325, 225)-(xx, yy), 15
  38. 'Hours
  39. h = 360 - hours * 30 + 180
  40. LINE (325, 225)-(xxx, yyy), 0
  41. xxx = INT(SIN(h / 180 * 3.141592) * 100) + 325
  42. yyy = INT(COS(h / 180 * 3.141592) * 100) + 225
  43. LINE (325, 225)-(xxx, yyy), 15
  44. GOTO go:
  45.  

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Analog Clock
« Reply #6 on: June 21, 2019, 11:27:34 pm »
Note: Anyone that got my Alarm Clock on the evening of Friday, June 22 or morning of June 23 please delete it. It had 1 error in it that set the alarm off at midnight LOL. I will paste the new one below, as well as another addition I added to it.
« Last Edit: June 22, 2019, 02:33:48 pm by SierraKen »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Analog Clock
« Reply #7 on: June 22, 2019, 01:17:55 pm »
What another clock?!?!

Yeah, but this has an alarm and a little surprise... ;-))

Code: QB64: [Select]
  1. OPTION _EXPLICIT 'B+ 2019-06-22
  2. CONST RED = &HFFFF0000, GREEN = &HFF009000, BLUE = &HFF0000FF, WHITE = &HFFFFFFFF, CYAN = &HFF00A8A8
  3. CONST BLACK = &HFF000000, YELLOW = &HFFFFFF00, PURPLE = &HFF800082, ORANGE = &HFFD26200
  4. CONST xmax = 320, ymax = 320, x0 = xmax / 2, y0 = ymax / 2, p = 3.14159265, p2 = p * 2, pd2 = p / 2
  5. DIM SHARED alarm$
  6.  
  7. SCREEN _NEWIMAGE(320, 320, 32)
  8. _SCREENMOVE 300, 100
  9. COLOR CYAN
  10.     outputClock
  11.     IF UCASE$(INKEY$) = "A" THEN setAlarm
  12.     _DISPLAY
  13.     _LIMIT 60
  14.  
  15. SUB outputClock
  16.     DIM i AS INTEGER, t, x, y, ha, ma, sa
  17.     IF alarm$ = "" THEN _TITLE "<a> to Set Alarm Clock" ELSE _TITLE "Alarm Clock is Set"
  18.     CLS
  19.     FOR i = 0 TO 59
  20.         x = x0 + .9 * y0 * COS(i / 60 * p2 - pd2)
  21.         y = y0 + .9 * y0 * SIN(i / 60 * p2 - pd2)
  22.         IF i MOD 5 = 0 THEN CIRCLE (x, y), 3, ORANGE ELSE CIRCLE (x, y), 2, PURPLE
  23.     NEXT
  24.     t = TIMER
  25.     ha = (t / 3600) / 12 * p2 - pd2
  26.     ma = (t / 60 - 60 * INT(ha)) / 60 * p2 - pd2
  27.     sa = (t - INT(ha) * 3600 - INT(ma) * 60) / 60 * p2 - pd2
  28.     arm y0 * .9, sa, GREEN: arm y0 * .85, ma, YELLOW: arm y0 * .65, ha, BLUE
  29.     LOCATE 20, 1: PRINT TIME$;
  30.     IF alarm$ <> "" THEN
  31.         COLOR PURPLE: LOCATE 20, 34: PRINT "@";: COLOR RED: PRINT alarm$;: COLOR CYAN
  32.         IF MID$(TIME$, 1, 5) = alarm$ THEN
  33.             _TITLE "Press any to stop beeping..."
  34.             _SCREENMOVE 300 + RND * 25, 100 + RND * 25: BEEP
  35.         END IF
  36.         IF LEN(INKEY$) THEN alarm$ = ""
  37.     END IF
  38.  
  39. SUB arm (radius AS INTEGER, radians AS SINGLE, colr AS _UNSIGNED LONG)
  40.     LINE (x0, y0)-STEP(radius * COS(radians), radius * SIN(radians)), colr
  41.  
  42. SUB setAlarm
  43.     CLS: LOCATE 8, 2: PRINT "For time: hh = 00-23 : mm = 00-59"
  44.     LOCATE 10, 2: INPUT "Enter hh:mm "; alarm$
  45.  

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Analog Clock
« Reply #8 on: June 22, 2019, 02:35:37 pm »
Here is my newest update. I apologize for the last Alarm Clock, it accidentally set the alarm off at midnight lol. Here is the fixed version as well as a new addition to it which plays the hour chimes every hour on top of the hour. I found this QB64 code on the Wiki page for chimes. :))) Thank you!

Code: QB64: [Select]
  1. 'This is my first analog clock!
  2. 'Thank you to someone named Chris Procter who put a QBasic clock online around 20 years ago or so.
  3. 'I used some of his math to make this clock.
  4. 'This clock was updated and simplified a lot using the QB64 _DELAY command.
  5. 'This was made by Ken G. and is freeware.
  6. _TITLE "Analog Alarm Clock"
  7. PRINT "                              Analog Alarm Clock"
  8. PRINT "                                  By Ken G."
  9. PRINT "                To set alarm, start clock and then press 'A' to set."
  10. PRINT "                    Hours must be set to a 24 hour scale (0-23)."
  11. PRINT "             The clock will chime the hours every hour on top of the hour."
  12. PRINT "   To shut off clock, press 'Q' or click the X button on the upper right corner."
  13. PRINT "                         Press any key to start clock.",
  14. gggo:
  15. _LIMIT 500
  16. st$ = INKEY$
  17. IF st$ = CHR$(27) THEN END
  18. IF st$ <> "" THEN CLS: GOTO drawing:
  19. GOTO gggo:
  20. drawing:
  21. COLOR 15, 0
  22. CIRCLE (327, 225), 184, 15
  23. CIRCLE (325, 225), 215, 15
  24. LOCATE 2, 41: PRINT "12"
  25. LOCATE 15, 16: PRINT "9"
  26. LOCATE 15, 66: PRINT "3"
  27. LOCATE 27, 41: PRINT "6"
  28. IF set = 1 THEN
  29.     LOCATE 24, 63: PRINT "Alarm Set At:"
  30.     LOCATE 25, 63: PRINT "Hour:"; hr
  31.     LOCATE 26, 63: PRINT "Minute:"; mn
  32.     LOCATE 27, 63: PRINT "Second:"; se
  33. go:
  34. a$ = INKEY$
  35. IF a$ = "q" OR a$ = "Q" THEN END
  36. IF a$ = "a" OR a$ = "A" THEN
  37.     CLS
  38.     PRINT "                           Set Alarm"
  39.     PRINT: PRINT: PRINT
  40.     hourset:
  41.     INPUT "Hour (24 Hour Format 0-23): ", hr
  42.     IF hr < 0 OR hr > 23 THEN GOTO hourset:
  43.     IF hr <> INT(hr) THEN GOTO hourset:
  44.     PRINT
  45.     minuteset:
  46.     INPUT "Minute: ", mn
  47.     IF mn < 0 OR mn > 59 THEN GOTO minuteset:
  48.     IF mn <> INT(mn) THEN GOTO minuteset:
  49.     PRINT
  50.     secondset:
  51.     INPUT "Second: ", se
  52.     IF se < 0 OR se > 59 THEN GOTO secondset:
  53.     IF se <> INT(se) THEN GOTO secondset:
  54.     set = 1
  55.     CLS
  56.     GOTO drawing:
  57. _LIMIT 500
  58. FOR sc = 1 TO 60
  59.     ss = (60 - sc) * 6 + 180
  60.     x2 = INT(SIN(ss / 180 * 3.141592) * 180) + 5
  61.     y2 = INT(COS(ss / 180 * 3.141592) * 180) + 5
  62.     x2 = x2 + 323
  63.     y2 = y2 + 220
  64.     CIRCLE (x2, y2), 3, 15
  65. NEXT sc
  66. hours = TIMER \ 3600
  67. minutes = TIMER \ 60 - hours * 60
  68. seconds = (TIMER - hours * 3600 - minutes * 60)
  69. 'Check For Alarm
  70. t$ = TIME$
  71. LOCATE 1, 1: PRINT t$
  72. ho$ = LEFT$(TIME$, 2): hou = VAL(ho$)
  73. min$ = MID$(TIME$, 4, 2): minu = VAL(min$)
  74. seco$ = RIGHT$(TIME$, 2): secon = VAL(seco$)
  75. IF hou = hr AND minu = mn AND secon = se AND set = 1 THEN
  76.     sounds:
  77.     _DELAY .05
  78.     alarm = alarm + 50
  79.     IF alarm = 800 THEN alarm = 100
  80.     SOUND alarm, .5
  81.     clr = clr + 1: IF clr = 15 THEN clr = 1
  82.     COLOR clr, 0
  83.     LOCATE 1, 20: PRINT "ALARM IS GOING OFF! - Press Space Bar to stop."
  84.     al$ = INKEY$
  85.     IF al$ = " " OR al$ = CHR$(27) THEN
  86.         CLS
  87.         set = 0
  88.         alarm = 0: clr = 0: hr = 0: mn = 0: se = 0
  89.         a$ = "": al$ = ""
  90.         _DELAY 1
  91.         GOTO drawing:
  92.     END IF
  93.     GOTO sounds:
  94. 'Seconds
  95. s = (60 - seconds) * 6 + 180
  96. LINE (325, 225)-(x, y), 0
  97. x = INT(SIN(s / 180 * 3.141592) * 180) + 325
  98. y = INT(COS(s / 180 * 3.141592) * 180) + 225
  99. LINE (325, 225)-(x, y), 15
  100. 'Minutes
  101. m = 180 - minutes * 6
  102. LINE (325, 225)-(xx, yy), 0
  103. xx = INT(SIN(m / 180 * 3.141592) * 180) + 325
  104. yy = INT(COS(m / 180 * 3.141592) * 180) + 225
  105. LINE (325, 225)-(xx, yy), 15
  106. 'Hours
  107. h = 360 - hours * 30 + 180
  108. LINE (325, 225)-(xxx, yyy), 0
  109. xxx = INT(SIN(h / 180 * 3.141592) * 100) + 325
  110. yyy = INT(COS(h / 180 * 3.141592) * 100) + 225
  111. LINE (325, 225)-(xxx, yyy), 15
  112. 'Chimes
  113. IF minu = 0 AND secon = 0 AND alarm = 0 THEN
  114.     hour2 = hou
  115.     IF hour2 > 12 THEN hour2 = hour2 - 12
  116.     IF hour2 = 0 THEN hour2 = 12
  117.     FOR chimes = 1 TO hour2
  118.         ttt = 0
  119.         DO
  120.             'queue some sound
  121.             DO WHILE _SNDRAWLEN < 0.1 'you may wish to adjust this
  122.                 sample = SIN(ttt * 340 * ATN(1) * 8) '340Hz sine wave (ttt * 440 * 2p)
  123.                 sample = sample * EXP(-ttt * 3) 'fade out eliminates clicks after sound
  124.                 _SNDRAW sample
  125.                 ttt = ttt + 1 / _SNDRATE 'sound card sample frequency determines time
  126.             LOOP
  127.             'do other stuff, but it may interrupt sound
  128.         LOOP WHILE ttt < 2 'play for 2 seconds
  129.         DO WHILE _SNDRAWLEN > 0 'Finish any left over queued sound!
  130.         LOOP
  131.     NEXT chimes
  132. GOTO go:
  133.  

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Analog Clock
« Reply #9 on: June 22, 2019, 02:50:44 pm »
LOL bplus, that's hilarious. :). The window bounces around lol. Good job.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Analog Clock
« Reply #10 on: June 22, 2019, 07:02:01 pm »
Hey Kennith, those chimes sound pretty good!

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Analog Clock
« Reply #11 on: June 28, 2019, 11:35:28 am »
Thanks B+! I think I got the code from the QB64 wiki page. :)