Setting aside the small matter of the discovery in 2023 of an aperiodic monotile, here are some notes (in lieu of a long slack post) on where the weavingspace project is at. Most links in the below are to items in the glossary.
2 February 2024
The latest round of coding has added a lot, particularly with respect to correctly implementing the labelling of distinct transitivity classes of tiling vertices, tiling edges, and tiles themselves.
In our case translations are baked in—we know these exist, because we put them there. Finding rotation and reflection symmetries which preserve the tiling is necessary for detecting transitivity classes, which in turn is required to label edges and vertices in order to support principled modification of tiles so as to maintain tileability.
Getting to this point has revealed some weaknesses in the Rube Goldberg / Heath Robinson machinery along with other desiderata.
In no particular order:
The whole point of venturing into topology was to enable principled modification of tiles—typically making them more ‘elaborate’ in an Escher-like way. For example, this tiling is derived (by hand) by putting a sinusoidal curve along each edge of square tiling, and indicates the surprising variety in tilings that might be enabled by allowing this possibility.
At the moment the only modification we’ve got is to ‘zig-zag’ an edge. More transforms of edges/vertices remain to be considered.
The tile corner / tiling vertex distinction is not carefully observed in the code. The transitivity class implementation should make this easier to do. For example it should be easy enough now to not label corners, as the logic of tiling symmetry implies.
The symmetry
code
The symmetry code needs to be revisited: it works, but the 'clever' quick fix that reuses code for finding the symmetries of a single polygon to identify the transformations between two distinct tiles is shaky. In particular when presented with a polygon and its mirror image, if the polygon has no rotational symmetries the function returns a None
result, suggesting the two polygons are unrelated. This has possible implications for the reliability of correctly labelling some tilings. While the 12-slices of a hexagon (Laves 4.6.12) tiling is correctly labelled, the two orientations of triangle are incorrectly assigned to different 'groups' during Topology
construction.
Also in relation to symmetries it would be nice on a diagram like that below to show the symmetry involved in each transformation. This relates to how tiling symmetries are implemented as a class. Although they are currently a class, there's not a lot there... This is also related to the previous point about transformations between two distinct polygons and would be a secondary goal of addressing the symmetry code issues.
Late in the process of implementing transitivity classes, I (with some reluctance) imported networkx
to resolve a gnarly problem of extracting the 'exclusive supersets' of a list of sets. And of course... 5 lines of graph code specifically the connected_components
method and the problem disappeared.
On reflection there are a number of places in the transitivity class code, which are effectively tackling the same problem in a more roundabout way, and it might pay to revisit them with that tool at hand. It could perhaps make the code a lot easy to follow (and perhaps quicker too).
The first round of attempts to label vertices and edges was 'tile-centric' and revolved around labelling tile corners and sides under the tile's symmetries. It remains to be seen if this code still has a role to play.
At the moment, the Topology
code is almost entirely independent of the main codebase. A Topology
object is constructed by supplying a Tileable
instance, and the code makes extensive use of functions in the tiling_utils
module, but no more than that. Whether a Topology
should be embedded in a Tileable
by default, or whether one should be used to generate dual tilings or not is an open question [the dual generation code in Topology
is much more satisfying and (probably) robust than the tiling_utils
implementation].
Because of how they are generated our weave based Tileable
objects (WeaveUnit
s) often contain more tiles than strictly required. In many biaxial tilings there are two times the required number. In the triaxial case it is often much worse than that with as many as 9 times more tiles than required. This causes the Topology
code to choke and fail. Needs investigation...
An attempt to define terms and how they relate to aspects of the code.
A point on the perimeter of a tile polygon where the perimeter changes direction. A polygon corner in the usual sense. Distinct from a tiling vertex. Corners are properties of individual tiles, not of the tiling.
The tiling formed from an existing tiling by placing a vertex at each tile and joining them by edges between any two tiles that share an edge in the original tiling. Tiles become vertices and vertices become tiles. The relation is reciprocal and essentially topological not geometric, since the placement of a vertex in a tile is ill-defined. An important dual relation is that between the Archimedean and the Laves tilings.
The line along which two tiles in a tiling meet. An edge has a vertex at each end and any number of corners along its length. Edges are a property of a tiling, not of individual tiles.
Collective term for tiles, edges and vertices.
A subset of a tiling which under two non-parallel translations can tile the plane. It is important to realise that the fundamental unit of a tiling is not uniquely defined. In a tiling with two orthogonal translation vectors, for example, any square region defined by those two vectors is a fundamental unit. In our implementation approximately equivalent to a Tileable
.
A tiling with two non-parallel translations among its symmetries.
Any one of the tiles that constitute a tiling. A set of prototiles is said to 'admit' a tiling. In our implementation the term is applied to the geometric union of the polygons in a Tileable
, which is closer to the fundamental unit. Refactoring to make things map better onto the literature is an option...
The image of a geometric object under a reflection transformation is its mirror image. A possible symmetry of a tile or tiling. Defined by a line of symmetry in which the reflection occurs.
A transformation of the plane around a fixed point (the centre of rotation) by a given angle. One of the possible symmetries of a tile or tiling.
A side of a polygon as commonly understood, connecting two of its corners. Distinct from a tiling edge. There is always a change in direction at a corner, but there may be many corners along a tiling edge. Tile corners and tiling vertices are often coincident but a vertex is not always a corner (there might be no change in direction) and corner is not always a vertex (if it is along an edge, when it will be incident on only two tiles).
OMG. All of mathematics. But seriously... albeit briefly, in our context a symmetry is any transformation of a tiling that maps its elements back on to other elements. Tiles also have symmetries but the symmetries of a tiling and of its constituent tiles are not the same. For example in the example above of the Cairo tiling the tiles have only a single reflection symmetry (also symmetry of the tiling), but the tiling also has 90° rotational symmetries.
A polygon that when arranged in a tiling exhausts the plane. A polygon is formed by straight sides connecting corners.
A covering of the plane with tiles. According to Grünbaum and Shephard 1987, page 16:
"... a countable family of closed sets
$\mathcal{T}={T_1,T_2,\ldots}$ which covers the plane without gaps or overlaps. More explicitly, the union of the sets$T_1,T_2,\ldots$ (which are known as the tiles of$\mathcal{T}$ ) is to be the whole plane, and the interiors of the sets$T_i$ are to be pairwise disjoint"
So... a close cousin to a GIS coverage then...
A one-to-one mapping of every point in the plane to another point in the plane.
A group of elements (tiles, vertices, or edges) that map onto one another under the symmetries of the tiling. This concept is a subtle one. The tiling below has two transitivity classes of tile, since there is no transformation that maps central tiles on to outer tiles while also mapping all tiles onto a tile. Those central tiles only ever map onto other central tiles, hence they are in a different transitivity class than the outer tiles, which form a second transitivity class. A tiling with one transitivity class is termed isohedral, and 2-hedral, n-hedral etc. are terms that are also used. Similar notions apply to vertices and edges, where the terms are respectively isogonality and isotoxality. The isohedral tilings of the plane have been thoroughly explored (for example it is proven that there are 81 types...).
A transformation in which every point in the plane is displaced by a defined vector, i.e.
Points in a tiling at which three or more tiles meet, which are therefore the end points of tiling edges. Often but not always coincident with the corners of tiles. In particular tiling vertices may result from the tiling. For example in the 'cheese sandwich' tiling above, the tiling induces two vertices along the long sides of each rectangle.
A general term for the process of assigning tiles, vertices and edges to transitivity classes, which allows them to be labelled. Currently tiles don't get labelled, but since they are in transitivity classes it wouldn't be hard to do this.
A simple polygon associated with a Tileable
object derived from either a rectangle or a hexagon.
This really only matters for weave based tilings where generation of the Tileable
object produces 'fragments' that are parts of the tiles that lie outside the simple prototile rectangle of hexagon shape. Some nasty code attempts to assemble such fragment back into a more manageable set and the result jigaw puzzle shaped piece is the regularised prototile. Here's an example (the red outline below):
An early implementation of labelling relied on labelling the corners and sides of tile polygons. Identifying the different shapes in a tiling was a key step in this process. There is still a tile_groups
attribute of the Topology
class as a result. More work on the symmetry code will probably make these assignments more reliable.
The central object class in the code base. A Tileable
instance has the following attributes that more or less loosely link to the mathematical concepts above:
tiles
a geopandas.GeoDataFrame of shapely.geometry.Polygon objects, with associatedtile_id
(by default a single character string) identifying tiles that can be associated with different data attributes.prototile
also aGeoDataFrame
, containing a single polygon shape which will be a rectangle or hexagon or simple modification (by stretching or skewing) of those, which indicates how the tiling can be constructed. Vectors joining opposite faces of the prototile form thevectors
of theTileable
and model the translation symmetries of the tiling.regularised prototile
also aGeoDataFrame
containing a single polygon. It is possible for theprototile
to cut across tile polygons in theTileable
; the regularised prototile is a different tileable polygon containing only complete tiles.vectors
a set of tuples of x and y displacements by which the polygons in theTileable
'stiles
attribute are 'copied and pasted' across a map area. These are not a minimal set of translation vectors. For example, hexagonally based tilings have 6 vectors (3 each in two different directions) where a strict mathematical representation would require only 2 (the third is the difference between the other two).
A specialisation of the Tileable
class that represents 'traditional' geometric tilings, constructed by geometry as implemented in the tiling_geometries
module.
A class that attempts to represent the elements in a tiling (i.e. tiles, vertices and edges) and the relations among them, in particular enabling labelling by detecting the transitivity classes of the tiling.
An Tileable.tiles
polygons are combined to yield a tiling.
A specialisation of the Tileable
class that represents tilings that can be produced by weaving. A particular feature of note is the aspect
attribute which defines the width of 'strands' in the weave relative to their spacing, and may mean that the resulting tiling has 'holes' (and are hence not tilings as defined by Grünbaum & Shephard). Note that there is theory of isonemal tilings which are precisely tilings that can be generated by weaving albeit without gaps (which in our implementation equates to aspect = 1
).