我正在尝试使用半圆来可视化 Recamán 序列。这是我尝试复制的示例:
通过手动定义每个半圆,我目前得到了以下结果:
\documentclass[tikz,margin=0.5cm]{standalone}
\begin{document}
\begin{tikzpicture}
\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);
\end{tikzpicture}
\end{document}
有没有办法对其进行编码,以便它能够自动生成该序列的 N 次迭代?
从基本术语上讲,步骤的大小会依次增加,但如果可以的话,您可以减去(即,如果您得出一个以前未使用过的数字),否则您可以添加。
作为参考,这个序列在“整数序列在线百科全书”中是 A005132 -https://oeis.org/A005132
答案1
由于我对 TikZ 不太了解,所以我无法添加颜色等等......
首先我们生成前 1000 个序列成员,
其次,我们在 tikz 图片中使用某种可扩展的循环。为此,我加载了
xinttools
,但还有其他选择。第三,我制作了三张单独的图片,但也许可以在同一张图片中使用带有新颜色的连续循环,或者使用索引#1 改变颜色。
我没有将步骤数抽象为一个宏作为参数,也没有做创建动画 gif 的工作,但这可以提供一个开始。
另外,我花了一些时间在 TikZ 手册中寻找半圆,但我感到困惑,所以我坚持使用arc
OP 的构造,我不知道 TikZ 是否有效。
\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}
为了生成图片,我遇到了一个问题,我通常的 gs 调用(具有透明背景)非常慢,并且生成了非常大的 png...(第三个是 13M)。所以我用较小的分辨率再次执行了该操作,这是第一个(n=2*10=20,大约)。
对于 n=2*50+1=101 为止的那个,我上传了一个屏幕截图
我后来才意识到,在触发 TikZ 的“尺寸过大错误”之前50
,(即 n=101)是1cm
单位的最大值。但这是可行的,其中单位约为1.5pt
(2pt
会太大)。
\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}
我得到了这个,它表示序列的值最多为n=999
:(抱歉,我最初上传了一张可能错误的图片,因为我使用了 500,因此 n=1001,但我在序言中的预计算只到 1000;没有触发错误,因为只\if
对某些控制序列进行了测试,而不是计算或\ifnum
)
我现在几乎是 TikZ 专家了:一个\draw
语句只能有一种颜色。所以我修改了我的方法,使用一些循环来累积多个\draw
来自颜色系列的颜色xcolor
。
我想创建一个动画 gif,为此我做了一个超级循环,每次都会增加步骤数。我通常的convert
调用失败了,似乎使用了第一个 pdf 页的大小。然后我修改了代码,让所有帧都使用相同的图片大小。这就是为什么在下面的代码中我添加了新的宏来保存\max(a(n), i=0..n)
。
但convert
再次失败了,所以我只在这里发布最后一帧的快照。
但是如果您编译为 pdf,您的 PDF 查看器可能会通过按住空格键为您重新创建动画(它对我有用;我将视图配置为单个页面,即而不是“连续页面”)。
\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}
以下是生成的 PDF 的第 100 页:
我终于得到了一个动画 gif:
- 65帧,
[x=1mm, y=1mm]
,- 每次绘制
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
输出不像人们希望的那样流畅,但有360383 (50 帧) 745256 字节。
答案2
对不起,我真的以为这些应该是螺旋线。应该检查一下。对不起!当然,使用插入路径,您可以插入任何您喜欢的东西,也可以插入一系列圆弧。不幸的是,我现在没有太多时间......
\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}