## by Peter Hosey

### Preface

I was an entrant in the zeroth Iron Coder. My entry is named “Beads”; it hangs a shellacked string of beads onto the frontmost window.

I'm very proud of the look of the beads. I'm going to tell you how I created them, which translates to how you can draw them yourself in your own app. (Aside from ganking my code, which is BSD-licensed. That's the other way to have them in your app.)

Each bead is drawn at a diameter of 1 cm (a little over 28+13 pt). They are drawn into the overlay window at a diameter of 16 pt.

### Step 1: Draw a circle

That's fine, but it's just a flat circle. Beads are spheres. Our bead needs to look like it has some depth.

### Step 2: Light and shadow

The Aqua Human Interface Guidelines (specific page: Icon Perspectives and Materials) say “All Aqua interface elements have a common light source from directly above…”, so we need a highlight on top and a shadow on the bottom.

I use a CGShading to achieve this affect. The shading function takes a value t ranging from 0 (bottom) to 1 (top). The first step in this function is:

sin((t - 0.5) π) 0.5

This value is a saturation delta: it is added to all of the components (R, G, B) of the color of the bead. We're making a red bead, so these components start at (1, 1, 0) and become:

• t = 0 → -0.5 → (0.5, 0.5, 0) (dark red)
• t = 12 → +0 → (1, 1, 0) (unchanged — the center of the bead is red)
• t = 1 → +0.5 → (1, 1, 0.5) (light red)

I don't know what inspired me to use a sine wave, but that's what I used, and it works well. Here's the result:

### Step 3: The sheen

I knew before I started coding the beads that just a gradient wouldn't cut it. I needed to fake a reflection on top of the beads. So I wrote a PostScript file (left it on my RAM disk; sorry) that printed out two rulers (one per axis), each 5 cm long and divided into tenths. I then printed this out and drew in pencil what I wanted the sheen to look like. Here it is, the first draft:

I soon found out that I wouldn't be able to work out a Bézier path for this one. I'm not good with Bézier curves. I soon came up with a simpler sheen, used in the submission, that works well and is much simpler to draw:

The top curve of the sheen begins at 35 from the bottom and peaks at 910. The bottom curve of the sheen peaks at 710. The left corner is at 110 and the right corner is at 910.

To draw it in PostScript:

0.9 0.6 moveto 0.5 1.0 0.1 0.6 curveto 0.5 0.77 0.9 0.6 curveto closepath sheenColor setfill fill

The above is a back-port to PostScript from the Quartz source in the submission.

And here is the product of all that hard work:

### Outtake: The beads you didn't see

The beads that you see in the submission look great. But you probably didn't notice that they contain a mistake. I didn't.

You see, my original intent (which you might notice if you look at the Beads 1.0 source code) was to draw a border (called a stroke) within the circumference of the circle. Unfortunately, I messed up. Here's the submitted code:

The problems are:

1. The `clip` is protected by the `gsave`/`grestore`.
2. The line width is set to 3.
3. The rect given is the media box.

The `clip` is necessary to keep the stroke within the circumference of the bead; otherwise, half of the stroke width would fall outside the media box at each of the cardinal points. So the `gsave` and `grestore` must go, so that the `clip` applies to the stroke as well.

But those last two problems are more critical.

The problem is caused by the `scale` earlier. Because of that, 1 user-space unit = 1 bead, rather than 1 pt. So our line width is 3 beads across, and the rect is about 28 by 28 beads (remember earlier that BEAD_SIZE = 1 cm = >28 pt).

The stroke should only be 1 bead in diameter, not 28.

The fix is threefold:

1. Let the clipping path apply to all the steps, including the stroke.
2. Change the line width to 2 / BEAD_SIZE. I'd only intended to have a 1-pt stroke. The clipping path cuts the line width in half, so a 2-pt line width gets me a 1-pt border within the clip.
3. Instead of passing the media box (whose size is about 28 pt on both axes), pass { 1, 1 } for the size.

These fixes have been rolled into Beads 1.1. But I didn't even notice that the code was wrong until I started writing this article. The beads do look great without the stroke.

Nonetheless, here's the director's cut of the beads — how they were supposed to look. On the left are the submitted (strokeless) beads; on the right are the director's cut (stroked) beads:

Version 1.1 has been digitally remastered to include the stroke.

### DVD Extras

#### The making of the Beads How-to

All of the examples shown above were created using a program called mkbead, which uses code excerpted from Beads. I commented out parts of the program to generate each step of the graphic. The output is a PDF, of course (this is also what Beads generates internally).