# teaching machines

## Fabrication Summer Camp: Day 3

May 21, 2021 by . Filed under public, twoville.

Welcome to the third day of our summer camp! All the shapes we’ve made up till now been solid objects. But some objects have holes, like buttons, donuts, and things with eyes and mouths. Additionally, our only means of adding curved edges has been to superimpose circles onto other objects. This superimposing is not a good fit for fabrication. Each shape will be traced out by a laser or a cutting tool, and when shapes overlap, there will be cuts on the inside of our object. Today we’re going to examine a new shape command that lets us add holes and curved edges without introducing unwanted cuts.

### Initial

Earlier we traced out a blocky letter. My first initial is C, and I ended up with a design that looked like this:



with polygon()
color = :black
vertex().position = [30, 20]
vertex().position = [30, 80]
vertex().position = [90, 80]
vertex().position = [90, 100]
vertex().position = [10, 100]
vertex().position = [10, 0]
vertex().position = [90, 0]
vertex().position = [90, 20]

var twovilleDiv = jQuery('#twoville_blocky-c');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_blocky-c').submit();

with polygon()
color = :black
vertex().position = [30, 20]
vertex().position = [30, 80]
vertex().position = [90, 80]
vertex().position = [90, 100]
vertex().position = [10, 100]
vertex().position = [10, 0]
vertex().position = [90, 0]
vertex().position = [90, 20]



Those right angles are too raw and rough. Lettering that pleases the reader has curvature. I’d rather have a C that looked like this:

We will make this better C using the path command. The path command is more general than rectangles, polylines, and polygons. It allows for both straight lines and curved lines. To draw this C, we anchor ourselves on the bottom of the internal straight edge using the go command and then draw a line straight upward with the line command:



with path()
with stroke
color = :black
size = 1
opacity = 0
color = :black
go().position = [30, 30]
line().position = [30, 70]

var twovilleDiv = jQuery('#twoville_rounded-c-1');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_rounded-c-1').submit();

with path()
with stroke
color = :black
size = 1
opacity = 0
color = :black
go().position = [30, 30]
line().position = [30, 70]



Next we need a curve. In particular, we need a circular arc. An arc is a portion of circle’s perimeter. In this case, the circle is centered at (50, 70) and the arc is just 180 degrees of it. That is all we need to tell the arc command:



with path()
with stroke
color = :black
size = 1
opacity = 0
color = :black
go().position = [30, 30]
line().position = [30, 70]
with arc()
center = [50, 70]
degrees = -180

var twovilleDiv = jQuery('#twoville_rounded-c2');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_rounded-c2').submit();

with path()
with stroke
color = :black
size = 1
opacity = 0
color = :black
go().position = [30, 30]
line().position = [30, 70]
with arc()
center = [50, 70]
degrees = -180



To turn clockwise, we use a negative number of degrees.

We keep add lines and arcs to arrive at this shape:



with path()
with stroke
color = :black
size = 1
opacity = 0
color = :black
go().position = [30, 30]
line().position = [30, 70]
with arc()
center = [50, 70]
degrees = -180
line().position = [80, 70]
with arc()
center = [50, 70]
degrees = 180
line().position = [20, 30]
with arc()
center = [50, 30]
degrees = 180
line().position = [70, 30]
with arc()
center = [50, 30]
degrees = -180

var twovilleDiv = jQuery('#twoville_rounded-c3');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_rounded-c3').submit();

with path()
with stroke
color = :black
size = 1
opacity = 0
color = :black
go().position = [30, 30]
line().position = [30, 70]
with arc()
center = [50, 70]
degrees = -180
line().position = [80, 70]
with arc()
center = [50, 70]
degrees = 180
line().position = [20, 30]
with arc()
center = [50, 30]
degrees = 180
line().position = [70, 30]
with arc()
center = [50, 30]
degrees = -180



If we’d rather see the filled object instead of its outline, we remove the stroke and add a color:



with path()
color = :black
go().position = [30, 30]
line().position = [30, 70]
with arc()
center = [50, 70]
degrees = -180
line().position = [80, 70]
with arc()
center = [50, 70]
degrees = 180
line().position = [20, 30]
with arc()
center = [50, 30]
degrees = 180
line().position = [70, 30]
with arc()
center = [50, 30]
degrees = -180

var twovilleDiv = jQuery('#twoville_rounded-c4');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_rounded-c4').submit();

with path()
color = :black
go().position = [30, 30]
line().position = [30, 70]
with arc()
center = [50, 70]
degrees = -180
line().position = [80, 70]
with arc()
center = [50, 70]
degrees = 180
line().position = [20, 30]
with arc()
center = [50, 30]
degrees = 180
line().position = [70, 30]
with arc()
center = [50, 30]
degrees = -180



Our vinyl cutter doesn’t care. It will cut along the outer edge of the shape whether we use fill or stroke.

### Spaceship

The path command allows you to describe an arc in two ways:

1. With degrees and center properties. Use this form when the arc orbits around something.
2. With degrees and position properties. Use this form when the arc must end at a certain location.

In the letter C above, we used the center property to make the inner and outer curves orbit around the same location. Sometimes reasoning about the center is difficult because the center isn’t actually part of the object. In such cases, the position property might be easier to use. For example, I modeled this spaceship by thinking about where I wanted the arcs to end:



with path()
with stroke
size = 1
color = :gray
color = :soggy
closed = true
go().position = [100, 50]
with arc()
degrees = 30
position = [70, 60]
with arc()
position = [30, 60]
degrees = 160
with arc()
position = [0, 50]
degrees = 30
with arc()
position = [100, 50]
degrees = 72

var twovilleDiv = jQuery('#twoville_spaceship');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_spaceship').submit();

with path()
with stroke
size = 1
color = :gray
color = :soggy
closed = true
go().position = [100, 50]
with arc()
degrees = 30
position = [70, 60]
with arc()
position = [30, 60]
degrees = 160
with arc()
position = [0, 50]
degrees = 30
with arc()
position = [100, 50]
degrees = 72



Use whichever form makes sense to you. Note that you can’t define both position and center. In either form, you must define degrees.

### Fish

Now it’s your turn to make an object with curved edges out of a path. You challenge is create a fish, perhaps like this one:

Start by drawing on your graph paper. Identify the vertices between the curved edges. Show your drawing to a teacher. Then start coding it up in Twoville.

### Pac-Man

You may be familiar with a little yellow creature that eats pellets and runs away from ghosts. That creature is named Pac-Man. He was born in a Japanese arcade game in 1980. Pac-Man’s made mostly out of circles, which makes him a good candidate for modeling in Twoville. However, one of those circles is his eye, which is really just a hole. So far we haven’t seen a way to make holes in our shapes. That all changes with path.

To make a hole in an object defined as a path, we plot a new shape in front of an old one. Wherever the path overlaps with itself, a hole appears.

Consider this first attempt at plotting Pac-Man, which draws a circle with a wedge removed using the line and arc commands:



with path()
with stroke
size = 1
color = :black
color = :yellow
closed = true
go().position = [50, 50]
line().position = [70, 70]
with arc()
center = [50, 50]
degrees = 270
line().position = [50, 50]

var twovilleDiv = jQuery('#twoville_pacman1');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_pacman1').submit();

with path()
with stroke
size = 1
color = :black
color = :yellow
closed = true
go().position = [50, 50]
line().position = [70, 70]
with arc()
center = [50, 50]
degrees = 270
line().position = [50, 50]



Notice that this Pac-Man lacks an eye. We attach one by adding more pieces to the path. The easiest way is to use the circle command inside the path:



with path()
with stroke
size = 1
color = :black
color = :yellow
closed = true
go().position = [50, 50]
line().position = [70, 70]
with arc()
center = [50, 50]
degrees = 270
line().position = [50, 50]
with circle()
center = [54, 68]

var twovilleDiv = jQuery('#twoville_pacman2');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_pacman2').submit();

with path()
with stroke
size = 1
color = :black
color = :yellow
closed = true
go().position = [50, 50]
line().position = [70, 70]
with arc()
center = [50, 50]
degrees = 270
line().position = [50, 50]
with circle()
center = [54, 68]



Holes do not need to be circles. We could have used the rectangle command. Or we can make any arbitrary shape using go, line, and arc. Here we make a triangular eye:



with path()
with stroke
size = 1
color = :black
color = :yellow
closed = true
go().position = [50, 50]
line().position = [70, 70]
with arc()
center = [50, 50]
degrees = 270
line().position = [50, 50]
go().position = [50, 67]
line().position = [56, 67]
line().position = [54, 72]

var twovilleDiv = jQuery('#twoville_pacman3');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_pacman3').submit();

with path()
with stroke
size = 1
color = :black
color = :yellow
closed = true
go().position = [50, 50]
line().position = [70, 70]
with arc()
center = [50, 50]
degrees = 270
line().position = [50, 50]
go().position = [50, 67]
line().position = [56, 67]
line().position = [54, 72]



Before he looked hungry. Now he looks like he’s yawning.

### ABDs

Remember that time you plotted a letter for someone you cared about, but that someone’s letter couldn’t have a hole in it? Well, we’re not limited anymore. Think of someone that you care about that can be identified by a letter that has a whole in it. In English, those letters are A, B, D, O, P, Q, and R.

Draw the letter on graph paper, use the path to trace its outer perimeter with all of its arcs and straight lines, and then trace out the perimeters of its holes. Identify its positions and sizes. Code it up and we’ll turn it into a sticker that you can give to the person you care about.

### Bezier

We’ve seen how the path command allows us to add circular arcs to our shapes. Not all curves are simple circular arcs. A guitar pick, for example, doesn’t look very circular. Let’s examine how to model these other kinds of curves.

Suppose we have a starting position P. We want to connect P to position Q. A straight line would lead directly from on to the other, but we want a curve. To control the curvature, we add a third position that acts as a black hole that sucks the edge toward it. This third point is called a control point. As the control point moves farther from the edge, the curve gets bigger and bigger.

To see this in action, let’s model a leaf. We start with the stem, which is made of straight lines:



with path()
color = :green
opacity = 0
with stroke
color = :green
size = 1
go().position = [5, 48]
line().position = [5, 52]
line().position = [30, 52]

var twovilleDiv = jQuery('#twoville_leaf1');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_leaf1').submit();

with path()
color = :green
opacity = 0
with stroke
color = :green
size = 1
go().position = [5, 48]
line().position = [5, 52]
line().position = [30, 52]



Now we jump to the tip, adding a control point to tug at the edge between the stem and the tip. We use the command quadratic to describe this curve:



with path()
color = :green
opacity = 0
with stroke
color = :green
size = 1
go().position = [5, 48]
line().position = [5, 52]
line().position = [30, 52]
position = [95, 50]
control = [38, 93]

var twovilleDiv = jQuery('#twoville_leaf2');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_leaf2').submit();

with path()
color = :green
opacity = 0
with stroke
color = :green
size = 1
go().position = [5, 48]
line().position = [5, 52]
line().position = [30, 52]
position = [95, 50]
control = [38, 93]



Now we mirror this same pattern to complete the other side of the leaf, closing out the path with the back command:



with path()
color = :green
go().position = [5, 48]
line().position = [5, 52]
line().position = [30, 52]
position = [95, 50]
control = [38, 93]
position = [30, 48]
control = [38, 7]
back()

var twovilleDiv = jQuery('#twoville_leaf3');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_leaf3').submit();

with path()
color = :green
go().position = [5, 48]
line().position = [5, 52]
line().position = [30, 52]
position = [95, 50]
control = [38, 93]
position = [30, 48]
control = [38, 7]
back()



A quadratic curve has a single control point tugging at the edge. To get even more control over the curvature, we can add two control points using the cubic command:



with path()
color = :green
go().position = [5, 48]
line().position = [5, 52]
line().position = [30, 52]
y = 2
with cubic()
position = [95, 50]
control1 = [39, 97]
control2 = [59, 65]
with cubic()
position = [30, 48]
control1 = [64, 37]
control2 = [36, 8]
back()

var twovilleDiv = jQuery('#twoville_leaf4');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_leaf4').submit();

with path()
color = :green
go().position = [5, 48]
line().position = [5, 52]
line().position = [30, 52]
y = 2
with cubic()
position = [95, 50]
control1 = [39, 97]
control2 = [59, 65]
with cubic()
position = [30, 48]
control1 = [64, 37]
control2 = [36, 8]
back()



These kinds of curves are called Bézier curves. They are named after Pierre Bézier, who invented them so that he could describe the shapes of cars.

### Shape Jam

We are going to have a shape jam. Your “theme” for today is to use paths and Bézier curves. Follow these steps in making your shape:

1. Start by drawing on graph paper.