From 71ab8b249dbd64b4fd0c8a85a676093c427fcc40 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Fri, 21 Dec 2012 00:34:30 -0500 Subject: [PATCH] Futzing around more with drawing API including implementation of `Rectangle(...)` and supporting methods, making `Draw()` a method of `Canvas`, other crap. --- algs4/src/go/algs4/canvas.go | 110 +++++++++++++++++++++++++++++++++-- algs4/src/go/algs4/draw.go | 32 +--------- 2 files changed, 106 insertions(+), 36 deletions(-) diff --git a/algs4/src/go/algs4/canvas.go b/algs4/src/go/algs4/canvas.go index 32f6a22..f79d93f 100644 --- a/algs4/src/go/algs4/canvas.go +++ b/algs4/src/go/algs4/canvas.go @@ -1,31 +1,131 @@ package algs4 import ( + "errors" + "fmt" "image" + "image/draw" + "math" + "os" + + "code.google.com/p/x-go-binding/ui" + "code.google.com/p/x-go-binding/ui/x11" ) var ( - DefaultCanvas = NewCanvas(512, 512) + DefaultCanvas, DefaultCanvasError = NewCanvas(512, 512, + float64(0.0), float64(1.0), float64(0.0), float64(1.0)) + + halfWidthNegativeError = errors.New("half width can't be negative") + halfHeightNegativeError = errors.New("half height can't be negative") ) +func init() { + if DefaultCanvasError != nil { + fmt.Fprintf(os.Stderr, + "Failed to initialize DefaultCanvas: %v\n", DefaultCanvasError) + panic(DefaultCanvasError) + } +} + type Canvas struct { Height int Width int + Xmin float64 + Xmax float64 + Ymin float64 + Ymax float64 + img *image.RGBA + window ui.Window } -func NewCanvas(height, width int) *Canvas { - return &Canvas{ +func NewCanvas(height, width int, xmin, xmax, ymin, ymax float64) (*Canvas, error) { + window, err := x11.NewWindow() + if err != nil { + return nil, err + } + + canvas := &Canvas{ Height: height, Width: width, + Xmin: xmin, + Xmax: xmax, + Ymin: ymin, + Ymax: ymax, + img: image.NewRGBA(image.Rect(0, 0, height, width)), + window: window, } + + return canvas, nil } func (me *Canvas) Image() *image.RGBA { return me.img } -func (me *Canvas) Rectangle(x, y, halfWidth, halfHeight float64) { - return +func (me *Canvas) Bounds() image.Rectangle { + return me.img.Bounds() +} + +func (me *Canvas) Rectangle(x, y, halfWidth, halfHeight float64) error { + if halfWidth < 0 { + return halfWidthNegativeError + } + + if halfHeight < 0 { + return halfHeightNegativeError + } + + f2 := float64(2.0) + + xs := me.scaleX(x) + ys := me.scaleY(y) + ws := me.factorX(f2 * halfWidth) + hs := me.factorY(f2 * halfHeight) + + if ws <= 1 && hs <= 1 { + return me.Pixel(x, y) + } + + draw.Draw(me.img, image.Rect(int(xs-ws/f2), int(ys-hs/f2), int(ws), int(hs)), + &image.Uniform{image.White}, image.ZP, draw.Src) + + return nil +} + +func (me *Canvas) Pixel(x, y float64) error { + return nil +} + +func (me *Canvas) Draw() error { + draw.Draw(me.window.Screen(), me.window.Screen().Bounds(), me.img, image.ZP, draw.Src) + me.window.FlushImage() + + for evt := range me.window.EventChan() { + switch evt := evt.(type) { + case ui.KeyEvent: + if evt.Key == ' ' { + return nil + } + } + } + return nil +} + +func (me *Canvas) scaleX(x float64) float64 { + return float64(me.Width) * (x - me.Xmin) / (me.Xmax - me.Xmin) +} + +func (me *Canvas) scaleY(y float64) float64 { + return float64(me.Height) * (me.Ymax - y) / (me.Ymax - me.Ymin) +} + +func (me *Canvas) factorX(w float64) float64 { + return w * float64(me.Width) / math.Abs(me.Xmax-me.Xmin) +} + +func (me *Canvas) factorY(h float64) float64 { + return h * float64(me.Height) / math.Abs(me.Ymax-me.Ymin) } diff --git a/algs4/src/go/algs4/draw.go b/algs4/src/go/algs4/draw.go index d2dd307..71fe894 100644 --- a/algs4/src/go/algs4/draw.go +++ b/algs4/src/go/algs4/draw.go @@ -1,35 +1,5 @@ package algs4 -import ( - "errors" - "image" - "image/draw" - - "code.google.com/p/x-go-binding/ui" - "code.google.com/p/x-go-binding/ui/x11" -) - func Draw() error { - img := DefaultCanvas.Image() - if img == nil { - return errors.New("DefaultCanvas's image is nil!") - } - - w, err := x11.NewWindow() - if err != nil { - return err - } - - draw.Draw(w.Screen(), w.Screen().Bounds(), img, image.ZP, draw.Src) - w.FlushImage() - - for evt := range w.EventChan() { - switch evt := evt.(type) { - case ui.KeyEvent: - if evt.Key == ' ' { - return nil - } - } - } - return nil + return DefaultCanvas.Draw() }