View difference between Paste ID: dQ6XAtDn and LGNUpDzz
SHOW: | | - or go back to the newest paste.
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.")