I’ve posted a new GWT Canvas demo at gwt-sunflower.appspot.com. Works in all modern browsers and IE>=9. You may need to refresh the page after loading due to a bug in the SliderBar that I haven’t dug into yet.

Like the previous demo, the math provides the fun. Each time you move the slider, the app clears the canvas and draws dots 1…n, where n is the number of seeds shown in the slider. The position of each seed n is computed using the equations in polar form shown above the figure. The key to the geometry is the golden angle (represented by *Φ*), which is simply the golden ratio as a fraction of a circle, where the golden ratio is approximated by the quotient of two successive Fibonacci numbers (example: 55 / 89 ≈ 0.618). The basic algorithm to fill the seed head (mathematically speaking, not biologically) is a dial going around and around like the hands of a clock, but counterclockwise in this example. Every time the dial reaches a multiple of the golden angle (0.618 x 360° ≈ 222.5°), a seed pops out. The distance of the seed from the center (*r*) is proportional to the square root of the seed number.

At any given time in the flower’s “growth,” the number of spiral arms apparent at the outer edge is a Fibonacci number (0,1,1,2,3,5,8,13,21,34,…). The number of spiral arms going in the opposite direction is the next nearest Fibonacci number. This property is true of real sunflowers and in fact, most flowers in the daisy family. See, for example, this tiny wildflower I photographed with my “poor man’s macro lens,” an extension tube. The diameter of the flower was less than half the width of my pinky fingernail.

In order to improve graphical performance, the app uses a coordinate space which is only half the actual pixel size (example: 200×200 vs. 400×400). HTML5 Canvas automatically scales the virtual coordinate space to fill the actual pixel space.

Here’s the essential GWT code.

/** * Draw the complete figure for the current * number of seeds */ private void drawFrame() { front.clearRect(0, 0, maxD, maxD); for (int i=0; i<numSeeds; i++) { double theta = i * PI2 / PHI; double r = Math.sqrt(i) * SCALE_FACTOR; double x = xc + r * Math.cos(theta); double y = yc - r * Math.sin(theta); drawSeed(x,y); } } /** * Draw a small circle representing a seed centered at (x,y) * * @param x Center of the seed head * @param y Center of the seed head */ private void drawSeed(double x, double y) { front.beginPath(); front.setLineWidth(2); front.setFillStyle("orange"); front.setStrokeStyle("orange"); front.arc(x, y, SEED_RADIUS, 0, PI2); front.fill(); front.closePath(); front.stroke(); }

The entire source code is available via the link below the figure.

Enjoy!