Pure-paper packable polyhedra in Python

This messy little script generates SVG patterns.

I wrote it because I had a sudden urge to play with polyhedra.  The pattern of polygons is printed, then cut out and assembled.  It’s even possible to construct a rickety solid (is that an oxymoron?) without glue or tape.  Interlocking tags in the paper hold it together:

This is the “orange”, so called because it’s one of the few packable archimedean solids.  It can be packed in layers like oranges (or any other approximately spherical fruit, for that matter); each successive layer is offset half a unit in both directions, with the “oranges” settling in the dimples in the layer below.

Algorithm and language

It is akin to a Turtle or Lindenmayer system.  Apart from that there is little rhyme or reason to the pattern language.  I just picked something that would figure out where to put polygons for me.  I’ll try to describe it.  The grammar, I suppose, is something like this:

Pattern = Cmd
Cmd     = Instr
        | Instr '(' Cmd* ')'
Instr   = {name of callable in provided dictionary}

The interpreter maintains a cursor, which is a four-tuple of (xpos,ypos,angle,scale).  It finds the next Instr and calls that function, with the cursor as an argument.  An Instr function does two things:

  1. It can optionally print some SVG text, and
  2. It returns a list of cursors, which may be derived from its input.

After calling an Instr function F, the interpreter will call the sub-commands in sequence on the cursors returned by F.  A missing or truncated sub-command list is padded out with extra copies of the “e” and “s” Instrs: “s” for the first returned cursor, and “e” for each subsequent one.

The idea is that the Instrs correspond to shapes; for instance, to the faces of a polyhedron.  You specify a root shape, then the shapes that are to be placed adjacent to it, and so on.  The shape “s” is used for the edges between adjacent shapes, and “e” is used for the outer edges.  “s” could be defined a dotted line indicating where to fold, for example.


Cube: p4(p4 p4 p4 p4(s e p4 e))

Truncated octahedron (“orange”): p4(p4 p4 p4 p4(s e p4 e))

Truncated cuboctahedron: p8(p4(s e p8(s e p4 e p4 p6)) p6 p4(s e p8(s e p4 e p4 p6)) p6 p4(s e p8(s e p4 e p4 p6)) p6 p4(s e p8(s e p4 e p4(s e p8) p6)) p6)


(Which I may or may not get round to…)

Clean up the language.  Functions could be parameterised, for example instead of defining a “p4” we could simply specify how many sides at interpretation time: “p(4)[p(4), p(4), p(4), p(4)[s() e() p(4) e()]”.  Recursion could be supported; perhaps using a kind of let command: “(x = F()[x, x])x”.  (Recursion would terminate when an Instr function determined that the scale was too small to be worth continuing; it could return an empty list of cursors to indicate this.)

Provide more embellishments for shapes.  For instance we could render pips on a die; or words; or just different coloured faces.

Output to a POV-Ray source as well as SVG, so that 3D models and even animations could be made.  Imagine an animation of the polyhedron folding itself up from a flat pattern.

Provide a “t” shape so that a human scissor-wielder can leave tabs on the optimal edges for ease of construction.

The script is at http://pastebin.com/2cExy3Rq.

This entry was posted in Math, Programming and tagged , , . Bookmark the permalink.

One Response to Pure-paper packable polyhedra in Python

  1. Pingback: Version control thoughts | EJRH

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s