ramdor

Clock

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