如何绘制像这样的分层矩阵图案(是否使用 TikZ)?以及如何在两个矩形矩阵的乘积之间添加一个小的方阵?
是否有可能创建一个可以在层次结构的下一级重复使用的构建块,而无需重复相同的代码?
我认为构建模块可能是这样的:
\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[baseline={(0, 1.75cm)}]
\draw (0,0) rectangle (4,4);
\filldraw [ fill={gray} ] (0,2) rectangle (2,4);
\filldraw [ fill={gray} ] (2,0) rectangle (4,2);
\filldraw [ fill={gray} ] (0.1,1) rectangle (0.4,1.8);
\filldraw [ fill={gray} ] (0.5,1.5) rectangle (0.8,1.8);
\filldraw [ fill={gray} ] (0.9,1.5) rectangle (1.7,1.8);
\filldraw [ fill={gray} ] (2.1,3) rectangle (2.4,3.8);
\filldraw [ fill={gray} ] (2.5,3.5) rectangle (2.8,3.8);
\filldraw [ fill={gray} ] (2.9,3.5) rectangle (3.7,3.8);
\end{tikzpicture}}
\end{document]
答案1
描述
pic
为两个矩形 (rectangles
) 和正方形 (x0
)定义s- 进一步的图片 xi 用递归方式定义
\defxi
- 该比例用作递归的参数
代码
\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\tikzset{
x0/.pic={
\draw[fill={gray}] (0,0) rectangle (1,1);
},
rectangles/.pic={
\draw[fill={gray}] (0.1,0.8) rectangle (.3,.2);
\draw[fill={gray}] (0.4,0.8) rectangle (.9,.6);
},
every pic/.style={transform shape},
}
\newcommand{\defxi}[1]{
\tikzset{
x#1/.pic={
\draw[scale=##1] (0,0) rectangle (1,1);
\pic[scale=.5*##1] at (0,.5) {x\the\numexpr#1-1\relax=##1};
\pic[scale=.5*##1] at (.5,0) {x\the\numexpr#1-1\relax=##1};
\pic[scale=.5*##1] at (0,0) {rectangles};
\pic[scale=.5*##1] at (.5,.5) {rectangles};
}
}
}
\defxi{1}
\defxi{2}
\defxi{3}
\defxi{4}
\begin{document}
\begin{tikzpicture}
\foreach \i in {0, ..., 4} {
\pic at (\i*1.2,0) {x\i=1};
}
\end{tikzpicture}
\end{document}
结果
答案2
我已经调整了我的递归代码这个多边形相关的答案drawDist
。我删除了有关和的全部长篇大论,shiftDist
因为它们让事情变得比本来的更复杂。
两个矩形的线宽随着每个更深的层次而减半。这是通过
line width=.4pt/2^(\pgfkeysvalueof{/tikz/flakes/level'}-1)
基本上/tikz/flakes/level'
是一个计数器,随着我们越深入,计数就会增加(而level
计数越低)。默认线宽thin
为 0.4pt,我在这里将其用作起始线宽。
代码
\documentclass[tikz]{standalone}
\usepgfkeyslibrary{ext.pgfkeys-plus}
\makeatletter
\pgfqkeys{/handlers}{
.foreach/.code={\let\pgfkeys@exp@call@\pgfkeys@exp@call
\foreach\pgf@keys@temp in{#1}{\expandafter\pgfkeys@exp@call@\expandafter{\pgf@keys@temp}}}}
\makeatother
\newcommand*\flakesset{\pgfqkeys{/tikz/flakes}}
\newcommand*\flakescreate[1][]{\begingroup\flakesset{#1,start}\endgroup}
\flakesset{% adapted from https://tex.stackexchange.com/a/685124
.code=\flakesset{#1}, tikz/.code=\tikzset{#1},
level/.initial=0, level'/.initial=0, item/.initial=0,
start item/.initial=0, end item/.initial=3,
item list/.initial={\pgfkeysvalueof{/tikz/flakes/start item},...,\pgfkeysvalueof{/tikz/flakes/end item}},
start/.style={level'=0, item=0, tikz=flakes/at start/.try, __do=0},
__do/.style={
/utils/TeX/ifnum={\pgfkeysvalueof{/tikz/flakes/level}=0}{__place={#1}}{
level/.--, level'/.++, before split={#1},
__split/.foreach/.expanded={\pgfkeysvalueof{/tikz/flakes/item list}}}},
__split/.code={%
\pgfkeyssetevalue{/tikz/flakes/item}{#1}%
\tikzset{flakes/before do={#1}}%
\flakesset{__do={#1}}%
\tikzset{flakes/after do/.try={#1}}},
__place/.code={\path[flakes/styling={#1}](0,0)to[flakes/path={#1}](0,0);},
before split/.style={
level \pgfkeysvalueof{/tikz/flakes/level}/.try={#1},
level \pgfkeysvalueof{/tikz/flakes/level'}'/.try={#1}}}
%% Here starts your definitions
\flakesset{
hiermatrix/.style={
/tikz/my test/.style n args={3}{/utils/TeX/if=##1{##2}{##3}},
before do/.style 2 args={
shift={(##1.5,##2.5)}, scale=.5,
my test={##1##2}{% if ++ or -- place the drawing and stop recursions
/tikz/flakes/__place={##1##2},
/tikz/flakes/__do/.code=}{}},
styling/.style={
my flakes,
my test={##1}{line width=.4pt/2^(\pgfkeysvalueof{/tikz/flakes/level'}-1)}{}},
item list={++, -+, --, +-},
path/.style={
my test={##1}{% if ++ or -- draw two rectangles with border
to path={
(-1,-1) edge[to path=rectangle(\tikztotarget),thin,path only,draw] (1,1)
(-.75, -.5) rectangle ++(.25, 1.125) ++(right:.2) rectangle +(1, -.25)},
}{% otherwise just a rectangle
to path={(-1, -1) rectangle (1, 1)}}}}}
\begin{document}
\tikz[my flakes/.style={draw=black, fill=lightgray}]
\matrix[
column sep=5mm,
nodes={node font=\bfseries\sffamily,
node contents=(\pgfkeysvalueof{/tikz/flakes/level})},
cells={flakes/level/.expanded=\inteval{\pgfmatrixcurrentcolumn-1}}
]{
\path[my flakes] (-1,-1) rectangle (1,1); & \flakescreate[hiermatrix]
& \flakescreate[hiermatrix] & \flakescreate[hiermatrix] \\
\node[]; & \node[]; & \node[]; & \node[];\\};
\end{document}