QB64.org Forum

Active Forums => Programs => Topic started by: SierraKen on November 16, 2020, 08:57:13 pm

Title: My Best Analog Chiming Clock
Post by: SierraKen on November 16, 2020, 08:57:13 pm
I've wanted to make an analog clock using realistic looking hands for a very long time, so I finally figured it out using the RotoZoom Sub. :) It took me all afternoon to make this but I am glad I figured it out. Tell me what you think. Put all of the files in one folder from the zip file in attachments below. There's a photo of it too. :)
It also chimes the hour on the hour using a chime example I got last year I believe in the Wiki example pages for another clock. Understanding how Subs work sure make things a lot easier. :)

Edit: The zip file and picture have been updated, please use these instead. Thank you.

Edit: Updated again with my own drawings of the clock hands and a new picture.

Edited Again: Changed the colors, added a graphical seconds hand and remade the hands and style.
Title: Re: My Best Analog Chiming Clock
Post by: bplus on November 16, 2020, 09:09:07 pm
Fabulous!
Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 16, 2020, 09:36:48 pm
Thanks B+! :)
Title: Re: My Best Analog Chiming Clock
Post by: johnno56 on November 16, 2020, 10:08:20 pm
Very nicely done indeed!
Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 16, 2020, 10:11:31 pm
Thanks Johno :).
Title: Re: My Best Analog Chiming Clock
Post by: OldMoses on November 17, 2020, 12:06:04 am
That's one of the best ones I've seen.
Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 17, 2020, 12:10:40 am
Wow thanks OldMoses! :)
Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 17, 2020, 01:10:21 am
In case anyone else wants to make a similar clock, the trick for using the RotoZoom sub is to use clock hand graphics that are double the length as the graphic itself. That's because RotoZoom rotates from the center so if the hand is only on one side, it will rotate in the center but look like it's rotating from the end like clocks do. Look at the hand graphics I have in my zip file as an example. Also use transparent .png files so graphics or colors behind it can show up around the hands. For specific clock code, etc. refer to my program and if you need help, just ask here.
Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 17, 2020, 02:29:29 am
I have updated the zip file with different clock hands. They are better looking in my opinion. I also know that these ones are for personal use only and the older ones I have no idea. Please use the new one instead, thanks.

Update: The zip file and picture were removed from this post. Please scroll to the next one. Thanks.
Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 17, 2020, 02:59:21 pm
Well after all that, I decided to draw my own clock hands. This way the whole thing was made by me. :)

Updated: Deleted this version, please keep scrolling to the second page on this forum.
Title: Re: My Best Analog Chiming Clock
Post by: bplus on November 18, 2020, 02:23:25 pm
@SierraKen

Hi Ken I am wondering how you got your clock hands saved on transparent background? I hate having to go through Paint3D and if I could do that with QB64 I don't remember how unless with Steve's saveImage?

BTW on the old clock hands or the new it might be cool if the holes centered on hour, minute or seconds tick marks?
I like the very smooth moving second hand.
Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 18, 2020, 03:18:30 pm
Thanks B+!! Yeah I agree that I do need to work on the hands a bit more, that sounds like a great idea, with holes over the hour, minute, and second marks.

To make the transparent .png files, I use the free paint program called Paint.Net (I'll put the link to it below). You just make the size of the graphic you want, then use the eraser (I suggest making the eraser size 50 or so) and erase all the white default background the picture has. When you erase it, it turns it into a chessboard type look which is a transparent background. From them on, any graphic you make using the paint brush, lines, shapes, whatever, will be on top of the nothing background. Then save it as .png. That's all you have to do and then you load it with _LOADIMAGE and put it on the screen like you do with any graphic file and QB64 takes care of the rest automatically. I've used Paint.Net for at least 10 years now and it's really good. It has no advertisements either.

For some reason Paint.Net's website isn't loading right now for me but I found it on CNet. Be careful though not to install or change anything you don't want on installation (CNet does that often).
https://download.cnet.com/Paint-NET/3000-2192_4-10338146.html (https://download.cnet.com/Paint-NET/3000-2192_4-10338146.html)


Title: Re: My Best Analog Chiming Clock
Post by: bplus on November 18, 2020, 03:59:11 pm
Thanks @SierraKen there's probably an option to start with transparent I would think.
Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 18, 2020, 05:20:16 pm
Yeah I looked for that but couldn't find it. Just remember to look hard for any white on the graphic. The first time I tried my analog hands I ended up with some bits of white all over my clock. LOL So I made the eraser big and did it as good as I could.
Title: Re: My Best Analog Chiming Clock
Post by: bplus on November 18, 2020, 05:41:22 pm
Well I know I'd rather draw in QB64 anyway, so do that in separate hand images and use those image handles for an all-in-one proggie. BUT this does not work for times when you want to make avatars say to use at forums.
Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 18, 2020, 08:12:14 pm
Here is a MUCH better clock. I completely remade the clock hands and added a new graphical seconds clock hand as well. It took me a few minutes to make a smoothly animated seconds hand but it's incredibly easier than it seems. All you need to do to find the degrees for RotoZoom of the seconds hand is this: angle = 6 * TIMER. TIMER is how many milliseconds since midnight. I also softened the hand graphics to add dark shade around them to look more authentic. I used B+'s idea to make circles around the hours, minutes, and seconds. Tell me what you think everyone. I also changed the colors around, I like these better. I'll update the original zip file and picture above and remove the last one. Here it is also below. By the way, it feels really good to be able to draw these clock hands when I've never been an artist hardly before.




Title: Re: My Best Analog Chiming Clock
Post by: bplus on November 18, 2020, 09:10:31 pm
Nice @SierraKen

The hands are picking up a nice style to them and I really like the blue hour dots more in the middle!
Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 18, 2020, 09:29:23 pm
Thanks B+, I really like it too. I'll be using this often. :)
Title: Re: My Best Analog Chiming Clock
Post by: _vince on November 19, 2020, 02:27:05 am
why not

Code: [Select]
pi = 4*atn(1)
sw = 800
sh = 600

s$ = "33111121131112121222132114211123113231"

screen _newimage(sw, sh, 32)
screen ,,1,0

pset (sw/2, sh/2),_rgb(100,100,100)
for a=0 to 2*pi step 0.01
        x = 100*cos(a) + 100*cos(14*a)
        y = 100*sin(a) + 100*sin(14*a)
        line -(sw/2 + x, sh/2 + y),_rgb(35,35,35)
next

circle (sw/2, sh/2), 8
circle (sw/2, sh/2), 12
circle (sw/2, sh/2), 210 - 5,_rgb(100,100,100)
circle (sw/2, sh/2), 280 + 5,_rgb(100,100,100)
circle (sw/2, sh/2), 280 + 10,_rgb(100,100,100)

a = -pi/2

do while i < len(s$)-1
        i = i + 1
        c$ = mid$(s$, i, 1)
        b = a - 0.05*(val(c$))*0.5
        for k=0 to val(c$) - 1
                i = i + 1
                select case mid$(s$, i, 1)
                case "1"
                        line (sw/2 + 210*cos(b), sh/2 + 210*sin(b))-step(70*cos(b), 70*sin(b))
                case "2"
                        if val(c$) > 1 then c = b + 0.05*0.5*((k = 0) - (k <> 0)) else c = b
                        line (sw/2 + 210*cos(c), sh/2 + 210*sin(c))-step(70*cos(c - 0.05*3), 70*sin(c - 0.05*3))
                        line (sw/2 + 210*cos(c), sh/2 + 210*sin(c))-step(70*cos(c + 0.05*3), 70*sin(c + 0.05*3))
                case "3"
                        if val(c$) > 1 then c = b + 0.05*0.5*((k = 0) - (k <> 0)) else c = b
                        line (sw/2 + 210*cos(c - 0.05*0.8), sh/2 + 210*sin(c - 0.05*0.8))-(sw/2 + 280*cos(c + 0.05*0.8), sh/2 + 280*sin(c + 0.05*0.8))
                        line (sw/2 + 210*cos(c + 0.05*0.8), sh/2 + 210*sin(c + 0.05*0.8))-(sw/2 + 280*cos(c - 0.05*0.8), sh/2 + 280*sin(c - 0.05*0.8))
                end select
                b = b + 0.05
        next
        a = a + pi/6
loop

screen ,,0,0

do
        t = 100*timer
        pcopy 1,0

        b = 2*pi*(t/36 mod 1200)/1200- pi/2
        pset (sw/2, sh/2)
        for a=0 to pi step 0.01
                x = 140*(0.8*cos(a))^5*abs(3*cos(8*a)^2)*sin(a)*cos(b) - 180*sin(a)*sin(b)
                y = 140*(0.8*cos(a))^5*abs(3*cos(8*a)^2)*sin(a)*sin(b) + 180*sin(a)*cos(b)
                line -(sw/2 + x, sh/2 + y)
        next

        b = 2*pi*(t*100 mod 360000)/360000 - pi/2
        pset (sw/2, sh/2)
        for a=0 to pi step 0.01
                x = 55*(cos(a))^5*abs(2*(cos(4*a))^2 - 0.5)*sin(a)*cos(b) - 280*sin(a)*sin(b)
                y = 55*(cos(a))^5*abs(2*(cos(4*a))^2 - 0.5)*sin(a)*sin(b) + 280*sin(a)*cos(b)
                line -(sw/2 + x, sh/2 + y)
        next

        _display
        _limit 100
loop until _keyhit=27
sleep
system
Title: Re: My Best Analog Chiming Clock
Post by: bplus on November 19, 2020, 11:52:59 am
Holy cow! that's nice @_vince
Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 19, 2020, 01:35:53 pm
That makes nothing on my computer. Was it supposed to go with something? Was it to make something transparent?
Title: Re: My Best Analog Chiming Clock
Post by: bplus on November 19, 2020, 01:43:44 pm
Hi @SierraKen

It's all drawing from bas code (the minutes hand is moving as if a seconds hand)
 


BTW @_vince this fixes line at 3 0'clock:
Code: QB64: [Select]
  1. 'PSET (sw / 2, sh / 2), _RGB(100, 100, 100)
  2. FOR a = 0 TO 2 * pi STEP 0.01
  3.     x = 100 * COS(a) + 100 * COS(14 * a)
  4.     y = 100 * SIN(a) + 100 * SIN(14 * a)
  5.     IF a = 0 THEN PSET (sw / 2 + x, sh / 2 + y) ELSE LINE -(sw / 2 + x, sh / 2 + y), _RGB(35, 35, 35) '<<< pset here
  6.  


Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 19, 2020, 04:30:42 pm
LOL I can't believe I did that. I only copy/pasted the code that I saw, I didn't scroll down on the rest of his code. lol

Vince this is awesome! Very nice design. It just needs to be added the real time to it. I looked briefly at the code and can't really figure it out yet, but I'll look a bit more.

Title: Re: My Best Analog Chiming Clock
Post by: bplus on November 19, 2020, 07:55:09 pm
Tried a mod of _vince clock with solid hands, kinda fuzzy :(
Code: QB64: [Select]
  1. CONST g = &HFF000088 'hnd5s and numbers
  2. pi = _PI
  3. sw = 800
  4. sh = 600
  5. s$ = "33111121131112121222132114211123113231"
  6.  
  7. SCREEN _NEWIMAGE(sw, sh, 32)
  8. hhand& = _NEWIMAGE(360, 80, 32) ' make hour hand image and save
  9. b = -pi / 2
  10. PSET (sw / 2, sh / 2)
  11. FOR a = 0 TO pi STEP 0.01
  12.     x = 140 * (0.8 * COS(a)) ^ 5 * ABS(3 * COS(8 * a) ^ 2) * SIN(a) * COS(b) - 176 * SIN(a) * SIN(b)
  13.     y = 140 * (0.8 * COS(a)) ^ 5 * ABS(3 * COS(8 * a) ^ 2) * SIN(a) * SIN(b) + 176 * SIN(a) * COS(b)
  14.     LINE -(sw / 2 + x, sh / 2 + y), g
  15. PAINT (sw / 2 + 10, sh / 2), g, g
  16. PAINT (sw / 2 + 60, sh / 2), g, g
  17. PAINT (sw / 2 + 120, sh / 2), g, g
  18. PAINT (sw / 2 + 160, sh / 2), g, g
  19. _PUTIMAGE , 0, hhand&, (sw / 2 - 180, sh / 2 - 39)-STEP(359, 79)
  20. 'check
  21. 'CLS
  22. 'RotoZoom sw / 2, sh / 2, hhand&, 1, 0
  23. 'CIRCLE (sw / 2, sh / 2), 6, &HFFFFFF00
  24.  
  25. SCREEN _NEWIMAGE(sw, sh, 32) ' cls screen without cls keep back transparent
  26. mhand& = _NEWIMAGE(560, 80, 32) 'make  minute hand
  27. b = -pi / 2
  28. FOR a = 0 TO pi STEP 0.01
  29.     x = 55 * (COS(a)) ^ 5 * ABS(2 * (COS(4 * a)) ^ 2 - 0.5) * SIN(a) * COS(b) - 270 * SIN(a) * SIN(b)
  30.     y = 55 * (COS(a)) ^ 5 * ABS(2 * (COS(4 * a)) ^ 2 - 0.5) * SIN(a) * SIN(b) + 270 * SIN(a) * COS(b)
  31.     LINE -(sw / 2 + x, sh / 2 + y), g
  32. PAINT (sw / 2 + 20, sh / 2), g, g
  33. PAINT (sw / 2 + 120, sh / 2), g, g
  34. PAINT (sw / 2 + 160, sh / 2), g, g
  35. _PUTIMAGE , 0, mhand&, (sw / 2 - 280, sh / 2 - 39)-STEP(559, 79)
  36. 'check
  37. 'CLS
  38. 'RotoZoom sw / 2, sh / 2, mhand&, 1, 36
  39. 'RotoZoom sw / 2, sh / 2, hhand&, 1, 150
  40. 'CIRCLE (sw / 2, sh / 2), 6, &HFFFFFF00
  41.  
  42. face& = _NEWIMAGE(_WIDTH, _HEIGHT, 32)
  43. fcirc sw / 2, sh / 2, 280 + 10, &HFFFF0000
  44. fcirc sw / 2, sh / 2, 280 + 5, &HFFFFFFFF
  45. fcirc sw / 2, sh / 2, 205, &HFFDDDDFF
  46. FOR a = 0 TO 2 * pi STEP 0.01
  47.     x = 100 * COS(a) + 100 * COS(14 * a)
  48.     y = 100 * SIN(a) + 100 * SIN(14 * a)
  49.     IF a = 0 THEN PSET (sw / 2 + x, sh / 2 + y) ELSE LINE -(sw / 2 + x, sh / 2 + y), _RGB(0, 255, 128)
  50.  
  51. fcirc sw / 2, sh / 2, 12, &HFFFFFF00
  52. fcirc sw / 2, sh / 2, 6, &HFF000000
  53. CIRCLE (sw / 2, sh / 2), 210 - 5, &HFF000000
  54. CIRCLE (sw / 2, sh / 2), 280 + 5, &HFF000000
  55. CIRCLE (sw / 2, sh / 2), 280 + 10, &HFF000000
  56. a = -pi / 2
  57. DO WHILE i < LEN(s$) - 1
  58.     i = i + 1
  59.     c$ = MID$(s$, i, 1)
  60.     b = a - 0.05 * (VAL(c$)) * 0.5
  61.     FOR k = 0 TO VAL(c$) - 1
  62.         i = i + 1
  63.         SELECT CASE MID$(s$, i, 1)
  64.             CASE "1"
  65.                 LINE (sw / 2 + 210 * COS(b), sh / 2 + 210 * SIN(b))-STEP(70 * COS(b), 70 * SIN(b))
  66.             CASE "2"
  67.                 IF VAL(c$) > 1 THEN c = b + 0.05 * 0.5 * ((k = 0) - (k <> 0)) ELSE c = b
  68.                 LINE (sw / 2 + 210 * COS(c), sh / 2 + 210 * SIN(c))-STEP(70 * COS(c - 0.05 * 3), 70 * SIN(c - 0.05 * 3))
  69.                 LINE (sw / 2 + 210 * COS(c), sh / 2 + 210 * SIN(c))-STEP(70 * COS(c + 0.05 * 3), 70 * SIN(c + 0.05 * 3))
  70.             CASE "3"
  71.                 IF VAL(c$) > 1 THEN c = b + 0.05 * 0.5 * ((k = 0) - (k <> 0)) ELSE c = b
  72.                 LINE (sw / 2 + 210 * COS(c - 0.05 * 0.8), sh / 2 + 210 * SIN(c - 0.05 * 0.8))-(sw / 2 + 280 * COS(c + 0.05 * 0.8), sh / 2 + 280 * SIN(c + 0.05 * 0.8))
  73.                 LINE (sw / 2 + 210 * COS(c + 0.05 * 0.8), sh / 2 + 210 * SIN(c + 0.05 * 0.8))-(sw / 2 + 280 * COS(c - 0.05 * 0.8), sh / 2 + 280 * SIN(c - 0.05 * 0.8))
  74.         END SELECT
  75.         b = b + 0.05
  76.     NEXT
  77.     a = a + pi / 6
  78. _PUTIMAGE , 0, face&
  79.     _PUTIMAGE , face&, 0
  80.     m = VAL(MID$(TIME$, 4, 2)) / 60
  81.     h = VAL(LEFT$(TIME$, 2))
  82.     IF h > 12 THEN h = h - 12
  83.     h = (h / 12 + m / 12) * 360
  84.     RotoZoom sw / 2, sh / 2, hhand&, 1, h - 90
  85.     RotoZoom sw / 2, sh / 2, mhand&, 1, m * 360 - 90
  86.     _DISPLAY
  87.     _LIMIT 100
  88.  
  89. SUB RotoZoom (X AS LONG, Y AS LONG, hdl AS LONG, Scale AS SINGLE, Rotation AS SINGLE)
  90.     DIM px(3) AS SINGLE: DIM py(3) AS SINGLE
  91.     W& = _WIDTH(hdl): H& = _HEIGHT(hdl)
  92.     px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  93.     px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  94.     sinr! = SIN(-Rotation / 57.2957795131): cosr! = COS(-Rotation / 57.2957795131)
  95.     FOR I& = 0 TO 3
  96.         x2& = (px(I&) * cosr! + sinr! * py(I&)) * Scale + X: y2& = (py(I&) * cosr! - px(I&) * sinr!) * Scale + Y
  97.         px(I&) = x2&: py(I&) = y2&
  98.     NEXT
  99.     _MAPTRIANGLE (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), hdl TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  100.     _MAPTRIANGLE (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), hdl TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  101.  
  102. 'from Steve Gold standard
  103. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  104.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  105.     DIM X AS INTEGER, Y AS INTEGER
  106.     Radius = ABS(R): RadiusError = -Radius: X = Radius: Y = 0
  107.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  108.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  109.     WHILE X > Y
  110.         RadiusError = RadiusError + Y * 2 + 1
  111.         IF RadiusError >= 0 THEN
  112.             IF X <> Y + 1 THEN
  113.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  114.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  115.             END IF
  116.             X = X - 1
  117.             RadiusError = RadiusError - X * 2
  118.         END IF
  119.         Y = Y + 1
  120.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  121.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  122.     WEND
  123.  

  [ This attachment cannot be displayed inline in 'Print Page' view ]  

I also found out Ken modified a perfectly fine rotozoom feeling need to change parameter name ;)
(I had copied the version he had in his code. I changed it back to hdl.)
Title: Re: My Best Analog Chiming Clock
Post by: _vince on November 19, 2020, 09:03:24 pm
Nice, I was definitely inspired by Ken's clock hands and wanted to see how hard it would be to render those vintage style 'calligraphy' hands in a short tight curve parametrization.  It turns out it is beyond me. I had my sights on something like this:
(https://image.shutterstock.com/image-vector/vintage-clock-dial-set-hands-600w-496516774.jpg)

I have no idea how you'd parametrize those spade like curves with all the loops and cusps. I am aware that there's an algorithm that can fit a sum of sinusoids expression to any arbitrary curve but it would not be as tight and elegant as the stuff here: https://mathworld.wolfram.com/HeartCurve.html (https://mathworld.wolfram.com/HeartCurve.html) - that math is beyond me. I'd be impressed if anyone can pull off a fancy spade clock hand curve with a similar expression. My hands are a sloppy few minutes of trial and error.

I am also aware that the program is a bit rough with mistakes and misalignment but had I polished all of that it would no longer be the cute 70-liner -- I would then be better off hand coding each roman numeral and so on. I would be down to code up the ultimate QB vintage clock some time, all the flourishings, calligraphy, fancy spirographs, true 3D shadows on hands, etc and no external images!
Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 19, 2020, 09:16:17 pm
Thanks Vince. RotoZoom takes care of most of the math by just rotating the picture. I tried to add the real time to your clock this afternoon but no luck. Your math is beyond me there is why.

Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 19, 2020, 09:32:04 pm
I see what you mean B+, "hdl AS LONG". Yeah hdl confused me so I just named it clock. lol I'll change it back and put the new version up in the zips above.
Title: Re: My Best Analog Chiming Clock
Post by: bplus on November 19, 2020, 09:43:01 pm
I see what you mean B+, "hdl AS LONG". Yeah hdl confused me so I just named it clock. lol I'll change it back and put the new version up in the zips above.

Don't worry about it Ken, I was proud to see you using a SUB! BTW hdl means rotozoom was looking for any image handle to scale and rotate.

@_vince maybe we could work something up from this?
Code: QB64: [Select]
  1. _TITLE "Beating Cardiod" 'B+ 2019-02-16
  2. '2019-02-28 random magnify and beat, redder heart
  3.  
  4.  
  5. CONST xmax = 800
  6. CONST ymax = 600
  7. SCREEN _NEWIMAGE(xmax, ymax, 32)
  8. _SCREENMOVE (1280 - xmax) / 2 + 30, (760 - ymax) / 2
  9.  
  10. 'center of screen
  11. CX = xmax / 2
  12. CY = ymax / 2 - 50
  13.  
  14. WHILE _KEYDOWN(27) = 0
  15.     CLS
  16.     loopCount = (loopCount + 1) MOD 2
  17.     IF loopCount THEN magnify = 10 ELSE magnify = RND * 10 + 12
  18.     FOR a = -_PI TO _PI STEP _PI(1 / 360)
  19.         x = CX + magnify * xCard(a)
  20.         y = CY - magnify * yCard(a)
  21.         IF a <> -_PI THEN
  22.             LINE (x, y)-(lastx, lasty), _RGB(140, 0, 0)
  23.         END IF
  24.         lastx = x: lasty = y
  25.     NEXT
  26.     PAINT (CX, CY), _RGB(180, 0, 0), _RGB(140, 0, 0)
  27.     _DISPLAY
  28.     IF loopCount THEN _DELAY 40 / 60 ELSE _DELAY (30 + RND * 15) / 65
  29.  
  30. 'Reference and thanks to:
  31. ' http://mathworld.wolfram.com/HeartCurve.html
  32. ' find the 6th heart curve equations #7, 8
  33. FUNCTION xCard (t)
  34.     xCard = 16 * SIN(t) ^ 3
  35.  
  36. FUNCTION yCard (t)
  37.     yCard = 13 * COS(t) - 5 * COS(2 * t) - 2 * COS(3 * t) - COS(4 * t)
  38.  
Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 19, 2020, 09:48:01 pm
B+ your white clock is amazing! Yeah, the brighter colors shows up the rough edges for some reason, not sure why. That is why I smoothed out my hand files using my graphics program.
Title: Re: My Best Analog Chiming Clock
Post by: STxAxTIC on November 20, 2020, 03:47:26 am
12-hour H:M:S clock with fading graphics and celtic-like overlay. The hands connect on-end, not on center:

Thanks @Fellippe for anti-aliased lines.

EDIT: Got rid of fading colors and other busy things, it looked bad after a while:

Code: QB64: [Select]
  1.  
  2. DIM MainScreen AS LONG
  3. DIM BackScreen AS LONG
  4. MainScreen = _NEWIMAGE(600, 600, 32)
  5. BackScreen = _NEWIMAGE(600, 600, 32)
  6. SCREEN MainScreen
  7.  
  8. pi = 4 * ATN(1)
  9. phi = (1 + SQR(5)) / 2
  10.  
  11. TYPE TimeValue
  12.     Hour AS DOUBLE
  13.     Minute AS DOUBLE
  14.     Second AS DOUBLE
  15.  
  16. TYPE Vector
  17.     x AS DOUBLE
  18.     y AS DOUBLE
  19.  
  20. TYPE ClockHand
  21.     Center AS Vector
  22.     HandPosition AS Vector
  23.     Length AS DOUBLE
  24.     Angle AS DOUBLE
  25.     Shade AS _UNSIGNED LONG
  26.  
  27. DIM SHARED TheTime AS TimeValue
  28. DIM SHARED HourHand AS ClockHand
  29. DIM SHARED MinuteHand AS ClockHand
  30. DIM SHARED SecondHand AS ClockHand
  31.  
  32. HourHand.Center.x = 0
  33. HourHand.Center.y = 0
  34. HourHand.Length = 140
  35. HourHand.Shade = _RGBA(255, 0, 0, 255)
  36. MinuteHand.Length = HourHand.Length / phi
  37. MinuteHand.Shade = _RGBA(0, 255, 0, 255)
  38. SecondHand.Length = HourHand.Length / (phi ^ 2)
  39. SecondHand.Shade = _RGBA(255, 0, 255, 255)
  40.  
  41. _DEST BackScreen
  42. FOR k = 0 TO 12 * 3600 - (3600) STEP (3600)
  43.     CALL UpdateTime(k)
  44.     CALL UpdateClock
  45.     CALL ccircle(HourHand.HandPosition.x, HourHand.HandPosition.y, 5, _RGBA(_RED32(HourHand.Shade), _GREEN32(HourHand.Shade), _BLUE32(HourHand.Shade), 200))
  46. FOR k = 0 TO 12 * 3600 - (12 * 3) STEP (12 * 3)
  47.     CALL UpdateTime(k)
  48.     CALL UpdateClock
  49.     CALL ccircle(MinuteHand.HandPosition.x, MinuteHand.HandPosition.y, 3, _RGBA(_RED32(MinuteHand.Shade), _GREEN32(MinuteHand.Shade), _BLUE32(HourHand.Shade), 100))
  50.  
  51. _DEST MainScreen
  52. _PUTIMAGE (0, 0)-(_WIDTH, _HEIGHT), BackScreen, MainScreen, (0, 0)-(_WIDTH, _HEIGHT)
  53.     CALL UpdateTime(TIMER)
  54.     CALL UpdateClock
  55.  
  56.     CLS
  57.     _PUTIMAGE (0, 0)-(_WIDTH, _HEIGHT), BackScreen, MainScreen, (0, 0)-(_WIDTH, _HEIGHT)
  58.     CALL DrawClockHands
  59.  
  60.     _DISPLAY
  61.     _LIMIT 60
  62.  
  63. SUB UpdateClock
  64.     HourHand.Angle = -((TheTime.Hour + (TheTime.Minute / 60)) / 12) * 2 * pi + pi / 2
  65.     MinuteHand.Angle = -((TheTime.Minute + (TheTime.Second / 60)) / 60) * 2 * pi + pi / 2
  66.     SecondHand.Angle = -(TheTime.Second / 60) * 2 * pi + pi / 2
  67.     HourHand.HandPosition.x = HourHand.Center.x + HourHand.Length * COS(HourHand.Angle)
  68.     HourHand.HandPosition.y = HourHand.Center.y + HourHand.Length * SIN(HourHand.Angle)
  69.     MinuteHand.Center.x = HourHand.HandPosition.x
  70.     MinuteHand.Center.y = HourHand.HandPosition.y
  71.     MinuteHand.HandPosition.x = MinuteHand.Center.x + MinuteHand.Length * COS(MinuteHand.Angle)
  72.     MinuteHand.HandPosition.y = MinuteHand.Center.y + MinuteHand.Length * SIN(MinuteHand.Angle)
  73.     SecondHand.Center.x = MinuteHand.HandPosition.x
  74.     SecondHand.Center.y = MinuteHand.HandPosition.y
  75.     SecondHand.HandPosition.x = SecondHand.Center.x + SecondHand.Length * COS(SecondHand.Angle)
  76.     SecondHand.HandPosition.y = SecondHand.Center.y + SecondHand.Length * SIN(SecondHand.Angle)
  77.  
  78. SUB DrawClockHands
  79.     CALL ccircle(SecondHand.HandPosition.x, SecondHand.HandPosition.y, 3, SecondHand.Shade)
  80.     CALL lineSmooth(SecondHand.Center.x, SecondHand.Center.y, SecondHand.HandPosition.x, SecondHand.HandPosition.y, SecondHand.Shade)
  81.     CALL ccircle(MinuteHand.HandPosition.x, MinuteHand.HandPosition.y, 3, MinuteHand.Shade)
  82.     CALL lineSmooth(MinuteHand.Center.x, MinuteHand.Center.y, MinuteHand.HandPosition.x, MinuteHand.HandPosition.y, MinuteHand.Shade)
  83.     CALL ccircle(HourHand.HandPosition.x, HourHand.HandPosition.y, 3, HourHand.Shade)
  84.     CALL lineSmooth(HourHand.Center.x, HourHand.Center.y, HourHand.HandPosition.x, HourHand.HandPosition.y, HourHand.Shade)
  85.  
  86. SUB UpdateTime (t AS DOUBLE)
  87.     TheTime.Hour = t \ 3600
  88.     t = t - TheTime.Hour * 3600
  89.     IF (TheTime.Hour > 12) THEN TheTime.Hour = TheTime.Hour - 12
  90.     TheTime.Minute = t \ 60
  91.     t = t - TheTime.Minute * 60
  92.     TheTime.Second = t
  93.  
  94. SUB cpset (x1, y1, col AS _UNSIGNED LONG)
  95.     PSET (_WIDTH / 2 + x1, -y1 + _HEIGHT / 2), col
  96.  
  97. SUB cline (x1 AS DOUBLE, y1 AS DOUBLE, x2 AS DOUBLE, y2 AS DOUBLE, col AS _UNSIGNED LONG)
  98.     LINE (_WIDTH / 2 + x1, -y1 + _HEIGHT / 2)-(_WIDTH / 2 + x2, -y2 + _HEIGHT / 2), col
  99.  
  100. SUB ccircle (x1 AS DOUBLE, y1 AS DOUBLE, rad AS DOUBLE, col AS _UNSIGNED LONG)
  101.     CIRCLE (_WIDTH / 2 + x1, -y1 + _HEIGHT / 2), rad, col
  102.  
  103. SUB lineSmooth (x0, y0, x1, y1, c AS _UNSIGNED LONG)
  104.     'translated from
  105.     'https://en.wikipedia.org/w/index.php?title=Xiaolin_Wu%27s_line_algorithm&oldid=852445548
  106.  
  107.     DIM plX AS INTEGER, plY AS INTEGER, plI
  108.  
  109.     DIM steep AS _BYTE
  110.     steep = ABS(y1 - y0) > ABS(x1 - x0)
  111.  
  112.     IF steep THEN
  113.         SWAP x0, y0
  114.         SWAP x1, y1
  115.     END IF
  116.  
  117.     IF x0 > x1 THEN
  118.         SWAP x0, x1
  119.         SWAP y0, y1
  120.     END IF
  121.  
  122.     DIM dx, dy, gradient
  123.     dx = x1 - x0
  124.     dy = y1 - y0
  125.     gradient = dy / dx
  126.  
  127.     IF dx = 0 THEN
  128.         gradient = 1
  129.     END IF
  130.  
  131.     'handle first endpoint
  132.     DIM xend, yend, xgap, xpxl1, ypxl1
  133.     xend = _ROUND(x0)
  134.     yend = y0 + gradient * (xend - x0)
  135.     xgap = (1 - ((x0 + .5) - INT(x0 + .5)))
  136.     xpxl1 = xend 'this will be used in the main loop
  137.     ypxl1 = INT(yend)
  138.     IF steep THEN
  139.         plX = ypxl1
  140.         plY = xpxl1
  141.         plI = (1 - (yend - INT(yend))) * xgap
  142.         GOSUB plot
  143.  
  144.         plX = ypxl1 + 1
  145.         plY = xpxl1
  146.         plI = (yend - INT(yend)) * xgap
  147.         GOSUB plot
  148.     ELSE
  149.         plX = xpxl1
  150.         plY = ypxl1
  151.         plI = (1 - (yend - INT(yend))) * xgap
  152.         GOSUB plot
  153.  
  154.         plX = xpxl1
  155.         plY = ypxl1 + 1
  156.         plI = (yend - INT(yend)) * xgap
  157.         GOSUB plot
  158.     END IF
  159.  
  160.     DIM intery
  161.     intery = yend + gradient 'first y-intersection for the main loop
  162.  
  163.     'handle second endpoint
  164.     DIM xpxl2, ypxl2
  165.     xend = _ROUND(x1)
  166.     yend = y1 + gradient * (xend - x1)
  167.     xgap = ((x1 + .5) - INT(x1 + .5))
  168.     xpxl2 = xend 'this will be used in the main loop
  169.     ypxl2 = INT(yend)
  170.     IF steep THEN
  171.         plX = ypxl2
  172.         plY = xpxl2
  173.         plI = (1 - (yend - INT(yend))) * xgap
  174.         GOSUB plot
  175.  
  176.         plX = ypxl2 + 1
  177.         plY = xpxl2
  178.         plI = (yend - INT(yend)) * xgap
  179.         GOSUB plot
  180.     ELSE
  181.         plX = xpxl2
  182.         plY = ypxl2
  183.         plI = (1 - (yend - INT(yend))) * xgap
  184.         GOSUB plot
  185.  
  186.         plX = xpxl2
  187.         plY = ypxl2 + 1
  188.         plI = (yend - INT(yend)) * xgap
  189.         GOSUB plot
  190.     END IF
  191.  
  192.     'main loop
  193.     DIM x
  194.     IF steep THEN
  195.         FOR x = xpxl1 + 1 TO xpxl2 - 1
  196.             plX = INT(intery)
  197.             plY = x
  198.             plI = (1 - (intery - INT(intery)))
  199.             GOSUB plot
  200.  
  201.             plX = INT(intery) + 1
  202.             plY = x
  203.             plI = (intery - INT(intery))
  204.             GOSUB plot
  205.  
  206.             intery = intery + gradient
  207.         NEXT
  208.     ELSE
  209.         FOR x = xpxl1 + 1 TO xpxl2 - 1
  210.             plX = x
  211.             plY = INT(intery)
  212.             plI = (1 - (intery - INT(intery)))
  213.             GOSUB plot
  214.  
  215.             plX = x
  216.             plY = INT(intery) + 1
  217.             plI = (intery - INT(intery))
  218.             GOSUB plot
  219.  
  220.             intery = intery + gradient
  221.         NEXT
  222.     END IF
  223.  
  224.     EXIT SUB
  225.  
  226.     plot:
  227.     ' Change to regular PSET for standard coordinate orientation.
  228.     CALL cpset(plX, plY, _RGB32(_RED32(c), _GREEN32(c), _BLUE32(c), plI * 255))
  229.     RETURN
  230.  

Title: Re: My Best Analog Chiming Clock
Post by: SierraKen on November 20, 2020, 10:47:01 am
Really cool StXaXtic! especially like the fading circular loop.
Title: Re: My Best Analog Chiming Clock
Post by: _vince on November 20, 2020, 06:15:39 pm
@_vince maybe we could work something up from this?
Code: QB64: [Select]
  1. _TITLE "Beating Cardiod" 'B+ 2019-02-16
  2. '2019-02-28 random magnify and beat, redder heart
  3.  
  4.  
  5. CONST xmax = 800
  6. CONST ymax = 600
  7. SCREEN _NEWIMAGE(xmax, ymax, 32)
  8. _SCREENMOVE (1280 - xmax) / 2 + 30, (760 - ymax) / 2
  9.  
  10. 'center of screen
  11. CX = xmax / 2
  12. CY = ymax / 2 - 50
  13.  
  14. WHILE _KEYDOWN(27) = 0
  15.     CLS
  16.     loopCount = (loopCount + 1) MOD 2
  17.     IF loopCount THEN magnify = 10 ELSE magnify = RND * 10 + 12
  18.     FOR a = -_PI TO _PI STEP _PI(1 / 360)
  19.         x = CX + magnify * xCard(a)
  20.         y = CY - magnify * yCard(a)
  21.         IF a <> -_PI THEN
  22.             LINE (x, y)-(lastx, lasty), _RGB(140, 0, 0)
  23.         END IF
  24.         lastx = x: lasty = y
  25.     NEXT
  26.     PAINT (CX, CY), _RGB(180, 0, 0), _RGB(140, 0, 0)
  27.     _DISPLAY
  28.     IF loopCount THEN _DELAY 40 / 60 ELSE _DELAY (30 + RND * 15) / 65
  29.  
  30. 'Reference and thanks to:
  31. ' http://mathworld.wolfram.com/HeartCurve.html
  32. ' find the 6th heart curve equations #7, 8
  33. FUNCTION xCard (t)
  34.     xCard = 16 * SIN(t) ^ 3
  35.  
  36. FUNCTION yCard (t)
  37.     yCard = 13 * COS(t) - 5 * COS(2 * t) - 2 * COS(3 * t) - COS(4 * t)
  38.  

I'm not so sure it would work, bplus, I'd prefer to remain as just friends
Title: Re: My Best Analog Chiming Clock
Post by: bplus on November 20, 2020, 07:19:54 pm
LOL!
Title: Re: My Best Analog Chiming Clock
Post by: STxAxTIC on November 21, 2020, 12:49:30 pm
I could never fix your heart, but I can improve your cardioid:

Code: QB64: [Select]
  1. _TITLE "Beating Cardiod" 'B+ 2019-02-16
  2. '2019-02-28 random magnify and beat, redder heart
  3. '2020-11-21 better heartbeat
  4.  
  5. CONST xmax = 800
  6. CONST ymax = 600
  7. SCREEN _NEWIMAGE(xmax, ymax, 32)
  8. _SCREENMOVE (1280 - xmax) / 2 + 30, (760 - ymax) / 2
  9.  
  10. 'center of screen
  11. CX = xmax / 2
  12. CY = ymax / 2 - 50
  13.  
  14. WHILE _KEYDOWN(27) = 0
  15.     CLS
  16.     magnify = 10 + COS(TIMER * 2 * 3.14159)
  17.  
  18.     FOR a = -_PI TO _PI STEP _PI(1 / 360)
  19.         x = CX + magnify * xCard(a)
  20.         y = CY - magnify * yCard(a)
  21.         IF a <> -_PI THEN
  22.             LINE (x, y)-(lastx, lasty), _RGB(140, 0, 0)
  23.         END IF
  24.         lastx = x: lasty = y
  25.     NEXT
  26.     PAINT (CX, CY), _RGB(180, 0, 0), _RGB(140, 0, 0)
  27.     _DISPLAY
  28.  
  29.  
  30. 'Reference and thanks to:
  31. ' http://mathworld.wolfram.com/HeartCurve.html
  32. ' find the 6th heart curve equations #7, 8
  33. FUNCTION xCard (t)
  34.     xCard = 16 * SIN(t) ^ 3
  35.  
  36. FUNCTION yCard (t)
  37.     yCard = 13 * COS(t) - 5 * COS(2 * t) - 2 * COS(3 * t) - COS(4 * t)
  38.  
Title: Re: My Best Analog Chiming Clock
Post by: bplus on November 21, 2020, 07:03:12 pm
https://blog.cardiogr.am/what-do-normal-and-abnormal-heart-rhythms-look-like-on-apple-watch-7b33b4a8ecfa

Quote
Normal Heart Rhythm is Irregular
Sometimes people say “irregular pulse” as a shorthand for an abnormal heart rhythm. That’s not quite right, because a normal pulse is irregular. In fact, it’s regularly irregular: your heart rate varies periodically due to your breathing rate and autonomic nervous system. The frequency and depth of variation reflects nearly everything that happens in your life, including your level of physical activity, emotional state, and whether you’re sleeping or waking.
Title: Re: My Best Analog Chiming Clock
Post by: STxAxTIC on November 21, 2020, 08:19:06 pm
Consider the bar raised, but you're holding the apple. Model something a little better using the same code ^