clockface: add minute hand tests
This commit is contained in:
		@ -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 {
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user