# Tikz: Lebesgue curve / Z curve

I tried to draw a Z curve (Lebesgue curve) by using this example for Hilbert curves. But I don't see why it does not work.

\documentclass[12pt]{article}

\usepackage{tikz}
\usepackage{ifthen}

\usepackage[position=top,labelformat=empty]{subfig}
\usepackage{verbatim}

\newdimen\HilbertLastX
\newdimen\HilbertLastY
\newcounter{HilbertOrder}

\def\DrawToNext#1#2{%
\pgfpathlineto{\pgfqpoint{\HilbertLastX}{\HilbertLastY}}
}

% \Hilbert[right_x,right_y,left_x,left_x,up_x,up_y,down_x,down_y]
\def\Hilbert[#1,#2,#3,#4,#5,#6,#7,#8] {
\ifnum\value{HilbertOrder} > 0%
\Hilbert[#5,#6,#7,#8,#1,#2,#3,#4]
\Hilbert[#1,#2,#3,#4,#5,#6,#7,#8]
\DrawToNext {#1} {#5}
\Hilbert[#1,#2,#3,#4,#5,#6,#7,#8]
\DrawToNext {#3} {#3}
\Hilbert[#7,#8,#5,#6,#3,#4,#1,#2]
\DrawToNext {#1} {#5}
\fi
}

\def\hilbert((#1,#2),#3){%
\pgfpathmoveto{\pgfqpoint{\HilbertLastX}{\HilbertLastY}}
\setcounter{HilbertOrder}{#3}
\Hilbert[1mm,0mm,-1mm,0mm,0mm,1mm,0mm,-1mm]
\pgfusepath{stroke}%
}

\begin{document}
\begin{figure}%
\centering
\subfloat[$n=1$]{\tikz[scale=18] \hilbert((0mm,0mm),1);}~~
\subfloat[$n=2$]{\tikz[scale=6] \hilbert((0mm,0mm),2);}~~
\subfloat[$n=3$]{\tikz[scale=2.6] \hilbert((0mm,0mm),3);}~~
\subfloat[$n=4$]{\tikz[scale=1.2] \hilbert((0mm,0mm),4);}~~
\subfloat[$n=5$]{\tikz[scale=0.58] \hilbert((0mm,0mm),5);}%
\end{figure}%

\end{document}


I get this result which is obviously wrong:

Any suggestions how to make it work? Thank you!

Here's a way using the lindenmayersystems library. Orders above 8 will take ages:

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{lindenmayersystems}
\pgfdeclarelindenmayersystem{z-curve}{
\symbol{I}{\pgftransformscale{+0.25\pgflsystemstep}}
\symbol{p}{%
\pgfpathmoveto{\pgfqpoint{1pt}{3pt}}\pgfpathlineto{\pgfqpoint{3pt}{3pt}}%
\pgfpathlineto{\pgfqpoint{1pt}{1pt}}\pgfpathlineto{\pgfqpoint{3pt}{1pt}}%
}
\symbol{q}{%
\pgfpathlineto{\pgfqpoint{1pt}{3pt}}\pgfpathlineto{\pgfqpoint{3pt}{3pt}}%
\pgfpathlineto{\pgfqpoint{1pt}{1pt}}\pgfpathlineto{\pgfqpoint{3pt}{1pt}}%
}
\symbol{S}{\pgftransformscale{+0.5pt}}
\symbol{A}{\pgftransformshift{\pgfqpoint{0pt}{4pt}}}
\symbol{B}{\pgftransformshift{\pgfqpoint{4pt}{4pt}}}
\symbol{C}{\pgftransformshift{\pgfqpoint{4pt}{0pt}}}
\symbol{[}{\bgroup}
\symbol{]}{\egroup}
\rule{Z -> Ip}
\rule{p -> S[Ap][Bq][q][Cq]}
\rule{q -> S[Aq][Bq][q][Cq]}
}
\begin{document}
\foreach \i in {1,...,9}{
\begin{tikzpicture}[line join=round]
\draw [draw=red] (0,0) rectangle (5,5) (2.5, 5) node [above] {order: \i};
\draw [l-system={z-curve, step=5cm, axiom=Z, order=\i}] l-system;
\end{tikzpicture}}
\end{document}


• How can I place the first four orders horizontal side by side? In addition I get an error if I try it using \documentclass[a4paper,11pt]{article}. But why? – recipe_for_disaster Jan 8 '17 at 19:07
• @Samuel the error is due to the fact that the tikz package was automatically included by the standalone class due to the tikz option. If the document class is changed then \usepackage{tikz} needs to be added to the preamble. To reposition the z-curve use the shift key as the first argument to the \draw command e.g., \draw [shift={(5,0)}, l-system={... – Mark Wibrow Jan 10 '17 at 8:43
• I would like to use your approach also for Hilbert Curves. Since I do not really understand how your code works I would like to know how it works and how I can modify it in order to get Hilbert curves. That would be great! – recipe_for_disaster Jan 11 '17 at 11:29
• This may be very impressive, but all I see is a solid black square with order: 9 above it. Is this supposed to illustrate something or is it a problem with my browser? Images sometimes disappear, but I've never known one turn into a black hole before! – cfr Jan 12 '17 at 0:18
• @Manuel This time, I saw the animation. When I wrote that comment, I'd only seen the last frame. I didn't know that there were 8 before it. So, as far as I saw, there was just a black square which did not seem very useful as an illustration of anything. – cfr Jan 12 '17 at 0:55

No Lindenmayer system, only recursive.

Compile here: http://asymptote.ualberta.ca/

path Zordercurve(pair A, pair B, int ite=1){
path[] g;
if (ite == 1){
g.push((xpart(A+(B-A)/4),ypart(A+3*(B-A)/4))--(A+3*(B-A)/4)--
(A+(B-A)/4)--(xpart(A+3*(B-A)/4),ypart(A+(B-A)/4)));
}
else {
g.push(Zordercurve((A.x,ypart((A+B)/2)),(xpart((A+B)/2),B.y),ite-1));
g.push(Zordercurve((A+B)/2,B,ite-1));
g.push(Zordercurve(A,(A+B)/2,ite-1));
g.push(Zordercurve((xpart((A+B)/2),A.y),(B.x,ypart((A+B)/2)),ite-1));
}
return operator --(... g);
}
unitsize(1cm);
size(300);
draw(box((0,0),(4,4)));
draw(Zordercurve((0,0),(4,4),4),linewidth(0.5bp));
label(Label("order: "+(string) 4,LeftSide),(0,4)--(4,4));
shipout(bbox(2mm,invisible));


Animation:

path Zordercurve(pair A, pair B, int ite=1){
path[] g;
if (ite == 1){
g.push((xpart(A+(B-A)/4),ypart(A+3*(B-A)/4))--(A+3*(B-A)/4)--
(A+(B-A)/4)--(xpart(A+3*(B-A)/4),ypart(A+(B-A)/4)));
}
else {
g.push(Zordercurve((A.x,ypart((A+B)/2)),(xpart((A+B)/2),B.y), ite-1));
g.push(Zordercurve((A+B)/2,B, ite-1));
g.push(Zordercurve(A,(A+B)/2, ite-1));
g.push(Zordercurve((xpart((A+B)/2),A.y),(B.x,ypart((A+B)/2)), ite-1));
}
return operator --(... g);
}
import animate;
settings.tex="pdflatex";
settings.outformat="pdf";
animation Ani;
unitsize(1cm);
size(300);
draw(box((0,0),(4,4)));
for (int i=1; i <= 9 ; ++i){
save();
draw(Zordercurve((0,0),(4,4),i),linewidth(0.3bp));
label(Label("order: "+(string) i,LeftSide),(0,4)--(4,4));
restore();
}
erase();
Ani.movie(BBox(2mm,invisible));


path Zordercurve(pair A, pair B, int ite=1){
path[] g;
if (ite == 1){
g.push((xpart(A+(B-A)/4),ypart(A+3*(B-A)/4))--(A+3*(B-A)/4)--
(A+(B-A)/4)--(xpart(A+3*(B-A)/4),ypart(A+(B-A)/4)));
}
else {
g.push(Zordercurve((A.x,ypart((A+B)/2)),(xpart((A+B)/2),B.y), ite-1));
g.push(Zordercurve((A+B)/2,B, ite-1));
g.push(Zordercurve(A,(A+B)/2, ite-1));
g.push(Zordercurve((xpart((A+B)/2),A.y),(B.x,ypart((A+B)/2)), ite-1));
}
return operator --(... g);
}
pair[] Lebesguecurve(pair A, pair B, int ite=1){
path G=Zordercurve(A,B,ite);
pair C[];
for (int i=0; i <= length(G); ++i){ C.push(point(G,i)); }
return C;
}

import animate;
settings.tex="pdflatex";
settings.outformat="pdf";
animation Ani;
unitsize(1cm);
size(300);
pair[] M=Lebesguecurve((0,0),(4,4),4);
guide d;
for (int i=0; i < M.length ; ++i){
save();
d=d--M[i];
draw((i != 0) ? d : nullpath );
draw(box((0,0),(4,4)));
label(Label("order: "+(string) 4,LeftSide),(0,4)--(4,4));