Author Topic: My Best Analog Chiming Clock  (Read 8699 times)

0 Members and 1 Guest are viewing this topic.

Marked as best answer by SierraKen on November 19, 2020, 04:40:15 pm

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: My Best Analog Chiming Clock
« Reply #15 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.




AnalogChimingClockBySierraKen2.png
* AnalogChimingClockBySierraKen2.png (Filesize: 27.17 KB, Dimensions: 599x624, Views: 253)
* Analog Chiming Clock.zip (Filesize: 32.89 KB, Downloads: 149)
« Last Edit: November 19, 2020, 09:38:51 pm by SierraKen »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: My Best Analog Chiming Clock
« Reply #16 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!

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: My Best Analog Chiming Clock
« Reply #17 on: November 18, 2020, 09:29:23 pm »
Thanks B+, I really like it too. I'll be using this often. :)

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: My Best Analog Chiming Clock
« Reply #18 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

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: My Best Analog Chiming Clock
« Reply #19 on: November 19, 2020, 11:52:59 am »
Holy cow! that's nice @_vince

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: My Best Analog Chiming Clock
« Reply #20 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?

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: My Best Analog Chiming Clock
« Reply #21 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)
 
_vince clock.PNG


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.  
fix.PNG


« Last Edit: November 19, 2020, 01:56:11 pm by bplus »

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: My Best Analog Chiming Clock
« Reply #22 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.


Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: My Best Analog Chiming Clock
« Reply #23 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.  

 
_vince clock mod.PNG


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.)

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: My Best Analog Chiming Clock
« Reply #24 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 - 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!

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: My Best Analog Chiming Clock
« Reply #25 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.

« Last Edit: November 19, 2020, 09:36:06 pm by SierraKen »

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: My Best Analog Chiming Clock
« Reply #26 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.
« Last Edit: November 19, 2020, 09:36:23 pm by SierraKen »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: My Best Analog Chiming Clock
« Reply #27 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.  
« Last Edit: November 19, 2020, 09:45:23 pm by bplus »

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: My Best Analog Chiming Clock
« Reply #28 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.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: My Best Analog Chiming Clock
« Reply #29 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.  

« Last Edit: November 20, 2020, 11:08:23 am by STxAxTIC »
You're not done when it works, you're done when it's right.