lpenap

Analog Clock

Jul 22nd, 2016
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.65 KB | None | 0 0
  1. -- Analogue Clock
  2. -- (c) by lpenap
  3. -- Based on original code from Ramdor
  4. -- v1.7
  5. --
  6. -- changes
  7. -- v1.7 - fixing auto strectch to advanced monitors
  8. -- v1.6 - added non filled face option (bFaceFilled = true  ... is the default)
  9. -- v1.5 - now uses computercraft paintutils line, re-worked circle code, auto find monitor
  10. -- v1.4 - colours added and some loop derps fixed
  11. -- v1.3 - added resize/auto scale and 0.5 textsize
  12. --        to double the effective resolution
  13. -- v1.2 - changed timer code
  14. -- v1.1 - tidy up
  15. -- v1.0 - initial release
  16. --
  17. -- You may edit/copy/redistribute/whatever this
  18. -- code in any way.  Just a credit listing this
  19. -- pastebin link (pastebin.com/LGNUpDzz) will be fine :)
  20. -- Have fun, I did :)
  21.  
  22. -- see  http://www.youtube.com/watch?v=RrgOIGW0C-s   for some more info
  23.  
  24. -- these two settings will hide/show
  25. -- the M and H that is on the end of the hand
  26. local bShowHourChar = false
  27. local bShowMinuteChar = false
  28. local bFaceFilled = true
  29.  
  30. -- coloured clocks anyone?
  31. local nBackColour = colors.lightGray
  32. local nFaceColour = colors.white
  33. local nHandColour = colors.black
  34. local nTickColour = colors.gray
  35.  
  36. -- find the monitor and set it up
  37. local monitor = nil
  38. local i,side
  39. for i, side in pairs(rs.getSides()) do
  40.   if peripheral.getType(side) == "monitor" then
  41.     monitor = peripheral.wrap(side)
  42.     break
  43.   end
  44. end
  45. if monitor==nil then
  46.   print("NO MONITOR FOUND")
  47.   print("Please attach a monitor and try again.")
  48.   return
  49. end
  50.  
  51. -- calculate scaling
  52. monitor.setTextScale(0.5)
  53.  
  54. -- hackish fix to enable large monitor arrays enough time to initialise?
  55. os.sleep(1)
  56.  
  57. local mw,mh = monitor.getSize()
  58. mw = mw / (15/10) -- 15x10 is w,h of 0.5 scale single monitor
  59. local minSize = (math.min(mw,mh) / 2) - 2
  60.  
  61. -- clock radius in character. 18 is good for a 6x6 advanced monitor
  62. -- or you can use minSize which attempts to fit
  63. -- to monitor size automatically
  64. local nClockRad = minSize
  65.  
  66. -- set up the screens
  67. term.clear()
  68. term.setCursorPos(1,1)
  69. print("Clock by Ramdor (c) 2013")
  70. print("Press 'Q' to terminate.")
  71. term.redirect(monitor)
  72. term.setBackgroundColor(nBackColour)
  73. term.clear()
  74.  
  75. -- some variables
  76. local h = 0 -- parsed hour
  77. local m = 0 -- parsed minute
  78. local nOldHX = -1
  79. local nOldHY = -1
  80. local nOldMX = -1
  81. local nOldMY = -1
  82.  
  83. local function plot(s,x,y)
  84.   term.setCursorPos(x,y)
  85.   term.write(s)
  86. end
  87.  
  88. -- the clock face ticks
  89. local function ticks(nW,nH)
  90.   local nIndex
  91.   local x
  92.   local y
  93.   local xi
  94.   local yi
  95.   local nInRadius = nClockRad-(nClockRad/4)
  96.   local nOutRadius = nClockRad-2
  97.  
  98.   local nxOutRad = nOutRadius + (nOutRadius/2)
  99.   local nyOutRad = nOutRadius
  100.   local nxInRad = nInRadius + (nInRadius/2)
  101.   local nyInRad = nInRadius
  102.  
  103.   for nIndex=0,359,(360/12) do
  104.     x = nW + math.sin(math.rad(nIndex)) * nxOutRad
  105.     y = nH + math.cos(math.rad(nIndex)) * nyOutRad
  106.  
  107.     xi = nW + math.sin(math.rad(nIndex)) * nxInRad
  108.     yi = nH + math.cos(math.rad(nIndex)) * nyInRad
  109.    
  110.     paintutils.drawLine(xi,yi,x,y,nTickColour)
  111.   end
  112. end
  113.  
  114. -- draw the face (circle)
  115. -- by working out a quarter of the points
  116. -- then drawing lines from oposite quarter
  117. -- results in much faster circle code
  118. local function face(nW,nH,nRadius)
  119.   local nIndex
  120.   local x
  121.   local y
  122.   local nxRad = nRadius + (nRadius/2)
  123.   local nyRad = nRadius
  124.   local nOldX = -1
  125.   local nOldY = -1
  126.  
  127.   local points = {}
  128.   local xy
  129.   local n = 1
  130.  
  131.   for nIndex=0,89 do
  132.     x = math.sin(math.rad(nIndex)) * nxRad
  133.     y = math.cos(math.rad(nIndex)) * nyRad
  134.     x = math.floor(x)
  135.     y = math.floor(y)
  136.  
  137.     -- only store positions if they are different from last time  
  138.     if x~=nOldX or y~=nOldY then
  139.       xy = {}
  140.       xy[1] = x
  141.       xy[2] = y
  142.       points[n] = xy
  143.      
  144.       if y~=nOldY or not bFaceFilled then
  145.         n=n+1
  146.       end
  147.  
  148.       nOldX = x
  149.       nOldY = y
  150.     end
  151.   end
  152.  
  153.   -- plot the circle
  154.   for nIndex=1,#points do
  155.     x = points[nIndex][1]
  156.     y = points[nIndex][2]
  157.  
  158.     if bFaceFilled then
  159.       paintutils.drawLine(nW-x,nH+y,nW+x,nH+y,nFaceColour)
  160.       paintutils.drawLine(nW-x,nH-y,nW+x,nH-y,nFaceColour)
  161.     else
  162.       paintutils.drawPixel(nW-x,nH+y,nFaceColour)
  163.       paintutils.drawPixel(nW+x,nH+y,nFaceColour)
  164.       paintutils.drawPixel(nW-x,nH-y,nFaceColour)
  165.       paintutils.drawPixel(nW+x,nH-y,nFaceColour)
  166.     end
  167.   end
  168. end
  169.  
  170. -- parse the time into H and M
  171. -- these are stored globally in h and m
  172. local function parseTime()
  173.   local t = os.time()
  174.   local sT = textutils.formatTime(t, true)
  175.  
  176.   local n = string.find(sT, ":")
  177.  
  178.   if(n>0) then
  179.     h = tonumber(string.sub(sT,1,n-1))
  180.     m = tonumber(string.sub(sT,n+1))
  181.   end
  182. end
  183.  
  184. -- plot minute hand
  185. -- it removes the previous minute hand
  186. -- then draws the new one
  187. local function plotM(nW,nH,nX,nY)
  188.   local nTmpColour
  189.  
  190.   if(nOldMX==nX and nOldMY==nY) then
  191.     return
  192.   end
  193.  
  194.   -- remove previous by drawing it again
  195.   -- in the face colour.  Also remove the
  196.   -- hand tag
  197.   if(nOldMX~=-1) then
  198.     if bFaceFilled then
  199.       nTmpColour = nFaceColour
  200.     else
  201.       nTmpColour = nBackColour
  202.     end
  203.     paintutils.drawLine(nW,nH,nOldMX,nOldMY,nTmpColour)
  204.      
  205.     if(bShowMinuteChar) then
  206.       plot(".",nOldMX,nOldMY)
  207.     end
  208.   end
  209.  
  210.   nOldMX = nX
  211.   nOldMY = nY
  212.  
  213.   paintutils.drawLine(nW,nH,nX,nY,nHandColour)
  214.  
  215.   -- draw the centre O
  216.   term.setTextColor(colors.black)
  217.   term.setBackgroundColor(colors.lightGray)
  218.   plot("O",nW,nH)
  219.  
  220.   if(bShowMinuteChar) then
  221.     -- draw the minute hand tag
  222.     plot("M",nX,nY)
  223.   end
  224. end
  225.  
  226. -- plot hour hand
  227. -- it removes the previous hour hand
  228. -- then draws the new one
  229. local function plotH(nW,nH,nX,nY)
  230.   local nTmpColour
  231.   if(nOldHX==nX and nOldHY==nY) then
  232.     return
  233.   end
  234.  
  235.   -- remove previous by drawing it again
  236.   -- in the face colour.  Also remove the
  237.   -- hand tag
  238.   if(nOldHX~=-1) then
  239.     if bFaceFilled then
  240.       nTmpColour = nFaceColour
  241.     else
  242.       nTmpColour = nBackColour
  243.     end
  244.     paintutils.drawLine(nW,nH,nOldHX,nOldHY,nTmpColour)
  245.  
  246.     if(bShowHourChar) then
  247.       plot(".",nOldHX,nOldHY)
  248.     end
  249.   end
  250.  
  251.   nOldHX = nX
  252.   nOldHY = nY
  253.  
  254.   paintutils.drawLine(nW,nH,nX,nY,nHandColour)
  255.  
  256.   if(bShowHourChar) then
  257.     -- draw the hour hand tag
  258.     term.setTextColor(colors.black)
  259.     term.setBackgroundColor(colors.lightGray)
  260.     plot("H",nX,nY)
  261.   end
  262. end
  263.  
  264. local fH
  265. local fM
  266. local fXH
  267. local fYH
  268. local fXM
  269. local fYM
  270. local nyMRadius = nClockRad - (nClockRad / 4)
  271. local nyHRadius = nClockRad - (nClockRad / 2)
  272.  
  273. local nxMRadius = nyMRadius + (nyMRadius / 2)
  274. local nxHRadius = nyHRadius + (nyHRadius / 2)
  275. local nW, nH = term.getSize()
  276.  
  277. nW = (nW / 2)+1
  278. nH = (nH / 2)+1
  279.  
  280. -- plot the circle
  281. face(nW,nH,nClockRad + 1)
  282.  
  283. local bRunning = true
  284. local nTimer
  285. nTimer = os.startTimer(0.25) -- the timer interval to update the clock
  286.  
  287. while(bRunning) do
  288.   parseTime()
  289.  
  290.   fH = (((h % 12)/12) + (m/60/12)) * 360
  291.   fM = (m/60) * 360
  292.  
  293.   -- shift by half a circle
  294.   fH = fH + 180
  295.   fM = fM + 180
  296.  
  297.   fXH = math.sin(math.rad(-fH))
  298.   fYH = math.cos(math.rad(fH))
  299.   fXM = math.sin(math.rad(-fM))
  300.   fYM = math.cos(math.rad(fM))
  301.  
  302.   plotH(nW,nH,  nW + fXH * nxHRadius, nH + fYH * nyHRadius)
  303.   plotM(nW,nH, nW + fXM * nxMRadius, nH + fYM * nyMRadius)
  304.  
  305.   -- draw the ticks on
  306.   ticks(nW,nH)
  307.  
  308.   local event, param1 = os.pullEvent()
  309.  
  310.   while (not (event=="timer" and param1==nTimer) and event~="char") do
  311.     event, param1 = os.pullEvent()
  312.   end
  313.  
  314.   if(event=="char") then
  315.      if(param1=="q" or param1=="Q") then
  316.        bRunning=false
  317.      end
  318.   elseif(event=="timer" and param1==nTimer) then
  319.      -- timer timed out, lets start again
  320.      nTimer = os.startTimer(0.25)
  321.   end
  322. end
  323.  
  324. term.restore()
  325. print("Ended.")
Advertisement
Add Comment
Please, Sign In to add comment