#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# Another analog clock

edited March 2012 Posts: 381

Found 2 analog clock sample codes in this forum, but both using translate() and rotate() functions which make the line looks jiggy and a bit pixelated. At least on my iPad 1. So here I offer another way to draw analog clock using simple trigonometry so the hour hands look smooth. Here's the code...

``````abs = math.abs
sin = math.sin
cos = math.cos

function circle(x,y,r)
ellipse(x,y,r,r)
end

function getLocalDateTime()
datetime = os.date("*t")
return datetime
end

function clock12ToDeg(clockVal)
if clockVal >= 12 then clockVal = clockVal-12 end
degVal = 90 - (30 * clockVal)
return degVal
end

function clock60ToDeg(clockVal)
if clockVal >= 60 then clockVal = clockVal-60 end
degVal = 90 - (6 * clockVal)
return degVal
end

function degToClock(degree, r,x,y)
if x == nil then x = clockX end
if y == nil then y = clockY end
if r == nil then r = clockR end
-- get position of a clock hand's degree
mx = x + r * cos(rad(degree))
my = y + r * sin(rad(degree))
return mx, my
end

function clockMode(sweep)
if sweep then
if last_sec == second then
sweepStep = sweepStep + 1
else
maxStep   = sweepStep + 1
sweepStep = 0
last_sec  = second
end
else
sweepStep = 0
end
end

function drawNumbers()
textMode(CENTER)
font("AmericanTypewriter-CondensedBold")
fontSize(digitSize)
local w,h = textSize('0')
-- adjust text position to clock size
local r = clockR - clockR/10 - borderThick
local x = clockX
local y = clockY
-- draw 12 clock numbers
for i = 5, 55, 5 do
local x,y = degToClock(clock60ToDeg(i),r,x,y)
text(i/5,x,y)
end
text('12', degToClock(clock60ToDeg(0),r,x,y))
end

function drawDial()
-- draw clock border
fill(backColor)
stroke(borderColor)
strokeWidth(borderThick)
circle(clockX, clockY, clockR + borderThick/2 + clockR/10)
-- draw clock dot marks
fill(clockColor)
stroke(backColor)
noStroke()
local dx,dy
for i = 0, 59 do
dx,dy = degToClock(clock60ToDeg(i))
if i % 5 ~= 0 then
circle(dx,dy,clockR/100) -- small tick
else
circle(dx,dy,2.5*clockR/100) -- big tick
end
end
drawNumbers()
end

function drawHour(hourVal)
local r = clockR*2/3 - borderThick
strokeWidth(hourThick)
stroke(hourColor)
line(clockX, clockY, degToClock(clock12ToDeg(hourVal),r))
end

function drawMinute(minuteVal)
local r = clockR - borderThick*2
strokeWidth(minuteThick)
stroke(minuteColor)
line(clockX, clockY, degToClock(clock60ToDeg(minuteVal),r))
end

function drawSecond(secondVal)
-- movement mode
if isSweep then
secondVal = secondVal + sweepStep/maxStep
end
-- hand
local r = clockR
strokeWidth(secondThick)
stroke(secondColor)
line(clockX, clockY, degToClock(clock60ToDeg(secondVal),r))
-- tail
local r = clockR/5
strokeWidth(secondThick*2)
line(clockX, clockY, degToClock(clock60ToDeg(secondVal+30),r))
-- center
fill(secondColor)
circle(clockX, clockY, secondThick*3)
end

borderThick = clockR/30
hourThick   = clockR/10
minuteThick = clockR/15
secondThick = clockR/30
digitSize = clockR/5
end

function setup()
-- clock size
clockX = WIDTH/2
clockY = HEIGHT/2
clockR = 200 --play with this value to see it auto-adjust
-- clock mode setup
isSweep   = true
maxStep   = 30
sweepStep = 0
last_sec  = getLocalDateTime().sec
iparameter("quartz",0,1,0)
-- clock color
backColor   = color(192,192,192,255)
clockColor  = color(  0,  0,  0,255)
borderColor = color(255,255,255,255)
hourColor   = color(  0,  0,192,255)
minuteColor = color(  0,  0,128,255)
secondColor = color(192,  0,  0,255)
-- param and watch
iparameter("clockR",50,300,clockR)
--watch("second")
--watch("maxStep")
end

function draw()
background(0)
smooth()
-- get local time
datetime = getLocalDateTime()
second   = datetime.sec
-- set clock mode
isSweep  = (quartz == 0)
clockMode(isSweep)
-- draw clock
drawDial()
drawHour(hour + minute/60)
drawMinute(minute + second/60)
drawSecond(second)
end
``````

Any suggestions are welcome. Hope this code will be useful. Thank you.

Tagged:

• edited March 2012 Posts: 381

And here is the video of it:

• Posts: 384

Hi @Bee, my son loved your clock! We added a tick sound. It would be great but tricky to have the hands moveable through touch... !

• Posts: 381

Thanks @Fred. Glad to know my simple little code got another fan. The other fan is my own kid. I use this to teach him reading clock, using the parameters. Indeed, it's tricky to move the hands by touch.

• Posts: 176

I really like it, but when I watched the video, the clock was off by about 25 minutes.

Just kidding.

• Posts: 381

Thank you. Really? In the video, I made it read the local time. Maybe you should check your clock setting.

Oh, sorry... Just read it that you're kidding. So am I.