如何用 tikz 绘制 Smith-Volterra-Cantor 集?

如何用 tikz 绘制 Smith-Volterra-Cantor 集?

如何绘制类似的 Smith-Volterra-Cantor 集(https://en.wikipedia.org/wiki/Smith-Volterra-Cantor_set)?它基本上是通过从单位间隔 开始,从4^{-n}级的每个间隔的中间移除而形成的。这是来自 wiki 的 Smith-Volterra-Cantor 集的图像:n[0,1]

enter image description here

我没有成功地制作出康托集代码的类似物(绘制康托集)。

答案1

(我在这个答案的底部添加了对 TikZ 矩形的翻译更新)

这里介绍一种使用的方法\rule。我使用图片环境主要是为了方便将方法转换为 TikZ 语言,只需将\put和转换\rule为其语言即可。

\documentclass[a4paper]{article}

\usepackage{picture}

\begin{document}

\setlength{\unitlength}{1sp}

\noindent
\begin{picture}(\linewidth,7\baselineskip)(0,-6\baselineskip)
\def\split #1#2\into#3#4{\def#3{#1}\def#4{#2}}%
\def\DrawL{%
    \edef\rulewidth{\the\numexpr\y*\totalwidth/\SUM}%
    \edef\Zdim{\the\numexpr\Zdim-\baselineskip}%
    \def\Y{0}\def\Ydim{0}\let\M\L
    \loop
      \put(\Ydim,\Zdim){\rule{\rulewidth sp}{.5\baselineskip}}%
    \unless\ifx\M\empty
      \expandafter\split\M\into\gap\M
      \edef\Y{\the\numexpr\Y+\y+\gap}%
      \edef\Ydim{\the\numexpr\Y*\totalwidth/\SUM}%
    \repeat
}%
\def\UpdateL{%
    \edef\x{\the\numexpr4*\x}%
    \edef\y{\the\numexpr2*\y-1}%
    \edef\SUM{\the\numexpr4*\SUM}%
    \edef\L{\L{\x}\L}%
}%
    \edef\totalwidth{\number\linewidth}%
    \def\Zdim{0}%
    \put(0,\Zdim){\rule{\totalwidth sp}{.5\baselineskip}}
    \def\L{{2}}\def\x{2}\def\y{3}\def\SUM{8}%
    \DrawL
    \UpdateL
    \DrawL
    \UpdateL
    \DrawL
    \UpdateL
    \DrawL
    \UpdateL
    \DrawL
    \UpdateL
    \DrawL
    %\UpdateL
\end{picture}
\end{document}

结果:

enter image description here

该宏\L保存了间隙长度。它仅使用整数,每次迭代时比例单位(默认)除以 4。此比例中的间隙长度均为偶数,实际规则的长度为奇数(2 的幂加 1)。关于其构造方式的解释,请参阅此评论


这是翻译成 TikZ 绘图指令,但保留了所有实际算法及其血腥的 TeX 宏......因此我猜这不算作 TikZ 解决方案!

我最初犯了一个错误,使用\filldraw了 ,而不是\fill,这会使矩形变厚一些,使得从 4 级或 5 级开始的间隙变得不可见……(无论如何,我们在理性的几何级数上很快达到了亚原子尺度1/4……)。感谢用户 @Kpym 的帮助。

\documentclass[a4paper]{article}

\usepackage{tikz}

\begin{document}

\noindent
\begin{tikzpicture}
\def\split #1#2\into#3#4{\def#3{#1}\def#4{#2}}%
\def\DrawL{%
    \edef\rulewidth{\the\numexpr\y*\totalwidth/\SUM}%
    \edef\Zdim{\the\numexpr\Zdim-\baselineskip}%
%
    \def\Y{0}\def\Ydim{0}\let\M\L
    \loop
% attention, \fill, not \filldraw !
    \fill[color=purple]
            (\Ydim sp,\Zdim sp) rectangle +(\rulewidth sp,0.5\baselineskip);
    \unless\ifx\M\empty
      \expandafter\split\M\into\gap\M
      \edef\Y{\the\numexpr\Y+\y+\gap}%
      \edef\Ydim{\the\numexpr\Y*\totalwidth/\SUM}%
    \repeat
}%
\def\UpdateL{%
    \edef\x{\the\numexpr4*\x}%
    \edef\y{\the\numexpr2*\y-1}%
    \edef\SUM{\the\numexpr4*\SUM}%
    \edef\L{\L{\x}\L}%
}%
    \edef\totalwidth{\number\linewidth}%
    \def\Zdim{0}%
%
    \fill[color=purple]
          (0,\Zdim) rectangle +(\totalwidth sp,.5\baselineskip);
%
    \def\L{{2}}\def\x{2}\def\y{3}\def\SUM{8}%
%
    \DrawL
    \UpdateL
    \DrawL
    \UpdateL
    \DrawL
    \UpdateL
    \DrawL
    \UpdateL
    \DrawL
    \UpdateL
    \DrawL
%    \UpdateL
\end{tikzpicture}
\end{document}

这是错误使用\filldrawwhere \fillonly must be used

enter image description here

结果如下\fill

enter image description here

与使用 LaTeX 相比\rule:(也是紫色)

enter image description here

答案2

以下是基于的答案lindenmayersystems。该答案的基础是这个较旧的

\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},
    },
    % the mid factor will be 1/4,1/16,...
    mid factor/.code={
      \pgfmathparse{#1}\global\let\midfactor\pgfmathresult
      \pgfmathsetmacro{\sidefactor}{(1-\midfactor)/2}
    }, mid factor = {1/4},
}
% define the cantor system
\pgfdeclarelindenmayersystem{Cantor}{
  \symbol{A}{\pgftransformscale{\sidefactor}}
  \symbol{B}{\pgftransformscale{(\midfactor)/(\sidefactor)}}
  \symbol{C}{\pgftransformscale{(\sidefactor)/(\midfactor)}}
  \symbol{D}{\pgftransformscale{1/(\sidefactor)}}
  \symbol{M}{\tikzset{mid factor=\midfactor/2/(1-\midfactor)}}
  \symbol{N}{\tikzset{mid factor=\midfactor/(.5+\midfactor)}}
  \rule{F -> MAF Bf CF DN}
}
\begin{document}
  \begin{tikzpicture}[xscale=10, line width=2mm, purple]
    \draw
      foreach \order in {0,...,4}{
        [yshift=-\order*3mm] l-system [cantor=\order]
      };
  \end{tikzpicture}
\end{document}

enter image description here

精度问题在最后一级结束时可见。当阶数超过 4 时,情况会变得更糟。

相关内容