# How do I draw Archimedean lattices in LaTeX?

I was trying to draw these two lattices in LaTeX for hours, but making no progress. Could someone please remind me the key code of doing so? Thanks a lot! Happy New Year!

• The second one is easier since it is easy to see the pattern to be translated. The first one also has a pattern, but it is more complicated. – Sigur Jan 1 '15 at 22:13
• Since you tried for hours, you got already something? Please show that, so we can help to improve it. – Stefan Kottwitz Jan 1 '15 at 22:16
• Is there a rule between those numbers and the shape? – percusse Jan 1 '15 at 22:16
• @percusse, the number of sides of the polygons. – Sigur Jan 1 '15 at 22:17
• @Sigur Thank you so much for your help. I can work out (4,8^2) now. It's just the (4,6,12) is quite annoying :( – Gaoran Yu Jan 1 '15 at 23:12

Here's a quick attempt at (4,6,12) in Metapost that might provide a starting point for you in TikZ. It's based on repeating a unit shape, shown highlighted in pink below.

prologues := 3;
outputtemplate := "%j%c.eps";

beginfig(1);

u = 20;
dx = u*(1+cosd(15)/sind(15));
picture unit; unit = image(
path s; s = unitsquare shifted -(1/2,1/2) scaled u shifted (dx/2,0);
for t=0 upto 2:
draw s rotated 120t;
for tt=1 upto 3:
draw subpath(3,4) of s rotated (120t+30tt);
endfor
endfor
);

draw unit withpen pencircle scaled 4 withcolor .8[red,white];

for x=-5dx step dx until 5dx:
for y=-5dx step dx until 5dx:
draw unit shifted (x,0) shifted ((y,0) rotated 60);
endfor
endfor

path box; box = unitsquare shifted -(1/2,1/2) scaled 12u;
clip currentpicture to box; draw box dashed evenly;

endfig;
end.

• I really appreciate your kindly help. But could you please send me the LaTeX code? I try to follow your pseudocode but I'm new to tex so I'm not familiar with how to scale, rotate or shift the box. Thanks again for your answer! – Gaoran Yu Jan 2 '15 at 6:10
• @GaoranYu This isn't pseudo-code: it's Metapost code. See What is Metapost/Metafont and how can I get started using it? for some basic information. – Alan Munn Jan 2 '15 at 6:43
• @AlanMunn Any well written computer language looks like pseudo-code. Metapost is very underrated for what it can do. – Yiannis Lazarides Jan 2 '15 at 15:11

Here is one TikZ solution for (4,6,12) :

\documentclass[border=50]{standalone}
\usepackage{tikz}
\usetikzlibrary{math}
\usetikzlibrary{calc}

\tikzset{square/.style= { to path={ let \p1=(\tikztostart), \p2=(\tikztotarget),
\p3=($(\p2)!1!90:(\p1)$), \p4=($(\p1)!1!-90:(\p2)$) in
(\p4) -- (\p1) -- (\p2) -- (\p3) (\p2)}}}

\tikzmath{
function drawone(\x,\y,\size) {
{
\draw[shift={(\x,\y)}] foreach \a in {-120,0,120} {
[rotate=\a] (-15:\size) to[square] (15:\size) -- (45:\size) -- (75:\size) -- (105:\size) };
};
};
}

\begin{document}
\begin{tikzpicture}
\tikzmath{
\size = 2; \nx = 3; \ny = 4;
\xstep = (cos(15)+sin(15))*\size;
\ystep = 3*\xstep/tan(60);
for \i in {1,...,\nx}{
for \j in {1,...,\ny}{
drawone((2*\i+mod(\j,2))*\xstep,\j*\ystep,\size);
};
};
}
\begin{scope}[red,thick]
\tikzmath{drawone(2,3,\size);}
\end{scope}
\end{tikzpicture}
\end{document}


UPDATE: Here is the (4,82) case which is simpler :

\documentclass[border=50]{standalone}
\usepackage{tikz}
\usetikzlibrary{math}

\tikzmath{
function drawone(\x,\y,\size) {
{
\draw[shift={(\x,\y)},rotate=-22.5] (0:\size) foreach \a in {0,45,...,360}{ -- (\a:\size)};
};
};
}

\begin{document}
\begin{tikzpicture}
\tikzmath{
\size = .7; \nx = 8; \ny = 5;
\step = 2*\size*cos(22.5);
for \i in {1,...,\nx}{
for \j in {1,...,\ny}{
drawone(\i*\step,\j*\step,\size);
};
};
}
\end{tikzpicture}
\end{document}


A layman's approach (with no computations):

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{shapes.geometric}
\tikzset{
myshape/.pic = {
\node[name=s,regular polygon, regular polygon sides=12, minimum width=1cm, draw,
outer sep=0pt] at (0,0){};
\draw (s.corner 3) -- ([shift={(120:2mm)}]s.corner 3) --
coordinate (b)([shift={(120:2mm)}]s.corner 2)
-- (s.corner 2);
\draw (s.corner 7) -- ([shift={(240:2mm)}]s.corner 7) -- ([shift={(240:2mm)}]s.corner 6)
-- (s.corner 6);
\draw (s.corner 11) -- ([shift={(0:2mm)}]s.corner 11) --
coordinate[midway] (a)([shift={(0:2mm)}]s.corner 10)
-- (s.corner 10);
}
}
\begin{document}
\begin{tikzpicture}
\pic (p) at (0,0) {myshape};
\pic[anchor=west] (q) at (pa) {myshape};
\pic[anchor=west] (r) at (qa) {myshape};
\pic[anchor=west] (s) at (ra) {myshape};

\pic[anchor=south east] (pp) at (pb) {myshape};
\pic[anchor=south east] (qq) at (qb) {myshape};
\pic[anchor=south east] (rr) at (rb) {myshape};
\pic[anchor=south east] (ss) at (sb) {myshape};

\pic[anchor=south east] (ppp) at (ppb) {myshape};
\pic[anchor=south east] (qqq) at (qqb) {myshape};
\pic[anchor=south east] (rrr) at (rrb) {myshape};
\pic[anchor=south east] (sss) at (ssb) {myshape};
\pic[anchor=west]  at (sssa) {myshape};

\end{tikzpicture}
\end{document}


or

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{shapes.geometric}
\tikzset{
myshape/.pic = {
\node[name=s,regular polygon, regular polygon sides=12, minimum width=1cm+2.5\pgflinewidth, draw,
outer sep=0pt] at (0,0){};
\draw (s.corner 3) -- ([shift={(120:2mm)}]s.corner 3) --
coordinate (b)([shift={(120:2mm)}]s.corner 2)
-- (s.corner 2);
\draw (s.corner 7) -- ([shift={(240:2mm)}]s.corner 7) -- ([shift={(240:2mm)}]s.corner 6)
-- (s.corner 6);
\draw (s.corner 11) -- ([shift={(0:2mm)}]s.corner 11) --
coordinate[midway] (a)([shift={(0:2mm)}]s.corner 10)
-- (s.corner 10);
}
}
\begin{document}
\begin{tikzpicture}
\foreach \x in {0,1.2,2.4,3.6,4.8}{
\pic (p) at (\x,0) {myshape};
}
\foreach \x in {0.6,1.8,3,4.2,5.4}{
\pic (p) at (\x,1.05cm-\pgflinewidth) {myshape};
}
\foreach \x in {0,1.2,2.4,3.6,4.8}{
\pic (p) at (\x,2.1cm-2\pgflinewidth) {myshape};
}
\foreach \x in {0.6,1.8,3,4.2,5.4}{
\pic (p) at (\x,3.15cm-3\pgflinewidth) {myshape};
}
\end{tikzpicture}
\end{document}


and

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{shapes.geometric}
\tikzset{
myshape/.pic = {
\node[name=s,regular polygon, regular polygon sides=8, minimum width=1.1cm-\pgflinewidth, draw,
outer sep=0pt] at (0,0){};
}
}
\begin{document}
\begin{tikzpicture}
\foreach \x in {0,1,2,3,4}{
\foreach \y in {0,1,2,3,4}{
\pic (p) at (\x,\y) {myshape};
}
}
\end{tikzpicture}
\end{document}

• (+1) for the (4,8^2) case. I think that using the idea of this case you can make the first one realy in a simpler way : create a pic using one node with regular polygon sides=12 and 3 square nodes with \foreach \i in {-120,0,120} \path[rotate=\i] (0:some distance) node[transform shape,...]. Then adapt your two step loop to draw two lines of shapes, one half xshifted. – Kpym Jan 2 '15 at 15:38

Here is a solution for the (4,6,12) case using to path.

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{calc}
\tikzset{
xy/.style args={(#1,#2)}{ x={(#1,#2)}, y={({-1*(#2)},#1)} },
sq/.style= { to path={ let \p1=(\tikztostart), \p2=(\tikztotarget), \p3=($(\p1)!.5!(\p2)$) in
{[shift={(\p3)},xy={(\x2-\x1,\y2-\y1)},scale={.5/(1+cot(15))}]
foreach \i in {1,-1}{ [scale=\i] (1,-1) -- (1,1) -- +(60:2) (1,1) -- (-1,1)} (\p2)}}}}
\begin{document}
\begin{tikzpicture}
% demonstrate to[sq]
\draw[green] (0,0) to ++(0:1) (0,0) to ++(120:1);
\draw[ultra thick,red] (0,0) to[sq] ++(1,0) (0,0) to[sq] ++(120:1);

% draw the patern
\foreach \x in {-2,...,2}{
\foreach \y in {-2,...,2}{
\draw ({\x+.5*\y},{.5*\y*tan(60)}) to[sq] ++(0:1) to[sq] ++(120:1) to[sq] ++(-120:1);
}
}
\end{tikzpicture}
\end{document}


• Thanks a lot for your answers! I can not be more grateful for your help. And I'm wondering if your code requires the latest version of tikz package. Cause there are several commands that my tex does not recognize. – Gaoran Yu Jan 4 '15 at 4:03
• @GaoranYu Yes you need the last version of TikZ : 3.0.0. The solution that use markings, works almost under 2.10, but you have to comment \scoped (or replace it by scope environment). I think that it is a good think to switch to the last version of TikZ. – Kpym Jan 4 '15 at 10:48

One more TikZ solution for (4,6,12). This time using slanted grid decorated with regular polygone shapes.

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{shapes.geometric}
\tikzset{
polygon/.style 2 args = { draw, regular polygon, regular polygon sides=#1,
minimum size=#2*1cm, inner sep=0pt, outer sep=0pt
},
p12/.style= {draw=red, opacity=.2,
preaction={decorate, decoration={ markings, mark=between positions 0 and .999 step 1cm
with { \node[polygon={12}{1/(sin(15)+cos(15))}]{}; }}}
},
p4/.style= { draw=blue, opacity=.2,
preaction={decorate, decoration={ markings, mark=between positions .5cm and .999 step 1cm
with { \node[transform shape, polygon={4}{sqrt(2)*sin(15)/(1+tan(15))}]{}; }}}
}
}
\begin{document}
\begin{tikzpicture}
\draw[clip] (2,1) rectangle +(3,3);

\begin{scope}[yscale=sqrt(3)/2,xslant=.5]
% demonstrate p4 and p12 decorations
\scoped[red,ultra thick,opacity=.5] \path[p12] (2,2) -- ++(1,0);
\scoped[green,ultra thick,opacity=.5] \path[p4] (2,2) -- ++(1,0);

% decorate slanted grids
\draw[p4,p12,ystep=10] (0,0) grid +(5,5);
\draw[xslant=-1,p4] (2,0) grid +(5,5);
\end{scope}
\end{tikzpicture}
\end{document}


• I am sure now you are a mathematician ;-) – user4686 Jan 3 '15 at 10:54
• @jfbu Is that so obvious ... just because I put three solutions to one problem? ;) – Kpym Jan 3 '15 at 11:01
• @jfbu I do not put the most "mathematical" solution that use the Coxeter group of symmetries to generate the figure starting from 1 edge. The problem is that I can't (easily) generate only the reduced words, and it draws multiple times the same edge :( – Kpym Jan 3 '15 at 11:10
• what are generators and relations? – user4686 Jan 3 '15 at 11:14
• @jfbu for generator we can take the three symmetries (s_1,s_2,s_3, elements of order 2) relating the centers of the three regular polygons. And, as the composition of two of them is a rotation of pi/2,pi/3 or pi/6, we have that they are of order 4,6 and 12. So we have the relations {s_1^2, s_2^2, s_3^2, (s_1 s_2)^4, (s_2 s_3)^6, (s_2 s_3)^12}. But please, don't do this ! ;) – Kpym Jan 3 '15 at 11:52