clockface: add minute hand tests
This commit is contained in:
parent
5a62fef4f3
commit
a4531bde4c
@ -14,6 +14,7 @@ type Point struct {
|
||||
}
|
||||
|
||||
const (
|
||||
minuteHandLength = 80
|
||||
secondHandLength = 90
|
||||
clockCentreX = 150
|
||||
clockCentreY = 150
|
||||
@ -34,12 +35,13 @@ const svgEnd = `</svg>`
|
||||
func SVGWriter(w io.Writer, t time.Time) {
|
||||
io.WriteString(w, svgStart)
|
||||
io.WriteString(w, bezel)
|
||||
SecondHand(w, t)
|
||||
secondHand(w, t)
|
||||
minuteHand(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) {
|
||||
func secondHand(w io.Writer, t time.Time) {
|
||||
p := secondHandPoint(t)
|
||||
p = Point{p.X * secondHandLength, p.Y * secondHandLength} // scale
|
||||
p = Point{p.X, -p.Y} // flip
|
||||
@ -52,30 +54,39 @@ func SecondHand(w io.Writer, t time.Time) {
|
||||
)
|
||||
}
|
||||
|
||||
// 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)
|
||||
p = Point{p.X * minuteHandLength, p.Y * minuteHandLength} // scale
|
||||
p = Point{p.X, -p.Y} // flip
|
||||
p = Point{p.X + clockCentreX, p.Y + clockCentreY} // translate
|
||||
fmt.Fprintf(
|
||||
w,
|
||||
`<line x1="150" y1="150" x2="%f" y2="%f" style="fill:none;stroke:#f00;stroke-width:3px;"/>`,
|
||||
p.X,
|
||||
p.Y,
|
||||
)
|
||||
}
|
||||
|
||||
func minutesInRadians(t time.Time) float64 {
|
||||
return (secondsInRadians(t) / 60) + math.Pi/(30/float64(t.Minute()))
|
||||
}
|
||||
|
||||
func minuteHandPoint(t time.Time) Point {
|
||||
angle := minutesInRadians(t)
|
||||
x := math.Sin(angle)
|
||||
y := math.Cos(angle)
|
||||
|
||||
return Point{x, y}
|
||||
return angleToPoint(minutesInRadians(t))
|
||||
}
|
||||
|
||||
func secondsInRadians(t time.Time) float64 {
|
||||
// XXX:Wanted 3.141592653589793 radians, but got 3.1415926535897936
|
||||
// return float64(t.Second()) * (math.Pi / 30)
|
||||
|
||||
return math.Pi / (30 / float64(t.Second()))
|
||||
}
|
||||
|
||||
func secondHandPoint(t time.Time) Point {
|
||||
angle := secondsInRadians(t)
|
||||
return angleToPoint(secondsInRadians(t))
|
||||
}
|
||||
|
||||
func angleToPoint(angle float64) Point {
|
||||
x := math.Sin(angle)
|
||||
y := math.Cos(angle)
|
||||
|
||||
// XXX: Wanted {0 -1} Point, but got {1.2246467991473515e-16 -1}
|
||||
return Point{x, y}
|
||||
}
|
||||
|
@ -59,6 +59,34 @@ func TestSVGWriterSecondHand(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSVGWriterMinuteHand(t *testing.T) {
|
||||
cases := []struct {
|
||||
time time.Time
|
||||
line Line
|
||||
}{
|
||||
{simpleTime(0, 0, 0), Line{150, 150, 150, 70}},
|
||||
// {simpleTime(0, 0, 30), Line{150, 150, 150, 240}},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(testName(c.time), func(t *testing.T) {
|
||||
b := bytes.Buffer{}
|
||||
SVGWriter(&b, c.time)
|
||||
|
||||
svg := Svg{}
|
||||
xml.Unmarshal(b.Bytes(), &svg)
|
||||
|
||||
if !containsLine(c.line, svg.Line) {
|
||||
t.Errorf(
|
||||
"Expected to find the minute hand line %+v in the SVG lines %v",
|
||||
c.line,
|
||||
svg.Line,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func containsLine(l Line, ls []Line) bool {
|
||||
for _, line := range ls {
|
||||
if line == l {
|
||||
|
Loading…
Reference in New Issue
Block a user