Wednesday, March 24, 2010

Leaning Flowers

Here is another variation of grain2. It's like the "flower" program, but it includes stems, and a porportion of "lean" (0 - full lean to the left, 100 - full lean to the right) is programmed in.

The variations were produced with this script:

for i in 0 25 50 75 100
./grain -n 150 -w 900 -h 200 -l 175 -nl $i > grain$i.svg

Grain 0

Grain 25

Grain 50

Grain 75

Grain 100

Here's the Go program

// grain -- flowers with programmable lean

package main

import (
svglib "./svg"

var (
width = flag.Int("w", 500, "width")
height = flag.Int("h", 500, "height")
ninter = flag.Int("n", 75, "interations")
stemlen = flag.Int("l", 450, "stem length")
stemwidth = flag.Int("st", 4, "stem thickness")
numleft = flag.Int("nl", 50, "percentage of left-leaning stems")
thickness = flag.Int("t", 10, "max petal thinkness")
np = flag.Int("p", 15, "max number of petals")
psize = flag.Int("s", 30, "max length of petals")
opacity = flag.Int("o", 50, "max opacity (10-100)")
svg = svglib.New(os.Stdout)

const (
flowerfmt = `stroke:rgb(%d,%d,%d); stroke-opacity:%.2f; stroke-width:%d`
stemfmt = `stroke:green;stroke-opacity:0.3;stroke-width:%d`

func radial(xp int, yp int, n int, l int, style ...string) {
var x, y, r, t, limit float64
limit = 2.0 * math.Pi
r = float64(l)
for t = 0.0; t < limit; t += limit / float64(n) {
x = r * math.Cos(t)
y = r * math.Sin(t)
svg.Line(xp, yp, xp+int(x), yp+int(y))

func background(v int) { svg.Rect(0, 0, *width, *height, svg.RGB(v, v, v)) }

func random(howsmall, howbig int) int {
if howsmall >= howbig {
return howsmall
return rand.Intn(howbig-howsmall) + howsmall

func randrad(x, y int) {
var r, g, b, o, s, t, p int
r = rand.Intn(255)
g = rand.Intn(255)
b = rand.Intn(255)
o = random(10, *opacity)
s = random(10, *psize)
t = random(2, *thickness)
p = random(10, *np)
radial(x, y, p, s, fmt.Sprintf(flowerfmt, r, g, b, float64(o)/100.0, t))

func init() {
rand.Seed(time.Nanoseconds() % 1e9)

func main() {
svg.Start(*width, *height)
svg.Gstyle(fmt.Sprintf(stemfmt, *stemwidth))
var x, l, xe, offset int
for i := 0; i < *ninter; i++ {
x = rand.Intn(*width)
l = rand.Intn(*stemlen)
offset = rand.Intn(*width / 10)
if rand.Intn(100) > *numleft {
xe = x - offset
} else {
xe = x + offset
svg.Line(x, *height, xe, *height-l)
randrad(xe, *height-l)

Sunday, March 21, 2010

Browser SVG Gallery - UI analysis

Browser SVG Gallery
Originally uploaded by ajstarks
This grid shows four modern browsers: Chrome (5.0.307.11) , Firefox (3.6) , Opera (10.10) , and Safari (4.0.5) displaying SVG content generated by SVGo. The browser UI's have been muted to emphasize the content. Some observations:

1) Chrome: shows more "chrome" than any of the others. Lot's of head space with it's tab structure, with an emphasis on the omnibox, but with a minimal number of controls (back, forward, refresh)

2) Firefox: as minimal as it gets, except for the OS X furniture, only minimal tab controls are visible

3) Opera: lots of buttons with space for the address box, but all in a single row

4) Similar to Opera, but with fewer buttons (only back and forward). The big ol' Google box looks conspicuous.

Note that both Opera and Safari allow for all controls to be suppressed so that you are left with pure content:

Saturday, March 6, 2010

Processing vs. SVG Go

Processing vs. SVG Go
Originally uploaded by ajstarks
This screenshot compares developing the same graphic using Processing and the SVG Go Library.

Top row: from the left: Processing code, Go Code (in TextWrangler), Command lines to run the Go code

Bottom row: Processing output, Go-generated SVG rendered in Safari and Chrome

The workflow for Processing is familiar: enter code, hit the run button. For Go: edit/write code, move to a shell window, compile, open a browser.
For subsequent runs, just hit refresh in the browser to see the result.

Both methods support rapid prototyping and sketching -- the Go compiles are so fast it's almost the same as hitting the run button in Processing. As you can see the results are identical

In terms of code, both environments are similar -- there is almost a one-to-one correspondence, however SVG and Processing treat ellipse width differently.

I note that the syntax highlighting of graphics functions in Processing tells me at a glance what the program is doing -- this is less apparent with the Go program.