//planets is an exploration of scale func planets(width, height int, message string) { w := float64(width) h := float64(height) y := h / 2 margin := 100.0 minsize := 7.0 labeloc := 100.0 bgcolor := "black" labelcolor := "white" maxsize := (h / 2) * 0.05 origin := sun.distance mostDistant := neptune.distance firstSize := mercury.radius lastSize := neptune.radius openvg.Start(width, height) openvg.BackgroundColor(bgcolor) for _, p := range SolarSystem { x := vmap(p.distance, origin, mostDistant, margin, w-margin) r := vmap(p.radius, firstSize, lastSize, minsize, maxsize) if p.name == "Sun" { openvg.FillRGB(p.color.Red, p.color.Green, p.color.Blue, 1) openvg.Circle(margin-(r/2), y, r) } else { light(x, y, r, p.color) openvg.Circle(x, y, r) if p.name == "Saturn" { ringwidth := r * 2.35 // Saturn's rings are over 2x the planet radius openvg.StrokeWidth(3) openvg.StrokeRGB(p.color.Red, p.color.Green, p.color.Blue, 1) openvg.Line((x - ringwidth/2), y, (x + ringwidth/2), y) openvg.StrokeWidth(0) } } if p.name == "Earth" && len(message) > 1 { openvg.StrokeColor(labelcolor) openvg.StrokeWidth(1) openvg.Line(x, y+(r/2), x, y+labeloc) openvg.StrokeWidth(0) openvg.FillColor(labelcolor) openvg.TextMid(x, y+labeloc+10, message, "sans", 12) } } openvg.End() }
func combohand(cx, cy, px, py, r, stroke openvg.VGfloat, t float64, value int, color string) { thinr := float64(r * 0.25) t = minadjust(t, value) * deg2rad tx := cx + openvg.VGfloat(thinr*math.Cos(t)) ty := cy + openvg.VGfloat(thinr*math.Sin(t)) openvg.FillColor(color) openvg.Ellipse(px, py, stroke*2, stroke*2) openvg.Ellipse(tx, ty, stroke*2, stroke*2) openvg.StrokeWidth(stroke) openvg.StrokeColor(color) openvg.Line(cx, cy, tx, ty) openvg.StrokeWidth(stroke * 2) openvg.Line(tx, ty, px, py) openvg.StrokeWidth(0) }
// rshapes draws shapes with random colors, openvg.Strokes, and sizes. func rshapes(width, height, n int) { var sx, sy, cx, cy, px, py, ex, ey, pox, poy float64 np := 10 polyx := make([]float64, np) polyy := make([]float64, np) openvg.Start(width, height) for i := 0; i < n; i++ { openvg.FillRGB(randcolor(), randcolor(), randcolor(), rand.Float64()) openvg.Ellipse(randf(width), randf(height), randf(200), randf(100)) openvg.Circle(randf(width), randf(height), randf(100)) openvg.Rect(randf(width), randf(height), randf(200), randf(100)) openvg.Arc(randf(width), randf(height), randf(200), randf(200), randf(360), randf(360)) sx = randf(width) sy = randf(height) openvg.StrokeRGB(randcolor(), randcolor(), randcolor(), 1) openvg.StrokeWidth(randf(5)) openvg.Line(sx, sy, sx+randf(200), sy+randf(100)) openvg.StrokeWidth(0) sx = randf(width) sy = randf(height) ex = sx + randf(200) ey = sy cx = sx + ((ex - sx) / 2.0) cy = sy + randf(100) openvg.Qbezier(sx, sy, cx, cy, ex, ey) sx = randf(width) sy = randf(height) ex = sx + randf(200) ey = sy cx = sx + ((ex - sx) / 2.0) cy = sy + randf(100) px = cx py = sy - randf(100) openvg.Cbezier(sx, sy, cx, cy, px, py, ex, ey) pox = randf(width) poy = randf(height) for j := 0; j < np; j++ { polyx[j] = pox + randf(200) polyy[j] = poy + randf(100) } openvg.Polygon(polyx, polyy) // , np) pox = randf(width) poy = randf(height) for j := 0; j < np; j++ { polyx[j] = pox + randf(200) polyy[j] = poy + randf(100) } openvg.Polyline(polyx, polyy) // , np) } openvg.FillRGB(128, 0, 0, 1) openvg.Text(20, 20, "OpenVG on the Raspberry Pi", "sans", 32) openvg.End() }
func roundhand(cx, cy, px, py, stroke openvg.VGfloat, color string) { openvg.StrokeWidth(stroke) openvg.StrokeColor(color) openvg.Line(cx, cy, px, py) openvg.StrokeWidth(0) openvg.FillColor(color) openvg.Ellipse(px, py, stroke, stroke) }
func secondhand(cx, cy, sx, sy, textsize openvg.VGfloat) { openvg.FillColor(secolor, 0.4) openvg.Ellipse(sx, sy, textsize, textsize) if secline { openvg.StrokeWidth(textsize / 6) openvg.StrokeColor(secolor) openvg.Line(cx, cy, sx, sy) openvg.StrokeWidth(0) } }
func face(x, y, r openvg.VGfloat, ts int) { var fx, fy, va openvg.VGfloat va = openvg.VGfloat(ts) / 2.0 secsize := openvg.VGfloat(ts) / 3 radius := float64(r) ir := radius * 1.2 // hour display openvg.FillColor(digitcolor) openvg.StrokeColor(digitcolor) openvg.StrokeWidth(5) for h := 12; h > 0; h-- { t := hourangles[h%12] * deg2rad fx = x + openvg.VGfloat(radius*math.Cos(t)) fy = y + openvg.VGfloat(radius*math.Sin(t)) ix := x + openvg.VGfloat(ir*math.Cos(t)) iy := y + openvg.VGfloat(ir*math.Sin(t)) if showdigits { openvg.TextMid(fx, fy-va, hourdigits[h%12], "sans", ts) } else { openvg.Line(fx, fy, ix, iy) } } // second display openvg.FillColor(dotcolor) openvg.StrokeColor(dotcolor) openvg.StrokeWidth(2) re := radius * edge for a := 0.0; a < 360; a += 6.0 { t := a * deg2rad sx := x + openvg.VGfloat(re*math.Cos(t)) sy := y + openvg.VGfloat(re*math.Sin(t)) if showdots { openvg.Ellipse(sx, sy, secsize, secsize) } else { ix := x + openvg.VGfloat(ir*math.Cos(t)) iy := y + openvg.VGfloat(ir*math.Sin(t)) openvg.Line(sx, sy, ix, iy) } } openvg.StrokeWidth(0) }
func main() { width, height := openvg.Init() w := openvg.VGfloat(width) h := openvg.VGfloat(height) y := h / 2 var ( margin openvg.VGfloat = 100.0 minsize openvg.VGfloat = 7.0 labeloc openvg.VGfloat = 100.0 ) bgcolor := "black" labelcolor := "white" maxsize := (h / 2) * 0.05 origin := sun.distance mostDistant := neptune.distance firstSize := mercury.radius lastSize := neptune.radius openvg.Start(width, height) openvg.BackgroundColor(bgcolor) for _, p := range solarSystem { x := vmap(p.distance, origin, mostDistant, margin, w-margin) r := vmap(p.radius, firstSize, lastSize, minsize, maxsize) if p.name == "Sun" { openvg.FillRGB(p.color.Red, p.color.Green, p.color.Blue, 1) openvg.Circle(margin-(r/2), y, r) } else { light(x, y, r, p.color) openvg.Circle(x, y, r) } if p.name == "Earth" && len(os.Args) > 1 { openvg.StrokeColor(labelcolor) openvg.StrokeWidth(1) openvg.Line(x, y+(r/2), x, y+labeloc) openvg.StrokeWidth(0) openvg.FillColor(labelcolor) openvg.TextMid(x, y+labeloc+10, os.Args[1], "sans", 12) } } openvg.End() bufio.NewReader(os.Stdin).ReadByte() openvg.Finish() }
// flake shows the snowflake icon func (d *dimen) flake(color string) { x, y, w, h := d.x, d.y, d.width, d.height cx := x + (w / 2) cy := y + (h / 2) r := w * 0.30 openvg.StrokeColor(color) openvg.StrokeWidth(w / 20) for t := 0.0; t < 2*math.Pi; t += math.Pi / 4 { c := openvg.VGfloat(math.Cos(t)) s := openvg.VGfloat(math.Sin(t)) x1 := (r * c) + cx y1 := (r * s) + cy openvg.Line(cx, cy, x1, y1) } openvg.StrokeWidth(0) }
// sun shows the icon for clear weather func (d *dimen) sun(color string) { x, y, w, h := d.x, d.y, d.width, d.height cx := x + (w / 2) cy := y + (h / 2) r0 := w * 0.50 r1 := w * 0.45 r2 := w * 0.30 openvg.FillColor(color) openvg.Circle(cx, cy, r0) openvg.StrokeColor(color) openvg.StrokeWidth(w / 30) for t := 0.0; t < 2*math.Pi; t += math.Pi / 6 { c := openvg.VGfloat(math.Cos(t)) s := openvg.VGfloat(math.Sin(t)) x1 := (r1 * c) + cx y1 := (r1 * s) + cy x2 := (r2 * c) + cx y2 := (r2 * s) + cy openvg.Line(x1, y1, x2, y2) } openvg.StrokeWidth(0) }
// fontrange shows a range of fonts func fontrange(w, h int) { var x, lx, length float64 y := float64(h) / 2.0 w2 := float64(w) / 2.0 spacing := 50.0 s2 := spacing / 2.0 sizes := []int{6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 21, 24, 36, 48, 60, 72, 96} openvg.Start(w, h) openvg.Background(255, 255, 255) // compute the length so we can center length = 0.0 for _, s := range sizes { length += float64(s) + spacing } length -= spacing lx = w2 - (length / 2) // center point // for each size, display a character and label x = lx for _, s := range sizes { openvg.FillRGB(128, 0, 0, 1) openvg.TextMid(x, y, "a", "serif", s) openvg.FillRGB(128, 128, 128, 1) openvg.TextMid(x, y-spacing, fmt.Sprintf("%d", s), "sans", 16) x += float64(s) + spacing } // draw a openvg.Line below the characters, a curve above x -= spacing openvg.StrokeRGB(150, 150, 150, 0.5) openvg.StrokeWidth(2) openvg.Line(lx, y-s2, x, y-s2) openvg.FillRGB(255, 255, 255, 1) openvg.Qbezier(lx, y+s2, x, y+s2, x, y+(spacing*3)) openvg.End() }
// refcard shows a reference card of shapes func refcard(width, height int) { shapenames := []string{ "Circle", "Ellipse", "Rectangle", "Rounded Rectangle", "Line", "Polyline", "Polygon", "Arc", "Quadratic Bezier", "Cubic Bezier", "Image", } top := float64(height) * .95 sx := float64(width) * 0.10 sy := top sw := float64(width) * .05 sh := float64(height) * .045 dotsize := 7.0 spacing := 2.0 fontsize := int(float64(height) * .033) shapecolor := Color{202, 225, 255, 1.0} openvg.Start(width, height) openvg.FillRGB(128, 0, 0, 1) openvg.TextEnd(float64(width-20), float64(height/2), "OpenVG on the Raspberry Pi", "sans", fontsize+(fontsize/2)) openvg.FillRGB(0, 0, 0, 1) for _, s := range shapenames { openvg.Text(sx+sw+sw/2, sy, s, "sans", fontsize) sy -= sh * spacing } sy = top cx := sx + (sw / 2) ex := sx + sw openvg.FillRGB(shapecolor.red, shapecolor.green, shapecolor.blue, shapecolor.alpha) openvg.Circle(cx, sy, sw) coordpoint(cx, sy, dotsize, shapecolor) sy -= sh * spacing openvg.Ellipse(cx, sy, sw, sh) coordpoint(cx, sy, dotsize, shapecolor) sy -= sh * spacing openvg.Rect(sx, sy, sw, sh) coordpoint(sx, sy, dotsize, shapecolor) sy -= sh * spacing openvg.Roundrect(sx, sy, sw, sh, 20, 20) coordpoint(sx, sy, dotsize, shapecolor) sy -= sh * spacing openvg.StrokeWidth(1) openvg.StrokeRGB(204, 204, 204, 1) openvg.Line(sx, sy, ex, sy) coordpoint(sx, sy, dotsize, shapecolor) coordpoint(ex, sy, dotsize, shapecolor) sy -= sh px := []float64{sx, sx + (sw / 4), sx + (sw / 2), sx + ((sw * 3) / 4), sx + sw} py := []float64{sy, sy - sh, sy, sy - sh, sy} openvg.Polyline(px, py) // , 5) coordpoint(px[0], py[0], dotsize, shapecolor) coordpoint(px[1], py[1], dotsize, shapecolor) coordpoint(px[2], py[2], dotsize, shapecolor) coordpoint(px[3], py[3], dotsize, shapecolor) coordpoint(px[4], py[4], dotsize, shapecolor) sy -= sh * spacing py[0] = sy py[1] = sy - sh py[2] = sy - (sh / 2) py[3] = py[1] - (sh / 4) py[4] = sy openvg.Polygon(px, py) // , 5) sy -= (sh * spacing) + sh openvg.Arc(sx+(sw/2), sy, sw, sh, 0, 180) coordpoint(sx+(sw/2), sy, dotsize, shapecolor) sy -= sh * spacing var cy, ey float64 cy = sy + (sh / 2) ey = sy openvg.Qbezier(sx, sy, cx, cy, ex, ey) coordpoint(sx, sy, dotsize, shapecolor) coordpoint(cx, cy, dotsize, shapecolor) coordpoint(ex, ey, dotsize, shapecolor) sy -= sh * spacing ey = sy cy = sy + sh openvg.Cbezier(sx, sy, cx, cy, cx, sy, ex, ey) coordpoint(sx, sy, dotsize, shapecolor) coordpoint(cx, cy, dotsize, shapecolor) coordpoint(cx, sy, dotsize, shapecolor) coordpoint(ex, ey, dotsize, shapecolor) sy -= (sh * spacing * 1.5) openvg.Image(sx, sy, 110, 110, "starx.jpg") openvg.End() }
// plot places a plot at the specified location with the specified dimemsions // using the specified settings, using the specified data func plot(x, y, w, h float64, settings plotset, d []rawdata) { nd := len(d) if nd < 2 { fmt.Fprintf(os.Stderr, "%d is not enough points to plot\n", len(d)) return } // Compute the minima and maxima of the data maxx, minx := d[0].x, d[0].x maxy, miny := d[0].y, d[0].y for _, v := range d { if v.x > maxx { maxx = v.x } if v.y > maxy { maxy = v.y } if v.x < minx { minx = v.x } if v.y < miny { miny = v.y } } // Prepare for a area or line chart by allocating // polygon coordinates; for the horizon plot, you need two extra coordinates // for the extrema. needpoly := settings.opt["area"] || settings.opt["connect"] var xpoly, ypoly []float64 if needpoly { xpoly = make([]float64, nd+2) ypoly = make([]float64, nd+2) // preload the extrema of the polygon, // the bottom left and bottom right of the plot's rectangle xpoly[0] = x ypoly[0] = y xpoly[nd+1] = x + w ypoly[nd+1] = y } // Draw the plot's bounding rectangle if settings.opt["showbg"] && !settings.opt["sameplot"] { openvg.FillColor(settings.attr["bgcolor"]) openvg.Rect(x, y, w, h) } // Loop through the data, drawing items as specified spacer := 10.0 for i, v := range d { xp := fmap(v.x, minx, maxx, x, x+w) yp := fmap(v.y, miny, maxy, y, y+h) if needpoly { xpoly[i+1] = xp ypoly[i+1] = yp } if settings.opt["showbar"] { openvg.StrokeColor(settings.attr["barcolor"]) openvg.StrokeWidth(settings.size["barsize"]) openvg.Line(xp, yp, xp, y) } if settings.opt["showdot"] { openvg.FillColor(settings.attr["dotcolor"]) openvg.StrokeWidth(0) openvg.Circle(xp, yp, settings.size["dotsize"]) } if settings.opt["showx"] { if i%int(settings.size["xinterval"]) == 0 { openvg.FillColor("black") openvg.TextMid(xp, y-(spacer*2), fmt.Sprintf("%d", int(v.x)), settings.attr["font"], int(settings.size["fontsize"])) openvg.StrokeColor("silver") openvg.StrokeWidth(1) openvg.Line(xp, y, xp, y-spacer) } openvg.StrokeWidth(0) } } // Done constructing the points for the area or line plots, display them in one shot if settings.opt["area"] { openvg.FillColor(settings.attr["areacolor"]) openvg.Polygon(xpoly, ypoly) } if settings.opt["connect"] { openvg.StrokeColor(settings.attr["linecolor"]) openvg.StrokeWidth(settings.size["linesize"]) openvg.Polyline(xpoly[1:nd+1], ypoly[1:nd+1]) } // Put on the y axis labels, if specified if settings.opt["showy"] { bot := math.Floor(miny) top := math.Ceil(maxy) yrange := top - bot interval := yrange / float64(settings.size["yinterval"]) for yax := bot; yax <= top; yax += interval { yaxp := fmap(yax, bot, top, float64(y), float64(y+h)) openvg.FillColor("black") openvg.TextEnd(x-spacer, yaxp, fmt.Sprintf("%.1f", yax), settings.attr["font"], int(settings.size["fontsize"])) openvg.StrokeColor("silver") openvg.StrokeWidth(1) openvg.Line(x-spacer, yaxp, x, yaxp) } openvg.StrokeWidth(0) } // Finally, tack on the label, if specified if len(settings.attr["label"]) > 0 { openvg.FillColor(settings.attr["labelcolor"], 0.3) openvg.TextMid(x+(w/2), y+(h/2), settings.attr["label"], settings.attr["font"], int(w/8)) // int(settings.size["fontsize"])) } openvg.StrokeWidth(0) }