From a1835a532d89360797729088b347cde92a678df7 Mon Sep 17 00:00:00 2001 From: Will Charczuk Date: Mon, 5 Sep 2016 14:03:20 -0700 Subject: [PATCH] bounded rotate works, ish --- _examples/text_rotation/main.go | 41 ++++++++++++++++++++++----------- box.go | 16 ++++++++----- box_test.go | 8 +++---- draw.go | 16 +++++++++++++ math.go | 2 +- raster_renderer.go | 2 +- vector_renderer.go | 2 +- 7 files changed, 60 insertions(+), 27 deletions(-) diff --git a/_examples/text_rotation/main.go b/_examples/text_rotation/main.go index c2a2b6c..84367a6 100644 --- a/_examples/text_rotation/main.go +++ b/_examples/text_rotation/main.go @@ -24,12 +24,12 @@ func drawChart(res http.ResponseWriter, req *http.Request) { TextRotationDegrees: 45.0, }, Ticks: []chart.Tick{ - {0.0, "0.00"}, - {2.0, "2.00"}, - {4.0, "4.00"}, - {6.0, "6.00"}, - {8.0, "Eight"}, - {10.0, "Ten"}, + {Value: 0.0, Label: "0.00"}, + {Value: 2.0, Label: "2.00"}, + {Value: 4.0, Label: "4.00"}, + {Value: 6.0, Label: "6.00"}, + {Value: 8.0, Label: "Eight"}, + {Value: 10.0, Label: "Ten"}, }, }, XAxis: chart.XAxis{ @@ -40,12 +40,12 @@ func drawChart(res http.ResponseWriter, req *http.Request) { TextRotationDegrees: 45.0, }, Ticks: []chart.Tick{ - {0.0, "0.00"}, - {2.0, "2.00"}, - {4.0, "4.00"}, - {6.0, "6.00"}, - {8.0, "Eight"}, - {10.0, "Ten"}, + {Value: 0.0, Label: "0.00"}, + {Value: 2.0, Label: "2.00"}, + {Value: 4.0, Label: "4.00"}, + {Value: 6.0, Label: "6.00"}, + {Value: 8.0, Label: "Eight"}, + {Value: 10.0, Label: "Ten"}, }, }, Series: []chart.Series{ @@ -60,15 +60,28 @@ func drawChart(res http.ResponseWriter, req *http.Request) { graph.Elements = []chart.Renderable{ func(r chart.Renderer, cb chart.Box, defaults chart.Style) { - b := chart.Box{50, 50, 90, 110} + b := chart.Box{Top: 50, Left: 50, Right: 150, Bottom: 300} + + cx, cy := b.Center() + + chart.Draw.Box(r, chart.Box{Top: cy - 2, Left: cx - 2, Right: cx + 2, Bottom: cy + 2}, chart.Style{ + StrokeWidth: 2, + StrokeColor: chart.ColorBlack, + }) + chart.Draw.Box(r, b, chart.Style{ StrokeWidth: 2, StrokeColor: chart.ColorBlue, }) - chart.Draw.Box(r, b.Rotate(chart.Math.DegreesToRadians(45)), chart.Style{ + chart.Draw.Box(r, b.BoundedRotate(chart.Math.DegreesToRadians(45)), chart.Style{ StrokeWidth: 2, StrokeColor: chart.ColorRed, }) + + chart.Draw.BoxRotated(r, b, chart.Math.DegreesToRadians(45), chart.Style{ + StrokeWidth: 2, + StrokeColor: chart.ColorOrange, + }) }, } graph.Render(chart.PNG, res) diff --git a/box.go b/box.go index 0b55023..450ad4c 100644 --- a/box.go +++ b/box.go @@ -220,16 +220,20 @@ func (b Box) OuterConstrain(bounds, other Box) Box { return newBox } -// Rotate rotates a box's corners by a given radian rotation angle. -func (b Box) Rotate(radians float64) Box { +// BoundedRotate rotates a box's corners by a given radian rotation angle +// and returns the maximum bounds or clipping rectangle. +func (b Box) BoundedRotate(radians float64) Box { cx, cy := b.Center() ltx, lty := Math.RotateCoordinate(cx, cy, b.Left, b.Top, radians) + lbx, lby := Math.RotateCoordinate(cx, cy, b.Left, b.Bottom, radians) + rtx, rty := Math.RotateCoordinate(cx, cy, b.Right, b.Top, radians) rbx, rby := Math.RotateCoordinate(cx, cy, b.Right, b.Bottom, radians) + return Box{ - Left: ltx, - Top: lty, - Right: rbx, - Bottom: rby, + Left: Math.MinInt(ltx, lbx), + Top: Math.MinInt(lty, rty), + Right: Math.MaxInt(rtx, rbx), + Bottom: Math.MaxInt(lby, rby), } } diff --git a/box_test.go b/box_test.go index 020dc22..39503ab 100644 --- a/box_test.go +++ b/box_test.go @@ -158,7 +158,7 @@ func TestBoxCenter(t *testing.T) { assert.Equal(20, cy) } -func TestBoxRotate(t *testing.T) { +func TestBoxBoundedRotate(t *testing.T) { assert := assert.New(t) b := Box{ @@ -167,9 +167,9 @@ func TestBoxRotate(t *testing.T) { Right: 20, Bottom: 10, } - rotated := b.Rotate(Math.DegreesToRadians(45)) + rotated := b.BoundedRotate(Math.DegreesToRadians(45)) assert.Equal(1, rotated.Top) - assert.Equal(4, rotated.Left) - assert.Equal(10, rotated.Right) + assert.Equal(5, rotated.Left) + assert.Equal(19, rotated.Right) assert.Equal(14, rotated.Bottom) } diff --git a/draw.go b/draw.go index 25ca38c..ba27e18 100644 --- a/draw.go +++ b/draw.go @@ -219,6 +219,22 @@ func (d draw) Box(r Renderer, b Box, s Style) { r.FillStroke() } +func (d draw) BoxRotated(r Renderer, b Box, thetaRadians float64, s Style) { + s.WriteToRenderer(r) + cx, cy := b.Center() + ltx, lty := Math.RotateCoordinate(cx, cy, b.Left, b.Top, thetaRadians) + lbx, lby := Math.RotateCoordinate(cx, cy, b.Left, b.Bottom, thetaRadians) + rtx, rty := Math.RotateCoordinate(cx, cy, b.Right, b.Top, thetaRadians) + rbx, rby := Math.RotateCoordinate(cx, cy, b.Right, b.Bottom, thetaRadians) + + r.MoveTo(ltx, lty) + r.LineTo(rtx, rty) + r.LineTo(rbx, rby) + r.LineTo(lbx, lby) + r.Close() + r.FillStroke() +} + // DrawText draws text with a given style. func (d draw) Text(r Renderer, text string, x, y int, style Style) { style.GetTextOptions().WriteToRenderer(r) diff --git a/math.go b/math.go index 8d745a1..f280c17 100644 --- a/math.go +++ b/math.go @@ -225,7 +225,7 @@ func (m mathUtil) RotateCoordinate(cx, cy, x, y int, thetaRadians float64) (rx, tempX, tempY := float64(x-cx), float64(y-cy) rotatedX := tempX*math.Cos(thetaRadians) - tempY*math.Sin(thetaRadians) rotatedY := tempX*math.Sin(thetaRadians) + tempY*math.Cos(thetaRadians) - rx = int(rotatedX) + cy + rx = int(rotatedX) + cx ry = int(rotatedY) + cy return } diff --git a/raster_renderer.go b/raster_renderer.go index fecd851..37ca0dc 100644 --- a/raster_renderer.go +++ b/raster_renderer.go @@ -187,7 +187,7 @@ func (rr *rasterRenderer) MeasureText(body string) Box { return textBox } - return textBox.Rotate(*rr.rotateRadians) + return textBox.BoundedRotate(*rr.rotateRadians) } // SetTextRotation sets a text rotation. diff --git a/vector_renderer.go b/vector_renderer.go index 4afad26..f9883b1 100644 --- a/vector_renderer.go +++ b/vector_renderer.go @@ -170,7 +170,7 @@ func (vr *vectorRenderer) MeasureText(body string) (box Box) { if vr.c.textTheta == nil { return } - box = box.Rotate(*vr.c.textTheta) + box = box.BoundedRotate(*vr.c.textTheta) } return }