15

I need a grid made up of pieces that look like a hat in tikz. Here is the piece with four hats. Could you help? Can we use a tikzlibrary for tiling of this?

aperiodic tiling

\documentclass[border=3pt]{standalone}

\usepackage{tikz}

\begin{document}
    
    
\begin{tikzpicture}[rotate=-0]
\def\ra{1}
    \coordinate(O) at(0,0);
\coordinate(A1) at(0:\ra);
\coordinate(A2) at(60:\ra);
\coordinate(A3) at(120:\ra);
\path(A2)--(A1)--([turn]-60:\ra/2)coordinate(A01);
\draw[fill=yellow!6, thick](O)--(A01)--(A1)--(A2)--++(-\ra/2,0)--++(0,\ra)--([turn]60:\ra)--([turn]90:\ra/2)--([turn]60:\ra/2)--([turn]-90:\ra)--++(0,-\ra)coordinate(A3)--++(\ra/2,0)coordinate(A4)--([turn]-60:\ra/2)coordinate(A5)--cycle;

\draw[fill=gray!6, thick](O)--(A5)--(A4)--(A3)--++(-\ra/2,0)--([turn]60:\ra/2)coordinate(B1)--([turn]90:\ra)coordinate(B2) --++(0,-\ra)coordinate(B3)--++(\ra/2,0)coordinate(B4)--([turn]-60:\ra/2)coordinate(B5)--([turn]90:\ra)coordinate(B6)--++(0,\ra)coordinate(B7)--++(\ra/2,0)coordinate(B8)--(A01)--cycle;

\draw[fill=purple!6, thick](A01)--(B8)--(B7)--(B6)--(B5)--([turn]90:\ra/2)coordinate(D1)--++(\ra, 0)--([turn]60:\ra/2)--([turn]-90:\ra)--([turn]60:\ra)--([turn]90:\ra/2)--++(-\ra/2,0)--++(0,\ra)--(A01); 

\draw[fill=teal!6, thick](B5)--(B4)--(B3)--(B2)--(B1)--([turn]90:\ra/2)coordinate(C1)--([turn]60:\ra/2)--([turn]-90:\ra)--++(0,-\ra)--([turn]90:\ra/2)--([turn]-60:\ra/2)--([turn]90:\ra)--([turn]-60:\ra)--(D1)--cycle;

\end{tikzpicture}

\end{document}
6
  • 2
    Interesting that someone came with that very new shape and asks for tiling it here. You need to use a pic to tile those. But when it comes to place them correctly, it could be challenging. Good question.
    – SebGlav
    Commented Apr 3, 2023 at 16:24
  • 1
    github.com/loopspace/penrose/commit/… Commented Apr 3, 2023 at 22:01
  • 2
    This is the "einstein" -- recently reported in the press. Eg sciencenews.org/article/mathematicians-discovered-einstein-tile The paper announcing the discovery has some details about how to create the tiling.
    – Thruston
    Commented Apr 3, 2023 at 22:17
  • 1
    I'm not keen on the "ein stein" pun since mathematics has enough of a problem with naming things after the wrong person, but even using it then this tile is an "ein stein", not the "ein stein" so it is better to use a more specific name for it. Commented Apr 3, 2023 at 22:26
  • You say Here is the piece with three hats but I see four of them (four rotated copies of the same shape). Did I misunderstand what you mean by a hat? Commented Apr 4, 2023 at 7:54

3 Answers 3

19

There is a TikZ library for this, originally designed for Penrose tilings from https://tex.stackexchange.com/a/440412/86, and I am in the process of updating it for the new tile. Currently, I have the hat and turtle with a command for defining a Tile(a,b), and the meta and super cluster tiles. I'm now working on the substitution system for the super clusters, and wondering about the subclusters.

You can find the latest version on github, there's a release with all the necessary files in it, or for the bleeding edge version then the key file is penrose_code.dtx, download that and run tex penrose_code.dtx to generate the necessary files.

\documentclass{article}
%\url{https://tex.stackexchange.com/q/681708/86}
\usepackage{tikz}
\usetikzlibrary{
  tilings.polykite,
  calc,
}

\tikzset{
  hexagon/.pic={
    \path[pic actions] (1,0)
    foreach \k in {1,...,6} { -- (\k*60:1)}
    foreach \k in {1,...,6} {(0,0) -- (\k*60:1)}
    foreach \k in {1,...,6} {(0,0) -- (\k*60+30:{sqrt(3)/2})}
    ;
  },
  every tile/.style={draw}
}

\begin{document}

\begin{tikzpicture}[
  every aperiodical hat/.style={
    draw,
    ultra thick
  },
]
\pic[draw=none,fill=gray!50] {aperiodical hat};
\pic[draw,gray] at (-1,0) {hexagon};
\pic[draw,gray] at (60:1) {hexagon};
\pic[draw,gray] at (-60:1) {hexagon};
\pic[aperiodical hat,name=hat-a];
\pic[aperiodical hat,name=hat-b,align with=hat-a along 11 using 4];
\pic[aperiodical hat,name=hat-c,align with=hat-a along 26 using 7];
\pic[aperiodical hat,name=hat-d,align with=hat-a along 24 using 5];
\pic[aperiodical hat,name=hat-e,align with=hat-a along 13 using 2];
\pic[aperiodical hat,name=hat-f,align with=hat-a along 16 using 5];
\pic[red,flip tile,aperiodical hat,name=hat-g,align with=hat-a along 21 using 3];
\pic[aperiodical hat,name=hat-h,align with=hat-g back along 14 using 6];
\end{tikzpicture}
\end{document}

The above produces:

Aperiodical hat using the penrose package

6
  • Wow - I didn't even know TeX had such an expressive language. But do you really want to do the complex substitution stuff in that? Or does TikZ actually have a nicer language? Note relate discussions and implementations at Add features for patch generation via substitution with customized visualization · Issue #3 · isohedral/hatvalidate - the Mathematica one is the best documented that I've seen. The hatviz code is pretty dense especially for a non-Javascript type like me....
    – nealmcb
    Commented Apr 9, 2023 at 16:33
  • @nealmcb I implemented the substitution code for Penrose tiles using the syntax of Lindenmayer systems so I already have the framework for it, just need to isolate the individual substitutions. This is never going to be the most efficient code, though. Commented Apr 9, 2023 at 16:57
  • 1
    @nealmcb Presumably it would be helpful. At the moment, I have the substitution system worked out for the super clusters (in a different language - I have two tiling programs that I work with). That could be used to generate a polykite tiling, I suppose, by extracting the combinatorial data and then applying it to a polykite tiling. Commented Apr 9, 2023 at 19:22
  • 1
    Note also this fascinating alternative construction scheme, as an alternative to the original substitution approach: Two algorithms for randomly generating aperiodic tilings
    – nealmcb
    Commented Apr 14, 2023 at 22:44
  • 1
    @nealmcb Thought you might be interested: github.com/loopspace/penrose/commit/… Picture at twitter.com/mathforge/status/1656063048421978113?s=20 Commented May 9, 2023 at 22:29
15

First, let's draw the tile more precisely and also choose a corner as coordinate zero:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}

\draw (0,0) coordinate (-i0)
    -- ++(60:1/2) coordinate (-i1)
    -- ++(120:1) coordinate (-i2)
    -- ++(180:1/2) coordinate (-i3)
    -- ++(90:{sin(60)}) coordinate (-i4)
    -- ++(150:{sin(60)}) coordinate (-i5)
    -- ++(240:1/2) coordinate (-i6)
    -- ++(300:1/2) coordinate (-i7)
    -- ++(210:{sin(60)}) coordinate (-i8)
    -- ++(270:{sin(60)}) coordinate (-i9) 
    -- ++(0:1/2) coordinate (-i10)
    -- ++(300:1/2) coordinate (-i11)
    -- ++(30:{sin(60)}) coordinate (-i12)
    -- cycle;

% adding the labels
\foreach \i in {0,...,12} {
    \pgfmathparse{int(\i == 3 || \i == 9 ? 1 : 0)}
    \draw[red] (-i\i) circle[radius=2pt];
    \ifnum\pgfmathresult=1\relax
        \node[below, red, font=\ttfamily\tiny] at (-i\i) {(-i\i)};
    \else
        \node[right, red, font=\ttfamily\tiny] at (-i\i) {(-i\i)};
    \fi
}

\end{tikzpicture}
\end{document}

enter image description here

Having this, we can create a pic from it. Since we would like to mirror and rotate this pic and also place it relative to others, we need to create it in a special way so that we first create the coordinates and only then draw the path having the possibility to shift and rotate the coordinates:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\newif\ifaperiodicalhatmirrored
\tikzset{
    pics/aperiodical hat/.style={
        code={
            \tikzset{
                aperiodical hat/.cd, 
                #1,
                coordinate transformation/.style={
                    rotate around={\pgfkeysvalueof{/tikz/aperiodical hat/rotate around inner anchor}:(-inner anchor)},
                    shift={($(-outer anchor)-(-inner anchor)$)},
                }
            }
            \ifaperiodicalhatmirrored
                \path[xscale=-1]
            \else
                \path
            \fi
                (0,0) coordinate (-i0)
                -- ++(60:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}/2}) coordinate (-i1)
                -- ++(120:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}}) coordinate (-i2)
                -- ++(180:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}/2}) coordinate (-i3)
                -- ++(90:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}*sin(60)}) coordinate (-i4)
                -- ++(150:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}*sin(60)}) coordinate (-i5)
                -- ++(240:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}/2}) coordinate (-i6)
                -- ++(300:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}/2}) coordinate (-i7)
                -- ++(210:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}*sin(60)}) coordinate (-i8)
                -- ++(270:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}*sin(60)}) coordinate (-i9) 
                -- ++(0:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}/2}) coordinate (-i10)
                -- ++(300:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}/2}) coordinate (-i11)
                -- ++(30:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}*sin(60)}) coordinate (-i12)
                -- cycle;
            \coordinate (-inner anchor) at (\pgfkeysvalueof{/tikz/aperiodical hat/inner anchor});
            \coordinate (-outer anchor) at (\pgfkeysvalueof{/tikz/aperiodical hat/outer anchor});
            \path[pic actions]
                ([aperiodical hat/coordinate transformation]-i0) coordinate (-o0)
                    foreach \x in {1,...,12} { 
                        -- ([aperiodical hat/coordinate transformation]-i\x) coordinate (-o\x)
                    } -- cycle;
        }
    },
    aperiodical hat/base unit/.initial={1},
    aperiodical hat/inner anchor/.initial={0,0},
    aperiodical hat/outer anchor/.initial={0,0},
    aperiodical hat/rotate around inner anchor/.initial={0},
    aperiodical hat/mirrored/.is if={aperiodicalhatmirrored}
}

\begin{document}
\begin{tikzpicture}

\pic[draw, fill=yellow!6] (tile1) {aperiodical hat};

\pic[draw, fill=black!6] (tile2) {aperiodical hat={inner anchor={-i5}, rotate around inner anchor=-60, mirrored}};

\pic[draw, fill=red!6] (tile3) {aperiodical hat={inner anchor={-i9}, rotate around inner anchor=240}};

\pic[draw, fill=green!6] (tile4) {aperiodical hat={inner anchor={-i2}, outer anchor={tile2-o10}}};

\end{tikzpicture}
\end{document}

enter image description here

The pic aperiodical hat takes the following options:

  • base unit: factor to scale the tile.
  • inner anchor: anchor of the current tile.
  • outer anchor: anchor of another tile (or some coordinate) which the anchor specified with inner anchor should sit at.
  • rotate around inner anchor: degrees the tile should be rotated around the coordinate specified by inner anchor.
  • mirrored: if used, the tile is mirrored.

There are two sets of anchors in each pic. The first set is -i0 to -i12 and represents the corners of the tile before it is rotated and shifted (but after it has been mirrored). The second set is -o0 to -o12 and represents the corners of the tile after all transformations are applied. For inner anchor the first set (-i0 to -i12) should typically be used, for outer anchor the second set (-o0 to -o12) should be used.

Having this functionality, I assume it should be possible to create also larger tilings ...

1
  • What a beautiful tutorial! Thank you!
    – PatrickT
    Commented Jan 15 at 3:17
10

Another \pic version. This one uses a hexagonal grid with coordinates to place the tiles. As we have an 'aperiodic tiling' we need to place the tiles by hand but the grid helps with that.

For example, trying to replicate part of the first image here the code could be:

\documentclass[tikz]{standalone}
\usetikzlibrary{calc}

\tikzset
{%
  tile1/.style={thick,draw=black,fill=blue!40!cyan},
  tile2/.style={thick,draw=black,fill=cyan!50},
  tile3/.style={thick,draw=black,fill=gray!30},
  tile4/.style={thick,draw=black,fill=white},
  pics/tile/.style={
    code={%
    \path[pic actions] (0,0)            --++ (330:{cos(30)})  --++ (60:0.5)  --++ (120:1)   -|++
                       (-0.5,{cos(30)}) --++ (150:{cos(30)})  --++ (240:0.5) --++ (300:0.5) --++
                       (210:{cos(30)})  |-++ (0.5,{-cos(30)}) --++ (300:0.5) -- cycle;
    % to show the hexagons, remove it or comment it if you want
    \draw[very thin,gray] (30:{cos(30)}) -- (0,0) -- (150:{2*cos(30)})
                     (0,0) -- (90:{cos(30)}) --++ (180:0.5) --++ (120:0.5) --++ (30:{cos(30)})
                     (-1,0) --++ (60:1);
    }}
}

\begin{document}
\begin{tikzpicture}
% grid and clip
\foreach\i in {0,...,9} \foreach[count=\j]\jj in {A,...,H} 
  \coordinate (\jj\i) at ({\j+0.5*mod(\i,2)},{\i*cos(30)});
\clip[draw] ($(A1)+(-0.2,0.2)$) rectangle ($(G8)+(0.2,-0.2)$);
% tiles
\pic[tile2]                      at (B1) {tile};
\pic[tile2,rotate=240]           at (D2) {tile};
\pic[tile4,rotate=120]           at (G2) {tile};
\pic[tile1,rotate=300,xscale=-1] at (B3) {tile};
\pic[tile3,rotate=300]           at (E3) {tile};
\pic[tile2,rotate=60]            at (H3) {tile};
\pic[tile4,rotate=120]           at (A4) {tile};
\pic[tile2]                      at (D4) {tile};
\pic[tile4,rotate=60]            at (B5) {tile};
\pic[tile3]                      at (E5) {tile};
\pic[tile4,rotate=180]           at (G6) {tile};
\pic[tile3,rotate=240]           at (B7) {tile};
\pic[tile3,rotate=180]           at (A8) {tile};
\pic[tile2,rotate=120]           at (G8) {tile};
\pic[tile4,rotate=120]           at (E9) {tile};
% to show the grid
%\foreach\i in {0,...,9} \foreach[count=\j]\jj in {A,...,H} 
%  \fill (\jj\i) node[right] {\footnotesize$\jj\i$} circle (0.4mm);
\end{tikzpicture}
\end{document}

And produces: enter image description here

Update: A 'map' to help with placing the tiles could be enter image description here

13
  • 1
    The grid idea for placement simplifies things a bit lot indeed! I have to admit that I first did not realize that these tiles could be placed on a grid at all. Commented Apr 4, 2023 at 8:25
  • 1
    @JasperHabicht, my first approach was similar to yours, but the image in my link gave the idea for the grid Commented Apr 4, 2023 at 8:27
  • Can you make it a greater grid?
    – Epa
    Commented Apr 4, 2023 at 8:27
  • @Epa, you only need to modify the line \foreach\i in {0,...,9} \foreach[count=\j]\jj in {A,...,H}. Change 9 and H for any other number or letter. Commented Apr 4, 2023 at 8:28
  • 1
    @Epa If you want larger tiles, you can always scale things using x=2cm, y=2cm (or whatever dimension you like) as option to the tikzpicture. Commented Apr 4, 2023 at 8:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .