Visualising Recamán's sequence using TikZ
As I am quite ignorant in TikZ I can't add the colours etc...
first we generate the first 1000 sequence members,
second, we use some kind of expandable loop in the tikz picture. For this I loaded
xinttools
, but there are other choices.third I did three separate pictures but one can probably use in the same picture successive loops with new colors perhaps, or vary the color with index #1.
I did not abstract into a macro with the number of steps as argument, and I did not do the work to created animated gif, but this could give a start.
Also, I spend a bit time in TikZ manual looking for half-circles, but I got confused, so I stick with the arc
construct of OP, I don't know if efficient or not for TikZ matters.
\documentclass[tikz,margin=0.5cm]{standalone}
% FIRST WE GENERATE a(n) for n=0, ..., 1000
% https://oeis.org/A005132
\makeatletter
\@namedef{recaman0}{0}\@namedef{namacer0}{0}
\@namedef{recaman1}{1}\@namedef{namacer1}{1}
\@namedef{recaman2}{3}\@namedef{namacer3}{2}
\@namedef{recaman3}{6}\@namedef{namacer6}{3}
% \<namacerN> will give the *last* index n with a(n) = N
\count@ 3
\loop
\advance\count@ \@ne
\edef\zzz{\the\numexpr
\@nameuse{recaman\the\numexpr\count@-\@ne}-\count@}%
\@namedef{recagoleft\the\count@}{0}%
\ifnum\zzz>\z@
\ifcsname namacer\zzz\endcsname
\edef\zzz{\the\numexpr\zzz+\count@+\count@}%
\else
\@namedef{recagoleft\the\count@}{1}%
\fi
\else
\edef\zzz{\the\numexpr\zzz+\count@+\count@}%
\fi
\expandafter\edef\csname recaman\the\count@\endcsname{\zzz}%
\expandafter\edef\csname namacer\zzz\endcsname{\the\count@}%
\typeout{a(\the\count@) = \@nameuse{recaman\the\count@}}%
\ifnum\count@<1000
\repeat
\usepackage{xinttools}
\makeatletter
% I added the "recagoleft" in a second stage originally I was doing
% \ifnum test to check if increase or decrease for index 2*#1 and
% 2*#1+1
% (perhaps I should have kept more cumbersome \ifnum rather than
% creating these extra macros?)
\def\mymacro#1{%
arc
\if\@nameuse{recagoleft\the\numexpr2*#1}1%
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{(-180:0:-\the\numexpr2*#1\relax)}{(180:0:\the\numexpr2*#1\relax)}%
arc
\if\@nameuse{recagoleft\the\numexpr2*#1+1}1%
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{(180:0:-\the\numexpr2*#1+1\relax)}{(-180:0:\the\numexpr2*#1+1\relax)}%
}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw [line width=3mm]
(0,0) arc
(-180:0:1)
\xintApplyUnbraced{\mymacro}{\xintSeq{1}{10}};
\end{tikzpicture}
\begin{tikzpicture}
\draw [line width=3mm]
(0,0) arc
(-180:0:1)
\xintApplyUnbraced{\mymacro}{\xintSeq{1}{30}};
\end{tikzpicture}
\begin{tikzpicture}
\draw [line width=3mm]
(0,0) arc
(-180:0:1)
\xintApplyUnbraced{\mymacro}{\xintSeq{1}{50}};
\end{tikzpicture}
\end{document}
For generating the picture I had the problem that my usual gs invocation (with transparent background) proved very slow and produced very big png's... (13M for the third one). So I did it again with smaller resolution and here is the first one (for n=2*10=20, circa).
For the one up to n=2*50+1=101 I upload a screen capture
I realized only later that 50
(i.e. n=101) was maximal with 1cm
units before triggering "dimension too large error" from TikZ. But this works, where the unit is about 1.5pt
(2pt
would be too big).
\begin{tikzpicture}[x=100000sp,y=100000sp]
\draw [line width=3mm]
(0,0) arc
(-180:0:1)
\xintApplyUnbraced{\mymacro}{\xintSeq{1}{499}};% and not 500 as a(1001) not pre-computed
\end{tikzpicture}
I obtain this, which indicates the values of sequence up to n=999
: (sorry I initially uploaded a possibly wrong picture because I used 500, hence n=1001 but my pre-computations in preamble go only up to 1000; no error was triggered because only an \if
test is done about some control sequence, not a computation or an \ifnum
)
I am almost an expert in TikZ now: a \draw
statement can have only one colour. So I modified my approach to use some loop to accumulate multiple \draw
with a colour from an xcolor
color series.
I wanted to create an animated gif, for this reason I do a super-loop which increases the number of steps each time. My usual convert
invocation failed, using seemingly the size of the first pdf page. Then I modified the code to use the same picture size for all frames. This is why in the code below I added new macros holding \max(a(n), i=0..n)
.
But convert
again failed so I post only here a snapshot of the last frame.
But if you compile to pdf, your PDF viewer possibly with re-create the animation for you by holding down the space key (it works for me; I configured view to a single page i.e. not "continous pages").
\documentclass[tikz]{standalone}
%\usepackage{xcolor}
% FIRST WE GENERATE a(n) for n=0, ..., 1000
% https://oeis.org/A005132
\makeatletter
\@namedef{recaman0}{0}\@namedef{namacer0}{0}
\@namedef{recaman1}{1}\@namedef{namacer1}{1}\@namedef{recagoleft1}{0}
\@namedef{recaman2}{3}\@namedef{namacer3}{2}\@namedef{recagoleft2}{0}
\@namedef{recaman3}{6}\@namedef{namacer6}{3}\@namedef{recagoleft3}{0}
% \<namacerN> will give the *last* index n with a(n) = N
\@namedef{recaMax0}{0}
\@namedef{recaMax1}{1}
\@namedef{recaMax2}{3}
\@namedef{recaMax3}{6}
\count@ 3
\loop
\advance\count@ \@ne
\edef\zzz{\the\numexpr
\@nameuse{recaman\the\numexpr\count@-\@ne}-\count@}%
\@namedef{recagoleft\the\count@}{0}%
\expandafter\let\csname recaMax\the\count@\expandafter\endcsname
\csname recaMax\the\numexpr\count@-\@ne\endcsname
\ifnum\zzz>\z@
\ifcsname namacer\zzz\endcsname
\edef\zzz{\the\numexpr\zzz+\count@+\count@}%
\ifnum\zzz>\@nameuse{recaMax\the\count@}
\expandafter\let\csname recaMax\the\count@\endcsname\zzz
\fi
\else
\@namedef{recagoleft\the\count@}{1}%
\fi
\else
\edef\zzz{\the\numexpr\zzz+\count@+\count@}%
\ifnum\zzz>\@nameuse{recaMax\the\count@}
\expandafter\let\csname recaMax\the\count@\endcsname\zzz
\fi
\fi
\expandafter\let\csname recaman\the\count@\endcsname\zzz
\expandafter\edef\csname namacer\zzz\endcsname{\the\count@}%
\typeout{a(\the\count@) = \@nameuse{recaman\the\count@}
(max so far=\@nameuse{recaMax\the\count@})}%
\ifnum\count@<1000
\repeat
\usepackage{xinttools}
\makeatletter
\def\mymacro#1{%
\draw
[color={foo!!+}]
% radius being n, width of circle 2n, end-point is at 2*a(n)
(2*\@nameuse{recaman\the\numexpr#1-1},0)
arc
\if\@nameuse{recagoleft#1}1%
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{(\unless\ifodd#1 -\fi180:0:-#1)}{(\ifodd#1 -\fi180:0:#1)};%
}
\makeatother
\makeatletter
\def\drawframe#1{\noexpand
\draw
(0,0)--(0,-#1)--(\the\numexpr2*\@nameuse{recaMax#1},-#1)
--(\the\numexpr2*\@nameuse{recaMax#1},#1)--(0,#1)--cycle;}%
\makeatother
\definecolorseries{foo}{rgb}{last}{blue}{red}
\begin{document}
\xintFor* #1 in {\xintSeq{1}{100}}\do{%
\begin{tikzpicture}[x=5mm, y=5mm]
\edef\zzz{\drawframe{100}}\zzz% get all pictures to be of same size
\resetcolorseries[#1]{foo}%
\xintApplyUnbraced{\mymacro}{\xintSeq{1}{#1}}
\end{tikzpicture}
}
\end{document}
Here is thus page 100 of the produced PDF:
I finally manage to get an animated gif:
Recipe:
- 65 frames,
[x=1mm, y=1mm]
,- each draw with
line width=.5mm
, - pdflatex
convert -density 72 recaman-colors.pdf _tmp%02d.png
convert -verbose -dispose previous -loop 0 -density 100 -delay 15 _tmp0{0..9}.png _tmp{10..63}.png -delay 300 _tmp64.png recaman.gif
Output not as smooth as one could hope, but 360383 (was for 50 frames) 745256 bytes.
I'm sorry, really thought these should be spirals. Should have checked. Sorry! With insert path you can, of course, insert whatever you like, also a series of arcs. I have not much time now, unfortunately ...
\documentclass[tikz,border=3.14mm]{standalone}
\tikzset{Recaman/.style n args={3}{insert path={
foreach \X in {#1,...,#2}
{arc (-180:0:{#3*(2*\X-1)/2}) arc (0:180:#3*2*\X/2) }
}}}
\begin{document}
\begin{tikzpicture}
\expandafter\draw[rounded corners] (0,1) to[out=0,in=90] (3,0)
[Recaman={2}{6}{0.3}] arc(-180:0:2) to[out=90,in=90] ++(3,1)
[Recaman={2}{7}{0.2}];
\end{tikzpicture}
\end{document}