package clockface
import (
"fmt"
"io"
"math"
"time"
)
// Point represents a two-dimentional Cartesian coordinate
type Point struct {
X float64
Y float64
}
const (
hourHandLength = 50
minuteHandLength = 80
secondHandLength = 90
clockCentreX = 150
clockCentreY = 150
)
const svgStart = `
`
func SVGWriter(w io.Writer, t time.Time) {
io.WriteString(w, svgStart)
io.WriteString(w, bezel)
secondHand(w, t)
minuteHand(w, t)
hourHand(w, t)
io.WriteString(w, svgEnd)
}
// SecondHand is the unit vector of the second hand of an analogue clock at the time `t` represented as a Point
func secondHand(w io.Writer, t time.Time) {
p := secondHandPoint(t)
makeHand(w, secondHandLength, p)
}
// MinuteHand is the unit vector of the minute hand of an analogue clock at the time `t` represented as a Point
func minuteHand(w io.Writer, t time.Time) {
p := minuteHandPoint(t)
makeHand(w, minuteHandLength, p)
}
// MinuteHand is the unit vector of the minute hand of an analogue clock at the time `t` represented as a Point
func hourHand(w io.Writer, t time.Time) {
p := hourHandPoint(t)
makeHand(w, hourHandLength, p)
}
func makeHand(w io.Writer, length float64, p Point) {
p = Point{p.X * length, p.Y * length} // scale
p = Point{p.X, -p.Y} // flip
p = Point{p.X + clockCentreX, p.Y + clockCentreY} // translate
fmt.Fprintf(
w,
``,
p.X,
p.Y,
)
}
func hoursInRadians(t time.Time) float64 {
return (minutesInRadians(t) / 12) + math.Pi/(6/float64(t.Hour()%12))
}
func hourHandPoint(t time.Time) Point {
return angleToPoint(hoursInRadians(t))
}
func minutesInRadians(t time.Time) float64 {
return (secondsInRadians(t) / 60) + math.Pi/(30/float64(t.Minute()))
}
func minuteHandPoint(t time.Time) Point {
return angleToPoint(minutesInRadians(t))
}
func secondsInRadians(t time.Time) float64 {
return math.Pi / (30 / float64(t.Second()))
}
func secondHandPoint(t time.Time) Point {
return angleToPoint(secondsInRadians(t))
}
func angleToPoint(angle float64) Point {
x := math.Sin(angle)
y := math.Cos(angle)
return Point{x, y}
}