有没有一种简单的方法可以在 tikz 中绘制出如图所示的装饰蜂窝?
我的尝试如下,但这种方法无法让我用颜色填充六边形。此外,目前绘制格子效率有点低,因为在使用范围时应该使用 for 循环。
\documentclass[10pt]{article}
\usepackage{tikz}
\usepackage{calculator}
\usetikzlibrary{rulercompass}
\usetikzlibrary{intersections,quotes,angles}
\usetikzlibrary{calc}
\usepackage{calc}
\newlength{\R}\setlength{\R}{2cm}
\newcommand{\gettikzxy}[3]{%
\tikz@scan@one@point\pgfutil@firstofone#1\relax
\edef#2{\the\pgf@x}%
\edef#3{\the\pgf@y}%
}
\begin{document}
\begin{tikzpicture}
%% Try to define a style, to prevent typing
[inner sep=0mm,
minicirc/.style={circle,draw=black!40,fill=black!40,thick}]
%% Now do the circle with nodes
\node (circ1) at (60:\R) [minicirc] {};
\node (circ2) at (120:\R) [minicirc] {};
\node (circ3) at (180:\R) [minicirc] {};
\node (circ4) at (240:\R) [minicirc] {};
\node (circ5) at (300:\R) [minicirc] {};
\node (circ6) at (360:\R) [minicirc] {};
\node (circ7) at (45:2*\R) [minicirc] {};
\node (circ8) at (105:2*\R) [minicirc] {};
\node (circ9) at (165:2*\R) [minicirc] {};
\node (circ10) at (225:2*\R) [minicirc] {};
\node (circ11) at (285:2*\R) [minicirc] {};
\node (circ12) at (345:2*\R) [minicirc] {};
\node (circ13) at (75:2*\R) [minicirc] {};
\node (circ14) at (135:2*\R) [minicirc] {};
\node (circ15) at (195:2*\R) [minicirc] {};
\node (circ16) at (255:2*\R) [minicirc] {};
\node (circ17) at (315:2*\R) [minicirc] {};
\node (circ18) at (375:2*\R) [minicirc] {};
%% Connect those circs
\draw [black] (circ1) to (circ2) to (circ3)
to (circ4) to (circ5) to (circ6) to (circ1);
\fill [orange] (circ1) to (circ2) to (circ3)
to (circ4) to (circ5) to (circ6) to (circ1);
\draw [] (circ7) to (circ13) to (circ8)
to (circ14) to (circ9) to (circ15) to (circ10) to (circ16) to (circ11) to (circ17) to (circ12) to (circ18) to (circ7);
\draw[](circ1)--(circ7);
\draw (circ2)--(circ8);
\draw (circ3)--(circ9);
\draw (circ4)--(circ10);
\draw (circ5)--(circ11);
\draw (circ6)--(circ12);
\draw (circ1)--(circ13);
\draw (circ2)--(circ14);
\draw (circ3)--(circ15);
\draw (circ4)--(circ16);
\draw (circ5)--(circ17);
\draw (circ6)--(circ18);
\draw node[scale=3]{B} (0,0);
\node (circshift) at ($ (circ7) + (\R,0) $) [minicirc] {};
\begin{scope}[shift={(circshift)}]
\node (circ1) at (60:\R) [minicirc] {};
\node (circ2) at (120:\R) [minicirc] {};
\node (circ3) at (180:\R) [minicirc] {};
\node (circ4) at (240:\R) [minicirc] {};
\node (circ5) at (300:\R) [minicirc] {};
\node (circ6) at (360:\R) [minicirc] {};
\node (circ7) at (45:2*\R) [minicirc] {};
\node (circ8) at (105:2*\R) [minicirc] {};
\node (circ9) at (165:2*\R) [minicirc] {};
\node (circ10) at (225:2*\R) [minicirc] {};
\node (circ11) at (285:2*\R) [minicirc] {};
\node (circ12) at (345:2*\R) [minicirc] {};
\node (circ13) at (75:2*\R) [minicirc] {};
\node (circ14) at (135:2*\R) [minicirc] {};
\node (circ15) at (195:2*\R) [minicirc] {};
\node (circ16) at (255:2*\R) [minicirc] {};
\node (circ17) at (315:2*\R) [minicirc] {};
\node (circ18) at (375:2*\R) [minicirc] {};
%% Connect those circs
\draw [black] (circ1) to (circ2) to (circ3)
to (circ4) to (circ5) to (circ6) to (circ1);
\fill [orange] (circ1) to (circ2) to (circ3)
to (circ4) to (circ5) to (circ6) to (circ1);
\draw [] (circ7) to (circ13) to (circ8)
to (circ14) to (circ9) to (circ15) to (circ10) to (circ16) to (circ11) to (circ17) to (circ12) to (circ18) to (circ7);
\draw (circ1)--(circ7);
\draw (circ2)--(circ8);
\draw (circ3)--(circ9);
\draw (circ4)--(circ10);
\draw (circ5)--(circ11);
\draw (circ6)--(circ12);
\draw (circ1)--(circ13);
\draw (circ2)--(circ14);
\draw (circ3)--(circ15);
\draw (circ4)--(circ16);
\draw (circ5)--(circ17);
\draw (circ6)--(circ18);
% \node (origin) at (0,0,0) {0};
\draw node[scale=3]{R} (0,0);%
\end{scope}
\end{tikzpicture}
\end{document}
答案1
一切皆节点。
这使用regular polygon
形状并且它放置的每一步如下图所示:
或者使用
node[hc41={##1}{##2}]node[hc42={##1}{##2}]node[hc43={##1}{##2}]
未注释:
(由于所有边都被六边形或三角形覆盖,因此实际上不需要正方形。)
每个六边形节点都存在一种可以改变的样式:
every hexagon node
获取两个参数(X和是值)和hexagon node x-y
对于每个六边形
第一种样式可用于通过以下方式查找特定的六边形:
every hexagon node/.style 2 args={label=center:#1/#2}
甚至三角形也有hc31
和 ,hc32
包括和。如果使用正方形,情况也是如此。hc31-x-y
hc32-x-y
对于较小的n-gon side length
s 来说,使用label
而不是更安全,node contents
因为label
不会改变节点的大小。
输出位于此答案的末尾,看起来与下一个答案完全相同,但是,当hc??
取消注释样式时,它看起来更加丰富多彩。
代码
\documentclass[tikz]{standalone}
\usetikzlibrary{shapes.geometric}
\tikzset{decorated honeycomb lattice/.style={
/utils/exec=\colorlet{honeycomb@0}{blue!50}%
\colorlet{honeycomb@1}{green!75!black}%
\colorlet{honeycomb@2}{red!75!black},
n-gon side length/.initial={#1},
n-gon/.style={shape=regular polygon, regular polygon sides={##1},
inner sep=+0pt, outer sep=+0pt, line join=round, node contents=},
6-gon/.style={n-gon=6, draw,
minimum size=2*(\pgfkeysvalueof{/tikz/n-gon side length})},
4-gon/.style={n-gon=4, draw, anchor=corner 3,
minimum size=1.41421356*(\pgfkeysvalueof{/tikz/n-gon side length})},
3-gon/.style={n-gon=3, draw, anchor=corner 2,
minimum size=1.15470053838*(\pgfkeysvalueof{/tikz/n-gon side length})},
dots/.style={shape=circle, draw, fill=white, inner sep=+0pt,
minimum size=(\pgfkeysvalueof{/tikz/n-gon side length})/5},
hc41/.style 2 args={4-gon,at=(@.corner 2),hc41-##1/.try},
hc42/.style 2 args={4-gon,at=(@.corner 3),rotate=60,hc42-##2/.try},
hc43/.style 2 args={4-gon,at=(@.corner 4),rotate=120,hc43-##2/.try},
hc31/.style 2 args={3-gon,at=(@.corner 2),rotate=90, hc31-##2/.try},
hc32/.style 2 args={3-gon,at=(@.corner 3),rotate=150,hc32-##2/.try},
@aac/.style 2 args={append after command={
node[hc41={##1}{##2}]node[hc42={##1}{##2}]node[hc43={##1}{##2}]
node[hc31={##1}{##2}]node[hc32={##1}{##2}]\pgfextra{\def\tikzlastnode{@}}}},
place hexagon/.style 2 args={
6-gon, name=hc-##1-##2, at={(##1,##2)}, alias=@,
/utils/exec=\pgfmathint{mod(mod(##1,3)-mod(##2,3)+3,3)},
fill/.expanded=honeycomb@\pgfmathresult,
@aac/.expanded={\pgfmathresult}{##1-##2},
every hexagon node/.try={##1}{##2}, hexagon node ##1-##2/.try},
x={([shift=(60:\pgfkeysvalueof{/tikz/n-gon side length}),
shift=(30:\pgfkeysvalueof{/tikz/n-gon side length})]
0:\pgfkeysvalueof{/tikz/n-gon side length})},
y={([shift=(120:\pgfkeysvalueof{/tikz/n-gon side length}),
shift=(90:\pgfkeysvalueof{/tikz/n-gon side length})]
60:\pgfkeysvalueof{/tikz/n-gon side length})}}}
\newcommand*\tikzplacehexagonsanddots[2]{%
\foreach \x in {#1} \foreach \y in {#2} \node[place hexagon={\x}{\y}]{};
\foreach \x in {#1} \foreach \y in {#2} \foreach \corner in {1,...,6}
\node[at=(hc-\x-\y.corner \corner),dots]{};}
\begin{document}
\begin{tikzpicture}[
decorated honeycomb lattice=.5cm,
% every hexagon node/.style 2 args={label=center:#1/#2},
every hexagon node/.append style={font=\itshape},
hexagon node 3-0/.style={node contents=b},
hexagon node 2-0/.style={node contents=r},
hexagon node 3--1/.style={node contents=g},
% hc41/.append style={fill=honeycomb@#1!50},
% hc42/.append style={fill=honeycomb@#1!50},
% hc43/.append style={fill=honeycomb@#1!50},
% hc31/.append style={fill=honeycomb@#1!50},
% hc32/.append style={fill=honeycomb@#1!50},
]
\clip (-.5,0) rectangle (4,1.25);
\tikzplacehexagonsanddots{0,...,5}{-3,...,3}
\end{tikzpicture}
\end{document}
递归路径
该解决方案仅使用路径,但以递归方式放置它们,以便我们可以在递归返回时放置点。
一些算法源自以前的方法。
此处正方形被禁用(参见\path[dhl/square/.try] …
),但即使启用,它们也不会绘制任何内容,为此dhl/square
需要定义样式(例如draw
)。这不会区分不同的三角形和正方形,但可以通过拆分路径轻松完成。
代码
\documentclass[tikz]{standalone}
\makeatletter
\pgfqkeys{/utils}{TeX/ifnum/.code n args={3}{%
\ifnum#1\relax\expandafter\pgfutil@firstoftwo\else
\expandafter\pgfutil@secondoftwo\fi{\pgfkeysalso{#2}}{\pgfkeysalso{#3}}}}
\makeatother
\colorlet{honeycomb@0}{blue!50}
\colorlet{honeycomb@1}{green!75!black}
\colorlet{honeycomb@2}{red!75!black}
\tikzset{
dhl/cs/.style={
/tikz/x={([shift=(60:#1),shift=(30:#1)]0:#1)},
/tikz/y={([shift=(120:#1),shift=(90:#1)]60:#1)}},
dhl/dots/.style={
shape=circle, draw, fill=white, inner sep=+0pt, minimum size=.1cm},
dhl/draw hexagon/.code n args={5}{%
\pgfmathtruncatemacro\hccolor{mod(mod(#1,3)-mod(#3,3)+3,3)}%
\coordinate (hc-#1-#3) at (xyz cs:/tikz/dhl/cs={#5},x=#1,y=#3);
\draw[shift=(hc-#1-#3), fill/.expanded=honeycomb@\hccolor, x={#5}, y={#5},
dhl/hexagon/.try={#1}{#3}, dhl/hexagon-#1-#3/.try](0:#5) --(60:#5)--(120:#5)
coordinate(@1)--(180:#5)coordinate(@2)--(240:#5)--(300:#5)--cycle;
\draw[dhl/triangle/.try] (@1) --+(90:#5) --+(150:#5) -- cycle
(@2) --+(150:#5)--+(210:#5) -- cycle;
% \path[dhl/square/.try] (@1)--++(0:#5)--([turn]90:#5)--([turn]90:#5)--cycle
% (@1)--++(150:#5)--([turn]90:#5)--([turn]90:#5)--cycle
% (@2)--++(210:#5)--([turn]90:#5)--([turn]90:#5)--cycle;
\tikzset{
/utils/TeX/ifnum={#1<#2}{% to the right?
dhl/draw hexagon/.expanded={\the\numexpr#1+1\relax}{#2}{#3}{#4}{#5}},
/utils/TeX/ifnum={#1=0}{% first row …
/utils/TeX/ifnum={#3<#4}{% … upwards?
dhl/draw hexagon/.expanded={#1}{#2}{\the\numexpr#3+1\relax}{#4}{#5}}}}
\path[shift=(hc-#1-#3)] foreach \ang in {0,60,...,359}{
node[dhl/dots] at (\ang:#5){}};},
start hexagon/.style args={#1 and #2 length #3}{
dhl/draw hexagon={0}{#1}{0}{#2}{#3}}}
\begin{document}
\begin{tikzpicture}[
% dhl/hexagon/.style 2 args={insert path={node{#1/#2}}},
dhl/text/.style={font=\itshape},
dhl/hexagon-2-3/.style={insert path={node[dhl/text]{r}}},
dhl/hexagon-3-2/.style={insert path={node[dhl/text]{g}}},
dhl/hexagon-3-3/.style={insert path={node[dhl/text]{b}}}
]
\clip[dhl/cs=.5cm] (-.5,3) rectangle (4,4.25);
\tikzset{start hexagon=6 and 7 length .5cm}
\end{tikzpicture}
\end{document}
输出
答案2
使用\pic
,我得出了以下结论:
\documentclass[border=10mm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[
pics/rhombitrihexagonal tiling/.default={r}{g}{b},
pics/rhombitrihexagonal tiling/.style n args={3}{
code={
\foreach \s/\c/\n in {(30:1+2*sin(60))/red/#1, (0:0)/green/#2, (-30:1+2*sin(60))/blue/#3} {
\begin{scope}[shift={\s}]
\draw[fill=\c] (0:1) -- (60:1) -- (120:1) -- (180:1) -- (240:1) -- (300:1) -- cycle;
\node at (0,0) {\n};
\foreach \i in {2,3} {
\begin{scope}[rotate=60*\i, shift={(0:1)}]
\draw (0:0) -- (30:1) -- (-30:1) -- cycle;
\end{scope}
}
\end{scope}
}
}
}]
\foreach \y in {0,...,3} {
\foreach \x in {0,...,3} {
\path ({(0.5*mod(\y,2)+\x)*(3+2*sin(60))},{\y*(1.5+3*sin(60))}) pic {rhombitrihexagonal tiling};
}
}
\end{tikzpicture}
\end{document}
添加小圆圈并可以设置自定义颜色:
\documentclass[border=10mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\colorlet{rhombitrihexagonal tiling color one}{red}
\colorlet{rhombitrihexagonal tiling color two}{green}
\colorlet{rhombitrihexagonal tiling color three}{blue}
\begin{document}
\begin{tikzpicture}[
pics/rhombitrihexagonal tiling/.default={r}{g}{b},
pics/rhombitrihexagonal tiling/.style n args={3}{
code={
\foreach \s/\c/\n in {
(30:1+2*sin(60))/rhombitrihexagonal tiling color one/#1,
(0:0)/rhombitrihexagonal tiling color two/#2,
(-30:1+2*sin(60))/rhombitrihexagonal tiling color three/#3
} {
\begin{scope}[shift={\s}]
\begin{pgfonlayer}{background}
\draw[fill=\c] (0:1) -- (60:1) -- (120:1) -- (180:1) -- (240:1) -- (300:1) -- cycle;
\node at (0,0) {\n};
\foreach \i in {2,3} {
\begin{scope}[rotate=60*\i, shift={(0:1)}]
\draw (0:0) -- (30:1) -- (-30:1) -- cycle;
\end{scope}
}
\end{pgfonlayer}
\foreach \i in {0,...,5} {
\draw[fill=white] ({60*\i}:1) circle[radius=2pt];
}
\end{scope}
}
}
}]
\foreach \y in {0,...,3} {
\foreach \x in {0,...,3} {
\path ({(0.5*mod(\y,2)+\x)*(3+2*sin(60))},{\y*(1.5+3*sin(60))}) pic {rhombitrihexagonal tiling};
}
}
\end{tikzpicture}
\end{document}
本例中需要使用该backgrounds
库,否则小圆圈不会一直位于前景中。然而,这会导致裁剪问题,因为由于范围限制,背景层上的内容不会被裁剪。
因此,我稍微修改了代码,使backgrounds
库的使用变得没有必要。然而,在这个解决方案中,重要的是从左到右、从下到上添加图块,以使小圆圈始终与之前的图块重叠:
\documentclass[border=10mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\colorlet{rhombitrihexagonal tiling color one}{red}
\colorlet{rhombitrihexagonal tiling color two}{green}
\colorlet{rhombitrihexagonal tiling color three}{blue}
\begin{document}
\begin{tikzpicture}[
pics/rhombitrihexagonal tiling/.default={r}{g}{b},
pics/rhombitrihexagonal tiling/.style n args={3}{
code={
\foreach \s/\c/\n [count=\k] in {
(0:0)/rhombitrihexagonal tiling color two/#2,
(-30:1+2*sin(60))/rhombitrihexagonal tiling color three/#3,
(30:1+2*sin(60))/rhombitrihexagonal tiling color one/#1
} {
\begin{scope}[shift={\s}]
\draw[fill=\c] (0:1) -- (60:1) -- (120:1) -- (180:1) -- (240:1) -- (300:1) -- cycle;
\node at (0,0) {\n};
\foreach \i in {4,5} {
\begin{scope}[rotate=60*\i, shift={(0:1)}]
\draw (0:0) -- (30:1) -- (-30:1) -- cycle;
\draw[fill=white] (0:0) circle[radius=2pt];
\draw[fill=white] (-30:1) circle[radius=2pt];
\ifnum\i=5
\ifnum\k=2
\draw[fill=white] (30:1) circle[radius=2pt];
\fi
\else
\draw[fill=white] (30:1) circle[radius=2pt];
\fi
\end{scope}
}
\ifnum\k=3\else
\draw[fill=white] (180:1) circle[radius=2pt];
\fi
\end{scope}
}
}
}]
\clip[draw] (4,2) rectangle (15,10);
\foreach \y in {0,...,3} {
\foreach \x in {0,...,3} {
\path ({(0.5*mod(\y,2)+\x)*(3+2*sin(60))},{\y*(1.5+3*sin(60))}) pic {rhombitrihexagonal tiling};
}
}
\end{tikzpicture}
\end{document}
单个图块如下所示: