Visualising Recamán's sequence using TikZ
Visualising Recamán's sequence using TikZ
I am trying to visualise Recamán's sequence using semicircles. This is an example of what I'm trying to replicate:
By manually defining each semicircle, I've got this so far:
documentclass[tikz,margin=0.5cm]standalone
begindocument
begintikzpicture
draw [line width=3mm] (0,0) arc (-180:0:1/2) arc (180:0:2/2) arc (-180:0:3/2) arc (-180:0:-4/2) arc (-180:0:5/2) arc (180:0:6/2) arc (-180:0:7/2) arc (-180:0:-8/2) arc (-180:0:9/2) arc (-180:0:-10/2);
endtikzpicture
enddocument
Is there a way to code this so it will automatically generate N iterations of the sequence?
In basic terms, the size of the steps increases sequentially, but you subtract if you can (i.e. if you arrive at a number that hasn't been used before), otherwise you add.
For reference, this sequence is A005132 on 'The On-Line Encyclopedia of Integer Sequences' - https://oeis.org/A005132
On pag. 640 of the pgf manual there is the Fibonacci sequence.
– vi pa
Aug 25 at 14:29
2 Answers
2
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.
xinttools
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.
arc
documentclass[tikz,margin=0.5cm]standalone
% FIRST WE GENERATE a(n) for n=0, ..., 1000
% https://oeis.org/A005132
makeatletter
@namedefrecaman00@namedefnamacer00
@namedefrecaman11@namedefnamacer11
@namedefrecaman23@namedefnamacer32
@namedefrecaman36@namedefnamacer63
% <namacerN> will give the *last* index n with a(n) = N
count@ 3
loop
advancecount@ @ne
edefzzzthenumexpr
@nameuserecamanthenumexprcount@-@ne-count@%
@namedefrecagoleftthecount@0%
ifnumzzz>z@
ifcsname namacerzzzendcsname
edefzzzthenumexprzzz+count@+count@%
else
@namedefrecagoleftthecount@1%
fi
else
edefzzzthenumexprzzz+count@+count@%
fi
expandafteredefcsname recamanthecount@endcsnamezzz%
expandafteredefcsname namacerzzzendcsnamethecount@%
typeouta(thecount@) = @nameuserecamanthecount@%
ifnumcount@<1000
repeat
usepackagexinttools
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?)
defmymacro#1%
arc
if@nameuserecagoleftthenumexpr2*#11%
expandafter@firstoftwoelseexpandafter@secondoftwofi
(-180:0:-thenumexpr2*#1relax)(180:0:thenumexpr2*#1relax)%
arc
if@nameuserecagoleftthenumexpr2*#1+11%
expandafter@firstoftwoelseexpandafter@secondoftwofi
(180:0:-thenumexpr2*#1+1relax)(-180:0:thenumexpr2*#1+1relax)%
makeatother
begindocument
begintikzpicture
draw [line width=3mm]
(0,0) arc
(-180:0:1)
xintApplyUnbracedmymacroxintSeq110;
endtikzpicture
begintikzpicture
draw [line width=3mm]
(0,0) arc
(-180:0:1)
xintApplyUnbracedmymacroxintSeq130;
endtikzpicture
begintikzpicture
draw [line width=3mm]
(0,0) arc
(-180:0:1)
xintApplyUnbracedmymacroxintSeq150;
endtikzpicture
enddocument
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).
50
1cm
1.5pt
2pt
begintikzpicture[x=100000sp,y=100000sp]
draw [line width=3mm]
(0,0) arc
(-180:0:1)
xintApplyUnbracedmymacroxintSeq1499;% and not 500 as a(1001) not pre-computed
endtikzpicture
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
)
n=999
if
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.
draw
draw
xcolor
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)
.
convert
max(a(n), i=0..n)
But convert
again failed so I post only here a snapshot of the last frame.
convert
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
%usepackagexcolor
% FIRST WE GENERATE a(n) for n=0, ..., 1000
% https://oeis.org/A005132
makeatletter
@namedefrecaman00@namedefnamacer00
@namedefrecaman11@namedefnamacer11@namedefrecagoleft10
@namedefrecaman23@namedefnamacer32@namedefrecagoleft20
@namedefrecaman36@namedefnamacer63@namedefrecagoleft30
% <namacerN> will give the *last* index n with a(n) = N
@namedefrecaMax00
@namedefrecaMax11
@namedefrecaMax23
@namedefrecaMax36
count@ 3
loop
advancecount@ @ne
edefzzzthenumexpr
@nameuserecamanthenumexprcount@-@ne-count@%
@namedefrecagoleftthecount@0%
expandafterletcsname recaMaxthecount@expandafterendcsname
csname recaMaxthenumexprcount@-@neendcsname
ifnumzzz>z@
ifcsname namacerzzzendcsname
edefzzzthenumexprzzz+count@+count@%
ifnumzzz>@nameuserecaMaxthecount@
expandafterletcsname recaMaxthecount@endcsnamezzz
fi
else
@namedefrecagoleftthecount@1%
fi
else
edefzzzthenumexprzzz+count@+count@%
ifnumzzz>@nameuserecaMaxthecount@
expandafterletcsname recaMaxthecount@endcsnamezzz
fi
fi
expandafterletcsname recamanthecount@endcsnamezzz
expandafteredefcsname namacerzzzendcsnamethecount@%
typeouta(thecount@) = @nameuserecamanthecount@
(max so far=@nameuserecaMaxthecount@)%
ifnumcount@<1000
repeat
usepackagexinttools
makeatletter
defmymacro#1%
draw
[color=foo!!+]
% radius being n, width of circle 2n, end-point is at 2*a(n)
(2*@nameuserecamanthenumexpr#1-1,0)
arc
if@nameuserecagoleft#11%
expandafter@firstoftwoelseexpandafter@secondoftwofi
(unlessifodd#1 -fi180:0:-#1)(ifodd#1 -fi180:0:#1);%
makeatother
makeatletter
defdrawframe#1noexpand
draw
(0,0)--(0,-#1)--(thenumexpr2*@nameuserecaMax#1,-#1)
--(thenumexpr2*@nameuserecaMax#1,#1)--(0,#1)--cycle;%
makeatother
definecolorseriesfoorgblastbluered
begindocument
xintFor* #1 in xintSeq1100do%
begintikzpicture[x=5mm, y=5mm]
edefzzzdrawframe100zzz% get all pictures to be of same size
resetcolorseries[#1]foo%
xintApplyUnbracedmymacroxintSeq1#1
endtikzpicture
enddocument
Here is thus page 100 of the produced PDF:
I finally manage to get an animated gif:
Recipe:
[x=1mm, y=1mm]
line width=.5mm
convert -density 72 recaman-colors.pdf _tmp%02d.png
convert -verbose -dispose previous -loop 0 -density 100 -delay 15 _tmp00..9.png _tmp10..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
tikzsetRecaman/.style n args=3insert path=
foreach X in #1,...,#2
arc (-180:0:#3*(2*X-1)/2) arc (0:180:#3*2*X/2)
begindocument
begintikzpicture
expandafterdraw[rounded corners] (0,1) to[out=0,in=90] (3,0)
[Recaman=260.3] arc(-180:0:2) to[out=90,in=90] ++(3,1)
[Recaman=270.2];
endtikzpicture
enddocument
Thanks, I thought they were spirals as well at first, but actually they are semicircles in the visualisation I'm looking to replicate. See for example, this Numberphile video on YouTube - youtube.com/watch?time_continue=135&v=FGC5TdIiT9U
– Milo
Aug 25 at 11:41
Added some more info to my question post to describe how the sequence is formed.
– Milo
Aug 25 at 11:55
@Milo I should have definitely checked before making such a statement. Sorry!
– marmot
Aug 25 at 15:34
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
At pag.21 of the animate manual there is a 3D example with a Lorenz's fly.
– vi pa
Aug 25 at 13:48