使用 lindenmeyer 系统,有一个很好的方法可以使用以下代码来创建均匀康托集。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{lindenmayersystems}
\pgfdeclarelindenmayersystem{cantor set}{
\rule{F -> FfF}
\rule{f -> fff}
}
\begin{document}
\begin{tikzpicture}
\foreach \order in {0,...,4}
\draw[yshift=-\order*10pt] l-system[l-system={cantor set, axiom=F, order=\order, step=100pt/(3^\order)}];
\end{tikzpicture}
\end{document}
这是通常的 1/3、1/3 康托集。我可以轻松修改它以制作 1/5、1/5、1/5 康托集等。但我想制作一个非均匀康托集,如 1/4、1/2。并且修改这个不起作用:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{lindenmayersystems}
\pgfdeclarelindenmayersystem{cantor set}{
\rule{F -> FfFF}
\rule{f -> ffff}
}
\begin{document}
\begin{tikzpicture}
\foreach \order in {0,...,4}
\draw[yshift=-\order*10pt] l-system[l-system={cantor set, axiom=F, order=\order, step=100pt/(4^\order)}];
\end{tikzpicture}
\end{document}
第一步是正确的,但此后分形不再自相似。有人知道我遗漏了什么吗?
答案1
问题在于,您的规则在间隙F -> FfFF
后有两个 F。f
这会产生预期的结果,即一条线的长度是正常 F 线的两倍,但副作用是它也被扩展了两倍(按照同一规则),在右侧段产生了两个“间隙”,而不是一个。
您需要某种方式来表达规则F -> FfG
,即 F 是绘制的线段,fa 是未绘制的(移动)线段,G 是长度不同于 F 长度的新线段。但随后您必须编写一条规则,说明如何为下一步扩展 G,而我们需要某种方式来表达“让 G 成为下一次扩展的 F”,但这无法用 Lyndenmayer 语法来表达。
因此,在我看来,非均匀康托集无法用 Lyndenmayer 语法来表达。至少我尝试了一个小时却没有成功,还是没能做到。例如:
\documentclass[margin=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{lindenmayersystems}
\pgfdeclarelindenmayersystem{cantor set}{
\symbol{G}{\pgflsystemdrawforward\pgflsystemdrawforward}
\rule{F -> FfG}
\rule{f -> ffff}
\rule{G -> FfG} % Doesn't work
}
\begin{document}
\begin{tikzpicture}
\foreach \order in {0,...,4}
\draw[yshift=-\order*10pt] l-system[l-system={cantor set, axiom=F, order=\order, step=100pt/(4^\order)}];
\end{tikzpicture}
\end{document}
这里我定义了一个符号G
来画一条两倍于 F 长度的线。这对于第一次扩展和“左分支”的扩展都有效,但后来我没能找到一条规则来表达“右分支”应该如何扩展(即:G 的扩展规则)。结果如下:
答案2
均匀和非均匀康托集的组合是相同的。所以我们唯一需要跟踪的是比例因子。因此,F -> F f F
我们可以使用代替标准,F -> AF Bf CF D
其中A
,B
,C
然后D
设置适当的比例因子。
和left factor
应right factor
适当设置。
\documentclass[tikz,border=7pt]{standalone}
\usetikzlibrary{lindenmayersystems,decorations.pathreplacing,calc}
\tikzset{
% starting options for the Cantor systems
cantor/.style = {
l-system={Cantor, axiom=F, order=#1, step=1cm},
},
% define the Cantor factors, the uniform case is 1/3,1/3,1/3
left factor/.store in=\leftfactor, left factor = {1/3},
right factor/.store in=\rightfactor, right factor = {1/3},
% calculate the middle factor
cantor/.append code={\pgfmathsetmacro{\midfactor}{1-\leftfactor-\rightfactor}}
}
% define the cantor system
\pgfdeclarelindenmayersystem{Cantor}{
\symbol{A}{\pgftransformscale{\leftfactor}}
\symbol{B}{\pgftransformscale{(\midfactor)/(\leftfactor)}}
\symbol{C}{\pgftransformscale{(\rightfactor)/(\midfactor)}}
\symbol{D}{\pgftransformscale{1/(\rightfactor)}}
\rule{F -> AF Bf CF D}
}
\begin{document}
\begin{tikzpicture}[xscale=10, line width=1mm, purple]
\draw[left factor=1/4,right factor=2/3]
foreach \order in {0,...,4}{
[yshift=\order*2mm] l-system [cantor=\order]
};
\end{tikzpicture}
\end{document}
但:从 5 阶开始就存在精度问题 :( 这是 7 个级别的图像。
另外,但是,考虑到1/4,1/4,1/2
因素,最多可以达到 7 阶;)