好的,我继续在 Tikz 中构建分形 - 另一个在这里:Tikz 分形 - Cantor Dust。我希望有人能帮我创建另一个稍微复杂一点的分形。它被称为孟格海绵,本质上是“3D”(尽管将分形定义为这样有点矛盾)谢尔宾斯基地毯。它看起来像这样:
从单位立方体开始,然后递归地移除立方体中每个面的中心 9 分之一。这里有一个更好、更精确的描述:https://en.wikipedia.org/wiki/Menger_sponge。
我认为使用“lindenmayer 系统”应该可以实现,但我对该系统只有很少的经验,而且我从未将其用于 3D 形状。
使用 Nancy-N 的解决方案后,我得到了以下结果:
(注意每个小立方体周围的细线)。
答案1
我不知道这是否会让您高兴,但确实,一种 Lindenmayer 系统可以解决您的问题,利用这样一个事实:立方体由 20 个 3 倍大小的立方体副本组成,而这些副本本身又由 3 倍大小的立方体组成,依此类推。您可以采用以下方法;我让您进行必要的调整以获得更好的图像。
level0.tex
首先使用以下代码生成一个 .tex 文件不 \documentclass
左右,\begin{document}
其内容将是:
\fill[yellow] (1, 1, 1) -- (1, -1, 1) -- (-1, -1, 1) -- (-1, 1, 1) -- cycle;
\fill[cyan] (1, 1, 1) -- (1, 1, -1) -- (1, -1, -1) -- (1, -1, 1) -- cycle;
\fill[magenta] (1, 1, 1) -- (1, 1, -1) -- (-1, 1, -1) -- (-1, 1, 1) -- cycle;
现在你创建一个文件level1.tex
(同样,不是\documentclass
左右),在其中使用 20 次的内容,level0
就像你将几个小立方体放在一起一样。请注意,你必须按正确的顺序绘制立方体,这样隐藏另一个立方体的立方体才会被绘制后它。您的文件level1.tex
将如下所示:
\begin{scope}[scale=.3333333333]
\begin{scope}[shift={(-2, -2, -2)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(0, -2, -2)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(2, -2, -2)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(-2, 0, -2)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(2, 0, -2)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(-2, 2, -2)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(0, 2, -2)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(2, 2, -2)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(-2, -2, 0)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(2, -2, 0)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(-2, 2, 0)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(2, 2, 0)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(-2, -2, 2)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(0, -2, 2)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(2, -2, 2)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(-2, 0, 2)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(2, 0, 2)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(-2, 2, 2)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(0, 2, 2)}]
\input{level0}
\end{scope}
\begin{scope}[shift={(2, 2, 2)}]
\input{level0}
\end{scope}
\end{scope}
接下来,创建一个level2.tex
与 相同的文件level1.tex
,只是\input{level0}
被 替换\input{level1}
。最后,您的最终绘图(在 等真实.tex
源文件中\documentclass
)将是
\begin{tikzpicture}
\input{level2}
\end{tikzpicture}
下面是我得到的渲染。当然,至少理论上你可以达到 3、4 级左右,但不要忘记,每增加一个级别,计算量和内存使用量就会增加 20 倍!
诚挚的问候,/Nancy-N
编辑:Paul Gaborit 很好地改进了我的解决方案,他编写了一个\mengersponge
带有一个参数的命令,这样你就不必为每个级别创建一个文件了。这是他的代码(他还选择了更相关的颜色 ;-)):
\documentclass[tikz]{standalone}
\usepackage{luatex85}
\newcommand\mengersponge[1]{
\pgfmathsetmacro\level{int(#1 - 1)}
\ifnum \level = 0 \relax
\filldraw[gray!50!black,line width=0] (1, 1, 1) -- (1, 1, -1) -- (1, -1, -1) -- (1, -1, 1) -- cycle;
\filldraw[gray,line width=0] (1, 1, 1) -- (1, 1, -1) -- (-1, 1, -1) -- (-1, 1, 1) -- cycle;
\filldraw[gray!50,line width=0] (1, 1, 1) -- (1, -1, 1) -- (-1, -1, 1) -- (-1, 1, 1) -- cycle;
\else
\begin{scope}[scale=.3333333333]
\begin{scope}[shift={(-2, -2, -2)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(0, -2, -2)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(2, -2, -2)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(-2, 0, -2)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(2, 0, -2)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(-2, 2, -2)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(0, 2, -2)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(2, 2, -2)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(-2, -2, 0)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(2, -2, 0)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(-2, 2, 0)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(2, 2, 0)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(-2, -2, 2)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(0, -2, 2)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(2, -2, 2)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(-2, 0, 2)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(2, 0, 2)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(-2, 2, 2)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(0, 2, 2)}]
\mengersponge{\level}
\end{scope}
\begin{scope}[shift={(2, 2, 2)}]
\mengersponge{\level}
\end{scope}
\end{scope}
\fi
}
\begin{document}
\begin{tikzpicture}
\mengersponge{4}
\end{tikzpicture}
\end{document}
使用 时pdflatex
,Paul Gaborit 只能执行到第 3 级的计算(对应于\mengersponge{4}
他的代码中的),这需要 40 秒才能编译完成;但使用lualatex
他可以编译第 4 级(对应于\mengersponge{5}
)。以下是他的照片 :-)
对于 3 级:
对于 4 级:
问候,/Nancy-N