As promised last time, my simple tour of POV-Ray continues with some examples a bit more interesting than an abacus stone or a box with holes in it. Time to move beyond a bunch of teal-colored spheres! (How about a bunch of hunter-green cones?)

I think it’s nice to have a place to sit while I lecture, so I’m going to use my digital woodworking set to provide a bar stool (and maybe a beer). The beauty of the virtual world is that , well, free stools (and maybe beers) for everybody.

Because I don’t just make a stool. I make a thing that *makes* stools.

And it makes them to order, so you can have a stool that is exactly the right height for you! And they come in a variety of cushion colors! (By “variety” we mean, “name a color.”) For those of you learned in the arcane arts of coding, we design a macro that makes bar stools. It takes a height and color as parameters. If “macro” seems a mysterious world, just use “template.”

The process of designing an object for computer rendering always begins by *looking at the object* to see what it is.

How you look, what you think about, depends on your rendering tool. For example, with POV-Ray we look at an object in terms of how we might construct it using the spheres, cones, boxes and other shapes POV-Ray provides.

When we look at a (four-legged) stool, the basics are pretty obvious: a round seat, four legs, a pair of dowels bracing each side. Another look reveals some details: the edge of the seat is curved, the legs are square and angle outwards from the seat. Notice also: adjacent braces are offset, not lined up (drilling the holes next together would weaken the leg).

I’ll tell you right now that if we want the stool to be as simple as possible, there’s a minor problem, a devil in the details. The square legs that angle out from the seat are not trivial. I mentioned yesterday that the *box* shape—the natural pick for square legs—is always rectangular; its sides are always straight.

[This is because we specify a *box* by giving two opposite corners and *assuming* the sides are straight. Think of any box and pick any two opposite corners. Now think city blocks— no diagonals—you have to go up, over and across to get to the other corner.]

The problem is not insurmountable, just non-trivial. We can rotate the box to make the legs angle, but that involves a bit of trigonometry. I promised no math, so we’ll leave the glorious, elegant beauty of cosines behines (*ugh!* sorry! can’t resist a bad pun even when it needs a crowbar).

It’s simple to use a cylinder for a leg. To make a cylinder you give the two end points and the radius. So you just say where the leg hits the seat and where it hits the floor (and how thick it is).

The braces dowels are also cylinders, and so is the seat. Or rather the seat has a cylinder part. It also has a torus part for the curved edge. The idea is identical to the abacus stone I showed you yesterday, but the proportions are different.

Usually when we make something, we make it in the center of reality, centered on the point (0,0,0)—the *origin* point of the XYZ space. Then to make it appear somewhere else we just move (*translate*) it. We can also *rotate* an object or *scale* it (change its size). All three operations (*translate*, *rotate* and *scale*) are three-dimensional; you can apply the operation along any axis.

In fact, I’d like to draw a connection to the Dimensional Coordinates post. It’s intended as support for the Vector Thinking thread, but the 3D coordinate discussion connects with image rendering. All the shapes we create exist in a three-dimensional XYZ space, and any point on any shape has an XYZ coordinate.

I mentioned that the directions the X, Y and Z axes point is arbitrary. In POV-Ray, the Y axis is the up-down axis (+Y is up). The X and Z axes are horizontal; you can think of them as map coordinates like latitude and longitude. When you don’t care about up and down—you’re looking down at a flat map, for instance—then XZ act like a 2D XY surface.

A common convention is that X runs east-west (+X is east), and Z runs north-south (+Z is north). You could rotate the map any other way if you wanted, but this orientation makes X and Z increase as you go east and north. A typical map often has the same convention.

Another common map convention has Y (aka Z) increasing as you move south. These maps place the lowest coordinates in the upper left rather than the lower left. Reversing the north-south axis in POV-Ray would require turning it upside down, so we’ll stick with the common convention!

There is a detail I haven’t touched on regarding the angled legs and the braces.

The stool “template” takes a height parameter that lets you create stools of any height. The template places the braces proportionally. The question is how to place the braces such that they intersect the legs precisely in the middle. The center of the leg angles out from center as the leg descends.

Because the legs are on 45 angles, it turns out to be a simple slope calculation, but explaining the formula or why no trig is needed would require some math!

You may have wondered about all those stools in the post’s lead image.

It might look like one hell of a cut ‘n’ paste job, but the code has only one stool command. It repeats that command in 32 rows of 32 stools [*do your own math*]. The code uses two nested loops that generate the rows and stools in the row.

You may have noticed the stools aren’t lined up nice and neat. As the code loops over the rows, four parameters are *joggled* a little randomly. Each stool is slightly different in terms of: back-forth, left-right, rotation and height.

It would have been much simpler to have them all lined up the same (it took over 45 minutes to write and debug the “joggle code” (and futz with it until I had it just right)). But lined up and regular is boring; a little randomness makes it look more interesting.

And that one red stool? There’s a check for a certain row and column; that stool wins the lottery. The “paint color” is just another parameter the template provides customizing the stool.

Now the only pity is we can’t throw all these stools on a giant bonfire!