我正在尝试使用 lindenmayersystems 包来绘制类似于康托集的以下模式:x、xox、xoxoooxox、...
我定义了以下系统:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{lindenmayersystems}
\begin{document}
\begin{figure}
\centering
\pgfdeclarelindenmayersystem{cantor}{
\symbol{X}{\pgflsystemdrawforward}
\symbol{Y}{\pgflsystemmoveforward}
\rule{X -> XYX}
\rule{Y -> YYY}
}%
\begin{tikzpicture}
\draw lindenmayer system [lindenmayer system={cantor, axiom=X, order=3}];
\end{tikzpicture}
\end{figure}
\end{document}
我希望 x 呈现为实心圆,而 o 呈现为空心圆。不幸的是,我找不到与此非常相似的例子。如能得到任何帮助,我将不胜感激。
也许使用 linden mayer 系统在这里不是最好的主意,而递归解决方案才是最好的。
答案1
我原来的解决方案(如下)很复杂,因为我觉得有必要重新创建 OP 的早期评论,在顺序 1 时,系统生成“X”。在顺序 2 时,系统生成“XYX”,在顺序 3 时,系统生成“XYXYYYXYX”。
然而,当后来讨论这些结果可以视为顺序 0、1 和 2(而不是 1、2 和 3)时,一切都变得简单多了。它只是相当于让宏\symbol
通过命令放置所需的图标\node
,然后通过命令\pgflsystemmoveforward
前进到下一个位置。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{lindenmayersystems}
\begin{document}
\begin{figure}
\centering
\pgfdeclarelindenmayersystem{cantor}{
\symbol{X}{\node{$\bullet$};\pgflsystemmoveforward}
\symbol{Y}{\node{$\circ$};\pgflsystemmoveforward}
\rule{X -> XYX}
\rule{Y -> YYY}
}%
\begin{tikzpicture}
\draw lindenmayer system [lindenmayer system=
{cantor, axiom=X, order=0}];
\end{tikzpicture}
\begin{tikzpicture}
\draw lindenmayer system [lindenmayer system=
{cantor, axiom=X, order=1}];
\end{tikzpicture}
\begin{tikzpicture}
\draw lindenmayer system [lindenmayer system=
{cantor, axiom=X, order=2}];
\end{tikzpicture}
\end{figure}
\end{document}
原始答案(顺序 1、2 和 3)
我不能说我知道我在这里做什么。但我注意到,如果我只使用简单的规则而不使用计数器,符号的重复次数就会比预期的要多。所以我尝试了一下。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{lindenmayersystems}
\newcounter{myindex}
\begin{document}
\begin{figure}
\centering
\pgfdeclarelindenmayersystem{cantor}{
\symbol{X}{\ifnum\themyindex<2\stepcounter{myindex}\else
\pgflsystemmoveforward\node{$\bullet$};\setcounter{myindex}{0}\fi}
\symbol{Y}{\ifnum\themyindex<2\stepcounter{myindex}\else
\pgflsystemmoveforward\node{$\circ$};\setcounter{myindex}{0}\fi}
\rule{X -> XYX}
\rule{Y -> YYY}
}%
\begin{tikzpicture}
\draw lindenmayer system [lindenmayer system={cantor, axiom=X, order=1}];
\end{tikzpicture}
\begin{tikzpicture}
\draw lindenmayer system [lindenmayer system={cantor, axiom=X, order=2}];
\end{tikzpicture}
\begin{tikzpicture}
\draw lindenmayer system [lindenmayer system={cantor, axiom=X, order=3}];
\end{tikzpicture}
\end{figure}
\end{document}
答案2
在 OpTeX 中,我们可以使用\replstring
:
\def\tmpb{\X}
\def\nextlevel{\replstring\tmpb{\Y}{\Y\Y\Y}\replstring\tmpb{\X}{\X\Y\X}}
\let\X=\bullet \let\Y=\circ
\def\printstring{\centerline{$\tmpb$}}
\printstring
\nextlevel\printstring
\nextlevel\printstring
\nextlevel\printstring
\bye
请注意,我们不需要 TikZ,只需要使用非常简单的宏。
答案3
当然,使用这个lindenmayersystems
库很有吸引力。然而,规则很容易直接实现。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\cantor}{m}
{% #1 = number of iterations
\misogrumpy_cantor:n { #1 }
}
% choose the symbols for X and Y
\tl_const:Nn \c_misogrumpy_cantor_x_tl { \,\textbullet\, }
\tl_const:Nn \c_misogrumpy_cantor_y_tl { \,\ensuremath{\circ}\, }
% variables
\seq_new:N \l__misogrumpy_cantor_levels_seq % for the final printing
\tl_new:N \l__misogrumpy_cantor_level_tl % current level
\tl_new:N \l__misogrumpy_cantor_temp_tl % for substituting
\cs_new_protected:Nn \misogrumpy_cantor:n
{
\tl_set:Nn \l__misogrumpy_cantor_level_tl { X } % initialize
\seq_clear:N \l__misogrumpy_cantor_levels_seq
\prg_replicate:nn { #1+1 } { \__misogrumpy_cantor_next: }
\__misogrumpy_cantor_print:
}
\cs_new_protected:Nn \__misogrumpy_cantor_next:
{
% store the previous level
\tl_set_eq:NN \l__misogrumpy_cantor_temp_tl \l__misogrumpy_cantor_level_tl
\tl_replace_all:Nnn \l__misogrumpy_cantor_temp_tl { X } { \c_misogrumpy_cantor_x_tl }
\tl_replace_all:Nnn \l__misogrumpy_cantor_temp_tl { Y } { \c_misogrumpy_cantor_y_tl }
\tl_put_left:Nn \l__misogrumpy_cantor_temp_tl { \! }
\tl_put_right:Nn \l__misogrumpy_cantor_temp_tl { \! }
\seq_put_right:NV \l__misogrumpy_cantor_levels_seq \l__misogrumpy_cantor_temp_tl
% compute the next level
\tl_replace_all:Nnn \l__misogrumpy_cantor_level_tl { Y } { YYY }
\tl_replace_all:Nnn \l__misogrumpy_cantor_level_tl { X } { XYX }
}
\cs_new_protected:Nn \__misogrumpy_cantor_print:
{
\begin{tabular}{@{}c@{}}
\seq_use:Nn \l__misogrumpy_cantor_levels_seq { \\[-1ex] }
\end{tabular}
}
\ExplSyntaxOff
\begin{document}
\section{Zero}
\cantor{0}
\section{One}
\cantor{1}
\section{Two}
\cantor{2}
\section{Three}
\cantor{3}
\end{document}