# teaching machines

## Center Bug

How do you teach elementary schoolers to programmatically trace a circle? Not with parametric equations involving sine and cosine, but with a turtle. You set them on its back, put the reins in their hands, and have them call out orders. The turtle only needs to know two commands: move and turn. Interleave these commands, and the turtle will eventually arrive back where it started.

Turtle geometry obviates many advanced mathematical concepts, including trigonometry and coordinate systems. If you know about lengths and angles, you can spur that turtle onward.

I like the turtle, but we pay a few penalties for employing it:

• Generating a “perfect” semi-circle is awkward.
• Calculating the circle’s radius is awkward.
• Finding the circle’s center is awkward.

The first two issues I’ll discuss another day. Today let’s focus on the circle’s center.

When I help young people build things, we often want to hollow out the center of a circle. Wheels need shafts for axles, cups need a place to put their liquid contents, and buttons need holes. But if the circle is laid out by a turtle, the center’s coordinates are not nice clean numbers.

A couple of years ago I tried to unify the Cartesian and turtle coordinate systems in Madeup. So that we could easily find the center of a path traced out by a turtle, I added a center command that shifts a path so that it’s centered around the origin. We could do whatever we needed to do at the center by visiting (0, 0). For instance, here’s a program to generate a hexagon with a square hole in its middle:

-- Trace a hexagon.
moveto 0, 0
repeat 6
move 1
yaw 60
end
center path
extrude 0, 0, 1, 1

-- Carve out a hole at the origin.
subtract
moveto 0, 0, -3
moveto 0, 0, 3
dowel

Just today, however, I discovered a bug:

That hole’s not very centered, is it?

The trouble was in how I calculated the path’s centroid. I had code like this:

centroid = 0, 0
for each point
centroid += point
centroid /= number of points

But when a path was closed, the starting point ended up getting double-counted, because the ending point was also in the list of points. Removing the ending point fixed the problem:

I try not to think about what havoc I might wreak if I wrote software for cars or spacecraft.