3. Programming the Patterns

Before turning to a description of the EscherTiling program we mention one further enhancement that Escher considered. The reader has surely noticed the weaving effect, which can be altered by varying the layering order in which the polygons that make up a motif are drawn. (In fact, this can be enhanced still further by using different colors for the different strands, a programming problem that we will go into shortly.) Escher allowed more variety by using a second ordering, wherein the layering order of polygons is simply reversed. He referred to motifs with this alternate weaving by appending the letter “a” to the integers in his signatures. The motifPieces function that follows defines the basic pieces with a color-list as an argument. Then motif and motifA produce the two types of woven motifs. This code produces the polygons only; the lines in Figure 7 were added by the package function AddLines. Grays (included in the package) defines a list of suitable gray shades.

[Graphics:../Images/index_gr_71.gif]

[Graphics:../Images/index_gr_72.gif]

Figure 7. The two woven motifs that can be used to generate intricate tilings.

So, following Escher, we will use ±1, ±2, ±3, ±4 as before, with reference to the leftmost pattern in Figure 7, and ±1a, ±2a, ±3a, ±4a to refer to the opposite weaving (Figure 7, right). Thus a signature might be: [Graphics:../Images/index_gr_73.gif]. The rotation and translation functions defined earlier will make it easy to perform the transformations. The only tricky step is turning the signature into a list of geometric instructions. And we want to incorporate a mechanism for coloring the result. To that end we use colInstrux, a 2×2 array of color instructions. If the array is, say, [Graphics:../Images/index_gr_74.gif], then, with respect to the five colors passed as an argument, the motif itself in the upper-left corner of the 2×2 tile would just use the five colors in order, the third color would be used for all five polygons in the upper right corner, the lower-left corner would be two-colored, and the lower-right corner would use the five given colors in reverse order.

The following code is the key construction. It produces a list of four 4-lists.

[Graphics:../Images/index_gr_75.gif]
Identity [Graphics:../Images/index_gr_76.gif] 0 [Graphics:../Images/index_gr_77.gif]
Identity [Graphics:../Images/index_gr_78.gif] 0 [Graphics:../Images/index_gr_79.gif]
flip [Graphics:../Images/index_gr_80.gif] 3 [Graphics:../Images/index_gr_81.gif]
Identity [Graphics:../Images/index_gr_82.gif] 1 [Graphics:../Images/index_gr_83.gif]

Each 4-list has a function as its first entry (Identity (which does nothing) or flip, which will flip when the time comes. Of course, this is determined by the sign of the integer part of the signature entry. The second entry is either m or mA applied to a list (that will be the colors); m and mA are temporary here; in practice they will be motif or motifA and the list of colors will be determined by the appropriate entry in cIn, a linear version of colInstrux (the index is advanced by 1 via the i++). The third entry is the number of times the motif will be rotated (one less than n, the integer part), and the fourth entry is the translation vector.

The trickiest part is “n_. * a :>”. This replaces any entry of the form, say, 3a by the appropriate four instructions. The dot means that, in the absence of an integer, it is to be interpreted as 1. Even though we might enter 1a, that gets immediately interpreted as just a. The dot in the pattern essentially puts the 1 back and uses it as n.

Assuming that m, mA, and c are changed to motif, motifA, and a list of true colors, respectively, we can apply the pure function

[Graphics:../Images/index_gr_84.gif]


to each of these instruction sets and the result will be the exact graphics object we want. We combine all of this into a function as follows (the just-defined colInstrux is being used here; the {3, 3, 3, 3, 3} means that the upper-right motif uses only one color. The more detailed versions of EscherTiling and MakeTile in the package in the electronic supplement have the colors and the color instructions fed in as options.

[Graphics:../Images/index_gr_85.gif]
[Graphics:../Images/index_gr_86.gif]

[Graphics:../Images/index_gr_87.gif]

Figure 8.  An example of how a motif and some coloring instructions combine to make a tile, poorly colored in this case.

The final piece of the code is to take the tile and translate it. This is what the EscherTiling function does. The key step here is to generate the set of translation vectors, which is most easily done by distributing List over List. Consider first:

[Graphics:../Images/index_gr_88.gif]
[Graphics:../Images/index_gr_89.gif]

Because {a,b} is shorthand for List[a,b], the preceding example should clarify why the following code generates all combinations. The List forming the last argument specifies that the distribution should be done over lists.

[Graphics:../Images/index_gr_90.gif]
[Graphics:../Images/index_gr_91.gif]

So the line: 2 Distribute[{Range[0, size/2 - 1], Range[0, size/2 - 1]}, List] will generate all pairs of even x- and y-coordinates up to a certain size.

[Graphics:../Images/index_gr_92.gif]

Here is an example of the preceding code in action on the signature [Graphics:../Images/index_gr_93.gif], with proper color-lists defined in colInstrux. First we must define flip. Note that EscherMotif as defined earlier has no black border-lines; the version in the package has black borders, and the user can add such borders via the AddLines package function.

[Graphics:../Images/index_gr_94.gif]

[Graphics:../Images/index_gr_95.gif]

Figure 9.  The signature [Graphics:../Images/index_gr_96.gif] leads to a fairly simple woven pattern.


Converted by Mathematica      July 21, 1999