diff --git a/clock.lua b/clock.lua index 64cb895..f6a2ef2 100644 --- a/clock.lua +++ b/clock.lua @@ -1,26 +1,50 @@ -local MAX_SECONDS = 60 * 60 * 12 +local MAX_MINUTES = 60 * 12 local Time = {} Time.__index = Time -function Time:new(hour, minute) +local function newTimeRaw(rawMinutes) local t = { - hour = (hour or 12), - minute = (minute or 0) + rawminutes = rawMinutes % MAX_MINUTES } - return setmetatable(t, self) + return setmetatable(t, Time) end -function Time:getHour() - return self.hour +function Time:new(hour, minute) + return newTimeRaw((hour or 12) % 12 * 60 + (minute or 0)) end -function Time:getMinute() - return self.minute +function Time:get() + local h = math.floor(self.rawminutes / 60 % 12) + if h == 0 then h = 12 end + local m = self.rawminutes % 60 + return h, m +end + +function Time:getHoursSinceTwelve() + local h = self.rawminutes / 60 + if h < 1 then h = h + 12 end + return h +end + +function Time:addMinutes(minutes) + return newTimeRaw(self.rawminutes + minutes) end function Time:fmt() - return string.format("%2d:%02d", self.hour, self.minute) + local h, m = self:get() + return string.format("%2d:%02d", h, m) +end + + +local function pointToTurns(x, y) + local rawTurns = math.atan2(y, x) / 2 / math.pi + local _, clockTurns = math.modf(rawTurns + 1.25) + return clockTurns +end + +local function turnsToRads(turns) + return turns * 2 * math.pi - 0.5 * math.pi end @@ -30,28 +54,15 @@ Hand.__index = Hand function Hand:new(length, color) local h = { length = (length or 10), - color = (color or {1,1,1}), - turns = 0 + color = (color or {1,1,1}) } return setmetatable(h, self) end -function Hand:setTurns(turns) - self.turns = turns -end - -function Hand:getTurns() - return self.turns -end - -function Hand:draw() --- local turns = sec_elapsed / self.sec_per_turn --- if self.ticks_per_turn then --- turns = math.floor(turns * self.ticks_per_turn) / self.ticks_per_turn --- end +function Hand:draw(turns) love.graphics.push("all") love.graphics.setColor(unpack(self.color)) - love.graphics.rotate(2 * math.pi * (self.turns + 0.25)) + love.graphics.rotate(turnsToRads(turns) + 0.5 * math.pi) love.graphics.rectangle("fill", -10, 10, 20, -self.length) love.graphics.pop() end @@ -63,7 +74,8 @@ Clock.__index = Clock function Clock:new(time, diameter, transform) local c = { time = (time or Time:new()), - minuteHand = Hand:new(240, {1,0,0}, 60*60), + minuteHand = Hand:new(240, {1,0,0}), + hourHand = Hand:new(180, {0,0.5,0.5}), dragging = false, transform = transform or love.math.newTransform(), radius = diameter and diameter/2 or 300 @@ -80,15 +92,15 @@ function Clock:getTime() end function Clock:draw() - -- debug - love.graphics.print(self.minuteHand:getTurns(), 10, 50) - -- end debug + local _, m = self.time:get() + local h = self.time:getHoursSinceTwelve() love.graphics.push("all") love.graphics.applyTransform(self.transform) love.graphics.setColor(0.5, 0.5, 0.5) love.graphics.circle("fill", 0, 0, self.radius) - self.minuteHand:draw() + self.minuteHand:draw(m / 60) + self.hourHand:draw(h / 12) love.graphics.pop() end @@ -100,8 +112,16 @@ end local function clockPointAt(clock, x, y) local localX, localY = clock.transform:inverseTransformPoint(x, y) - local turns = math.atan2(localY, localX) / 2 / math.pi - clock.minuteHand:setTurns(turns) + local minutes = pointToTurns(localX, localY) * 60 + local _, oldMinutes = clock.time:get() + local dMinutes = minutes - oldMinutes + -- Adjust for rolling over + if dMinutes < -30 then + dMinutes = dMinutes + 60 + elseif dMinutes > 30 then + dMinutes = dMinutes - 60 + end + clock.time = clock.time:addMinutes(dMinutes) end function Clock:movemouse(x, y)