Tessellations of the Euclidean, Elliptic and Hyperbolic Plane 
Tess package for Mathematica 4.0
Miodrag Sremcevic (msremac@agnld.uni-potsdam.de) & Radmila Sazdanovic (seasmile@galeb.etf.bg.ac.yu)
user guide for version 1.7, 12. September 2002, file: Tess.m

Tess is a package for generation and drawing of Archimedean (including regular and uniform) tessellations in Euclidean (E2), Elliptic (S2 - polyhedra), and Lobachevskian  (L2, or hyperbolic) plane. The tiles of Archimedean tessellations are regular polygons and all vertices are of the same type. Tessellations are given with their  vertex configuration. The vertex configuration does not define uniquely tiling, and the program calculates, for a given vertex configuration, all different (if any) realizations of the tiling. The package correctly finds all uniform (semi-regular) tilings, Archimedean tilings which are not uniform, and also `colored' realizations. A typical command for drawing a tiling is TessShow[{4,4,4,6}]. Beside the drawing of tessellations, the program provides additional data, such as: geometry and type of tessellation, number of possible realizations, angles of tiles and transformation rules between neighboring vertices. The drawing in hyperbolic plane is realized using I. Knezevic, R. Sazdanovic & S. Vukmirovic package L2Primitives (www.MathSource.com).

Tessellations in hyperbolic plane are drawn using functions from L2Primitives package by authors I. Knezevic, R. Sazdanovic & S. Vukmirovic. The package is available at MathSource (library of Mathematica related materials): 
http://www.MathSource.com/Content/Applications/Graphics/2D/0211-879.
This loads L2Primitives package:

<< L2Primitives.m

This loads Tess package:

<< Tess.m

Implemented and mapped functions.

The generic object is TessGraph, and it contains all data about a given tessellation. It is the output of Tess procedure. TessGraph object is used in some more advanced applications, but TessGraphics and TessShow procedures can be called directly with options for Tess procedure which is then internally invoked. Thus, Tess is always started, either directly by the user, or indirectly through plotting functions. The intermediate steps with Tess and TessGraph are left because some other manipulations can be performed (isometric transformations for instance) different then just plotting.

The basic procedure: Tess[vertex].

The first usage of Tess procedure is to test the existence of the tessellation. We test {4,4,4,6} vertex configuration:

Tess[{4, 4, 4, 6}, Test -> All]

The option Info is by default On and the additional data is printed as a side effect. First, we learn that this is hyperbolic (L2) tessellation, then calculated angles and generation groups are shown. There are 3 uniform realizations (Order was assumed to be 1) of {4,4,4,6} configuration. Next, the quantity sum is printed for the vertex configuration {n1,...,nN}. It is equal to sum=(n1-2)/n1+...(nN-2)/nN. For elliptic (S2) tessellations the sum is sum<2 , Euclidean (E2):  sum=2, and L2 case: sum>2. The polygons are given by the fundamental triangulation, and all angles forming the vertices and faces are displayed. For instance Alpha are angles between sides in each polygon: Alpha4=1.4581860386714987 radians (it can be copied from above output) is side angle of quadrilaterals, and Alpha6=1.9086271911650905 in hexagons. The fundamental triangulation always exists, but it does not imply existence of tessellation. The data about the geometry, are followed by the list of realizations (if any). Program checks whether the tilling is uniform or not, and if reflections belong to the symmetries of the whole tessellation (snub if not, also called enantiomorphic). Then, congruence classes of polygons are displayed, and the mappings between the nearby polygons (group).  The congruence is defined by the symmetries; the `same' polygons can isometrically transformed to each other while the whole tiling remains the same. It is necessary that congruent polygons have the same number of sides, but it is not sufficient (see also further examples). Usually, the congruent polygons are colored with the same color.
Now we calculate two realizations of {4,4,4,6} configuration (with 40 polygons):

a1 = 
      Tess[{4, 4, 4, 6}, Info -> Off, 
        NPolygons -> 40]
a2 = 
      Tess[{4, 4, 4, 6}, Info -> Off, NPolygons -> 40, 
        Realization -> 2]

The head of the output is TessGraph:

Head[a1]

For the visualization there are two procedures: TessGraphics and TessShow.

Procedure TessGraphics[].

The usage of TessGraphics is very straightforward. As an example, we plot the previously calculated two realizations of {4,4,4,6} configuration:

Show[GraphicsArray[{TessGraphics[a1], TessGraphics[a2]}]]

Now we show available options (options 1 and Off are not used here) for the coloring (it may take a while for this command):

Show[
      GraphicsArray[{
{TessGraphics[a1, 
              Annotate -> Off], 
TessGraphics[a1, 
              Annotate -> Off, 
              PolygonColor -> Hue], 
TessGraphics[a1, 
              Annotate -> Off, 
              PolygonColor -> 
                GrayLevel]}, 
{TessGraphics[a1, 
              Annotate -> Off, 
              PolygonColor -> {4 -> 1/6, 
                  6 -> 0}], 
TessGraphics[a1, 
              Annotate -> Off, 
              PolygonColor -> {1 -> Hue[1/6], 2 -> Hue[1/2], 
                  3 -> Hue[2/3]}], 
TessGraphics[a1, 
              Annotate -> Off, 
              PolygonColor -> {4 -> RGBColor[ .4,  .4, 1], 
                  6 -> 
                    RGBColor[0, 1, 0]}]}, 
{TessGraphics[
              a1, Annotate -> Off, 
              PolygonColor -> Union], 
TessGraphics[
              a1, Annotate -> Off, 
              PolygonColor -> 2], 
TessGraphics[a1, 
              Annotate -> Off, 
              PolygonColor -> Random]}
}]]

In most cases one will avoid direct use of both Tess procedure and TessGraph objects, since the procedure TessShow directly plots the tessellation on the screen. It is doing the same as TessGraphics except it calls at the end the system procedure Show and plots the output to the screen.

Procedure TessShow[].

We plot directly on the screen one interesting polyhedra:

TessShow[{4, 3, 4, 5}]

The same polyhedra, but in Sphere model, without quadrilaterals:

TessShow[{4, 3, 4, 5}, Model -> Sphere, 
      Polygon -> {4 -> Off, 3 -> On, 
          5 -> On}]

This is the E2 `cousin' of the polyhedra from above (with 200 polygons and specified plot range):

TessShow[{4, 3, 4, 6}, NPolygons -> 200, 
      PlotRange -> {{-5, 5}, {-5, 5}}]

The input vertex configuration (list) can be cyclically rotated and reversed, and still it describes the same tessellation(s). Procedure TessCompare can be used for testing.

Testing the equivalence of the two vertex configurations: procedure TessCompare[].

This is the same vertex configuration:

TessCompare[{3, 3, 3, 4, 6}, {3, 6, 4, 3, 3}]

The object with the head TessGraph contains all data about a tilling, and we can extract coordinates of vertices or faces with procedures that bear the same name.

Extracting the coordinates of faces and vertices.

For further examples we extract first two vertices of the tilling {4,4,4,6} realization number 1 that we calculated in one of the previous examples:

{pt1, pt2} = Take[  Vertices[a2]  ,  2 ]

For the systematic search of the possible tessellations one can use the function SearchVertices.

Searching for the tessellations: SearchVertices[].

This command (it may take a while) will reveal all 8 uniform non-regular E2 tilings (J. Kepler):

SearchVertices[0, 2, 12, 5, Infinity, 
      Infinity, {2, Infinity}]

And this finds all 13 uniform non-regular polyhedra (S2 tessellations - Archimedes):

SearchVertices[0, {0, 1.99}, 10, 5, Infinity, Infinity, {2, Infinity}, 
      False]

Specially for L2 tessellations isometries from L2Primitives package (L2Reflection, L2Translation, L2Rotation) are mapped so that they can work on tessellations as well. Isometries are simply applied to each point of the tilling.

Mapped L2 isometries.

First we translate (in hyperbolic plane) the tilling {4,4,4,6} realization number 2 (examples above) along the line connecting first two vertices:

res1 = L2Translation[pt1, pt2][a2]

Then we rotate the result for an angle: Pi-Alpha6 (Alpha6 is mentioned above along the testing the existence of the tessellation and explaining the fundamental triangulation) with respect to the second vertex:

res2 = L2Rotation[pt2, Pi - 1.9086271911650905][res1]

And we reflect the result with respect to the point {0,0}:

res3 = L2Reflection[PDPoint[{0, 0}]][res2]

The last result is the same as the starting tessellation (up to the different order of polygons):

Show[
      GraphicsArray[{
TessGraphics[a2, 
            Annotate -> Off], 
TessGraphics[res1, 
            Annotate -> Off], 
TessGraphics[res2, 
            Annotate -> Off], 
TessGraphics[res3, 
            Annotate -> Off]}]]

We can check this comparing the coordinates for two vertices:

{pt1, pt2}
Vertices[res3] [[{3, 4}]]

The next set of commands is producing an interesting comparison between tilings:

c1 = 
        TessGraphics[{6, 6, 7}, NPolygons -> 60, Annotate -> Off, 
          Thickness -> 0.0005, 
          PolygonColor -> {6 -> Hue[1/6,  .4, 1], 
              7 -> RGBColor[0, 1, 0]}];

    c2 = 
        Tess[{7, 7, 7}, Info -> Off, 
          NPolygons -> 30];

    c3 = L2Reflection[PDPoint[{0, 0}]][c2];

    c4 = 
        TessGraphics[c3, Annotate -> Off, Border -> Off, 
          Polygon -> Off, 
          PolygonColor -> {6 -> Hue[1/6,  .4, 1], 
              7 -> RGBColor[0, 1, 0]}];

    c5 = 
        TessGraphics[{3, 3, 3, 3, 3, 3, 3}, Polygon -> Off, 
          Border -> Off, Annotate -> Off, NPolygons -> 40, 
          LOrigin -> PDPoint[{0, 0}], 
          Order -> 0];

    Show[{c1, Graphics[RGBColor[1, 0, 0]], c4}];

    Show[{c1, Graphics[RGBColor[0, 0, 1]], c5}];

The pictures show that tessellations {7,7,7} (3 times 7) and {3,3,3,3,3,3,3} (7 times 3) are dual, and the tessellation {6,6,7} can be obtained from them using some operations on faces or vertices (truncation).

Now we test the existence of one very interesting combination of polygons: {3,4,3,4,4}. This is one example where the old algorithm (Order->0) is faster (if you know what to look for):

Tess[{3, 4, 3, 4, 4}, Test -> On, Order -> 0]

There is one realization which is not uniform and it is snub (reflections are not mapping this tessellation into itself).

TessShow[{3, 4, 3, 4, 4}, PolygonColor -> Hue, 
      NPolygons -> 200, Order -> 0]

This is not the uniform tessellation: there is no isometry between the vertices that belong to the red triangle and cyan quadrilateral (stripes) that would leave the tessellation unchanged.

Here, you can see the only non-uniform realization in both Euclidean and elliptic geometry (it can take a while for this commands). It is {3,4,4,4} polyhedra, the left one is uniform, but the right one is not (lower un upper triangles can not be mapped to each other):

view = {-3.2, -0.8, 0.7};
Show[
      GraphicsArray[{
Show[{
TessGraphics[{3, 4, 4, 4}, Polygon -> {3 -> On, 
                    4 -> Off}, 
Realization -> 1, 
                Order -> 2, 
                ViewPoint -> view], 
TessGraphics[{3, 
                  4, 4, 4}, 
                Polygon -> Off, 
Realization -> 
                  1, Order -> 2, 
                ViewPoint -> view]
}, 
            DisplayFunction -> 
              Identity], 
Show[{
TessGraphics[{3, 4, 4, 4}, 
                Polygon -> {3 -> On, 1 -> Off, 2 -> Off, 
                    4 -> Off}, 
Realization -> 2, 
                Order -> 2, 
                ViewPoint -> view], 
TessGraphics[{3, 
                  4, 4, 4}, 
                Polygon -> Off, 
Realization -> 
                  2, Order -> 2, 
                ViewPoint -> view]
}, 
            DisplayFunction -> 
              Identity]
}]]

One hyperbolic example of the configuration {4,4,4,6} (left uniform, right non-uniform of order 2; it may take a while for this):

Show[
      GraphicsArray[{
TessGraphics[{4, 4, 4, 6}, 
            Realization -> 1], 
TessGraphics[{4, 4, 4, 
              6}, Realization -> 9, Order -> 2, 
            FirstPoly -> 6]
}]]

Now, lets take a look at the `normal' and `colored' version of tessellation {4,4,4,6}:

Show[
      GraphicsArray[{
TessGraphics[{4, 4, 4, 6}, 
            Realization -> 
              1, 
PolygonColor -> {3 -> Hue[0], 
                2 -> Hue[2/3], 
                1 -> Hue[1/6]}], 
TessGraphics[{4, 4, 
              4, 6}, Realization -> 3, 
            PolygonColor -> {4 -> Hue[0], 3 -> Hue[2/3], 
                2 -> Hue[1/6], 
                1 -> Hue[1/8]}]
}]]

The right tiling is a `colored' version of the left one. They are the same, except some of the yellow quadrilaterals from left picture are turned to orange color. In the right picture we consider that yellow and orange quadrilaterals are different. Then, symmetries are different, as well as corresponding congruency classes, since it is not allowed to map with isometries yellow and orange quadrilaterals in the right tilling. And now, another example for {3,3,3,3,3,4}:

Show[
      GraphicsArray[{
TessGraphics[{3, 3, 3, 3, 3, 4}, 
            Realization -> 
              2, 
PolygonColor -> {3 -> Hue[0], 
                1 -> Hue[2/3], 
                2 -> Hue[1/6]}], 
TessGraphics[{3, 3, 
              3, 3, 3, 4}, 
            Realization -> 
              1, 
PolygonColor -> {4 -> Hue[0], 
                1 -> Hue[2/3], 2 -> Hue[1/6], 
                3 -> Hue[1/8]}]
}]]

Here we show some non-uniform realizations of {3,3,3,3,3,4} vertex configuration:

Show[
      GraphicsArray[{
TessGraphics[{3, 3, 3, 3, 3, 4}, 
            Realization -> 1, Order -> 0, 
            NPolygons -> 200], 
TessGraphics[{3, 3, 3, 
              3, 3, 4}, Realization -> 2, Order -> 0, 
            NPolygons -> 200]
}]]

Lets see {3,3,3,3,7} hyperbolic tessellation in two different models of visualization. This one is `snub' or `enantiomorphic', meaning that reflections do not belong to the symmetries of the tessellation - there are `left' and `right' versions, mirror symmetric to each other.

a3 = 
        Tess[{3, 3, 3, 3, 7}, Order -> 0, NPolygons -> 300, 
          Info -> Off];
Show[
      GraphicsArray[{
TessGraphics[a3, 
            Model -> PoincareDisk], 
TessGraphics[a3, 
            Model -> KleinDisk]
}]]

Below are some interesting examples...

TessShow[{4, 8, 10}, NPolygons -> 200]

TessShow[{4, 6, 10}]

TessShow[{3, 6, 4, 6}, NPolygons -> 200]

TessShow[{3, 3, 3, 3, 4}, Model -> Sphere, EdgeForm -> 0, 
      PlotPoints -> 3]

TessShow[{3, 3, 4, 3, 4}, PlotRange -> {{-4, 4}, {-4, 4}}, 
      NPolygons -> 200]

TessShow[{3, 3, 5, 3, 4}, NPolygons -> 300]

However, not all vertex configurations form a tessellation:

Tess[{3, 5, 4, 5}, Test -> All]