TikZ - 如何制作镶嵌图案

TikZ - 如何制作镶嵌图案

我正在尝试使用 TikZ 制作一个简单的镶嵌,如下所示:

平面的镶嵌

但并没有取得多大成功。我尝试复制我在这里看到的一些工作,但钻石的位置甚至不是我所期望的:

\documentclass[tikz,border=5]{standalone}

\tikzset{pics/.cd, diamond-left/.style={code={
\path [every diamond-left/.try, #1]
 ( 0, 0) -- ( 0.866, -0.5) -- (0.866, 0.5) -- ( 0, 1) -- cycle;
}}}

\tikzset{pics/.cd, diamond-right/.style={code={
\path [every diamond-right/.try, #1]
 ( 0.866, -0.5) -- ( 1.732, 0) -- ( 1.732, 1) -- (0.866, 0.5) -- cycle;
}}}

\tikzset{pics/.cd, diamond-top/.style={code={
\path [every diamond-top/.try, #1]
 ( 0, 1 ) -- ( 0.866, 0.5) -- ( 1.732, 1) -- ( 0.866, 1.5) -- cycle;
}}}

\begin{document}
\begin{tikzpicture}[x=(300:5pt),y=(30:5pt)]
\pic at ( 0, 0) {diamond-left={fill=red}};
\pic at ( 0, 0) {diamond-right={fill=green}};
\pic at ( 0, 0) {diamond-top={fill=yellow}};
\end{tikzpicture}
\end{document}

此代码尝试生成 3 个菱形,以生成大小为 1 的六边形,仅生成:

基本六边形

值 0.866 约为 \sqrt{3}/2。定义它的正确方法是什么?

答案1

您可以写出({sqrt(3)/2},-0.5)或者使用极坐标(-30:1)

\documentclass[tikz,border=1cm]{standalone}
\tikzset{
pics/diamond/.style={code={
\fill (0,0) -- ++(30:1) -- ++(150:1) -- ++(210:1) -- cycle;
}}}
\begin{document}
\begin{tikzpicture}
\foreach \n in {0,...,3}{
   \pic[cyan] at ({\n*sqrt(3)},0) {diamond};
   \pic[cyan!60!black, rotate=120] at  ({\n*sqrt(3)},0) {diamond};
   \pic[cyan!80!black, rotate=240] at  ({\n*sqrt(3)},0) {diamond};
}
\begin{scope}[shift={({sqrt(3)/2},-1.5)}]
\foreach \n in {0,...,3}{
   \pic[cyan] at ({\n*sqrt(3)},0) {diamond};
   \pic[cyan!60!black, rotate=120] at  ({\n*sqrt(3)},0) {diamond};
   \pic[cyan!80!black, rotate=240] at  ({\n*sqrt(3)},0) {diamond};
}
\end{scope}
\begin{scope}[shift={(0,-3)}]
\foreach \n in {0,...,3}{
   \pic[cyan] at ({\n*sqrt(3)},0) {diamond};
   \pic[cyan!60!black, rotate=120] at  ({\n*sqrt(3)},0) {diamond};
   \pic[cyan!80!black, rotate=240] at  ({\n*sqrt(3)},0) {diamond};
}
\end{scope}
\end{tikzpicture}
\end{document}

3D 效果块镶嵌

编辑:300 行!但这段代码对此来说非常愚蠢。无需定义pics进行简单填充。也无需为每个单元格绘制三个形状。- 所有内容只需一个背景,然后每个单元格两个填充。- 甚至每行只需两个巧妙的填充。

无论如何,这里是循环列和行的代码:

\documentclass[tikz,border=1cm]{standalone}
\tikzset{
pics/diamond/.style={code={
\fill (0,0) -- ++(30:1) -- ++(150:1) -- ++(210:1) -- cycle;
}}}
\begin{document}
\begin{tikzpicture}[x=1mm, y=1mm]
\foreach \m in {0,...,19}{
\foreach \n in {0,...,29}{
   \pic[cyan] at ({\n*sqrt(3)},{\m*3}) {diamond};
   \pic[cyan!60!black, rotate=120] at  ({\n*sqrt(3)},{\m*3}) {diamond};
   \pic[cyan!80!black, rotate=240] at  ({\n*sqrt(3)},{\m*3}) {diamond};
   \begin{scope}[shift={({sqrt(3)/2},-1.5)}]
   \pic[cyan] at ({\n*sqrt(3)},{\m*3}) {diamond};
   \pic[cyan!60!black, rotate=120] at  ({\n*sqrt(3)},{\m*3}) {diamond};
   \pic[cyan!80!black, rotate=240] at  ({\n*sqrt(3)},{\m*3}) {diamond};
   \end{scope}
}}
\end{tikzpicture}
\end{document}

大面积 3D 效果立方体

编辑:更高效的代码:

\documentclass[tikz, border=1cm]{standalone}
\begin{document}
\begin{tikzpicture}[x=1mm, y=1mm]
\newcommand{\N}{100}
\newcommand{\M}{50}
\clip (1,-1) rectangle ({sqrt(3)*(\N+1)},{3*\M+2});
\fill[cyan]  (1,-1) rectangle ({sqrt(3)*(\N+1)},{3*\M+2});
\foreach \m in {0,...,\M}{
\begin{scope}[shift={(0,\m*3)}]
\fill[cyan!80!black] (0,0) foreach \n in {0,...,\N} {-- ++(30:1) -- ++(-30:1)} -- ++(0,-1) foreach \n in {0,...,\N} {-- ++(-30:-1) -- ++(30:-1)} -- cycle;
\fill[cyan!60!black]  foreach \n in {0,...,\N} { ({\n*sqrt(3)},0) -- ++(30:1) -- ++(0,-1) -- ++(30:-1) -- cycle};
\begin{scope}[shift={({sqrt(3)/2},1.5)}]
\fill[cyan!80!black]  (0,0) foreach \n in {0,...,\N} {-- ++(30:1) -- ++(-30:1)} -- ++(0,-1) foreach \n in {0,...,\N} {-- ++(-30:-1) -- ++(30:-1)} -- cycle;
\fill[cyan!60!black]  foreach \n in {0,...,\N} { ({\n*sqrt(3)},0) -- ++(30:1) -- ++(0,-1) -- ++(30:-1) -- cycle};
\end{scope}
\end{scope}
}
\end{tikzpicture}
\end{document}

非常大的立方体区域

答案2

在尝试简化@hpekristiansen的代码时,我想到了一个稍微不同的方法:box创建一张图片。使用TeX的原始命令很有趣\ifodd

在此处输入图片描述

\documentclass[tikz,border=5mm]{standalone}
\tikzset{pics/box/.style={code={
\fill[cyan!50] (0,0)--(30:1)--(0,1)--(150:1)--cycle;
\fill[cyan!75] (0,0)--(30:1)--(-30:1)--(0,-1)--cycle;
\fill[cyan] (0,0)--(150:1)--(210:1)--(0,-1)--cycle;
}}}

\begin{document}
\begin{tikzpicture}[declare function={m=6;n=4;a=sqrt(3)/2;}]
\foreach \i[parse=true] in {0,...,(m)}
\foreach \j[parse=true] in {0,...,(n)}{
\ifodd\j
\path (\i*2*a+a,-1.5*\j) pic{box};
\else
\path (\i*2*a,-1.5*\j) pic{box};
\fi 
}
\end{tikzpicture}
\end{document}

感谢@Qrrbrbirlbel 建议isodd使用 TikZ/PGF。这样,代码就变成了下面的一行代码。

\begin{tikzpicture}[declare function={m=6;n=4;a=sqrt(3)/2;}]
\foreach \i[parse=true] in {0,...,(m)}
\foreach \j[parse=true] in {0,...,(n)}
\path ({\i*2*a+isodd(\j)*a},-1.5*\j) pic{box};
\end{tikzpicture}

我们可以使用 Asymptote 获得许多优点:(size自动缩放、固定大小)、更好的准确性、更容易创建多参数picture等等。

在此处输入图片描述

// http://asymptote.ualberta.ca/
size(8cm); 
picture hexPoly;
pen p=Cyan;
fill(hexPoly,(0,0)--dir(30)--(0,1)--dir(150)--cycle,p+white);
fill(hexPoly,(0,0)--dir(30)--dir(-30)--(0,-1)--cycle,p+gray);
fill(hexPoly,(0,0)--dir(150)--dir(210)--(0,-1)--cycle,p+black);

int m=30,n=30;
real a=sqrt(3)/2;
for (int i=0; i<m; ++i)
for (int j=0; j<n; ++j)
if (remainder(j,2)==0)
add(shift(i*2*a+a,-1.5*j)*hexPoly);
else
add(shift(i*2*a,-1.5*j)*hexPoly);

另一个代码

在此处输入图片描述

// http://asymptote.ualberta.ca/
size(8cm); 
picture hexPoly;
pen p=Cyan;
path diamond=(0,0)--dir(30)--(0,1)--dir(150)--cycle;
fill(hexPoly,diamond,p+white);
fill(hexPoly,rotate(120)*diamond,p+gray);
fill(hexPoly,rotate(-120)*diamond,p+black);

int m=20,n=12;
real a=sqrt(3)/2;
for (int i=0; i<m; ++i)
for (int j=0; j<n; ++j)
add(shift(i*2*a+remainder(j,2)*a,-1.5*j)*hexPoly);
clip(box((0,.5),(m,-n)));

答案3

这是使用模式的完全不同的方法。它使用 PDF/postscripts 自己的模式程序,并且可以轻松创建十亿立即释放小盒子。

\documentclass[tikz, border=1cm]{standalone}
\usetikzlibrary{patterns}
\pgfdeclarepatternformonly{rhombus1} {\pgfpointorigin}{\pgfpointadd{\pgfpointpolar{30}{2pt}}{\pgfpoint{0pt}{2pt}}} {\pgfpointadd{\pgfpointpolar{30}{2pt}}{\pgfpoint{0pt}{2pt}}}{
\pgfpathmoveto{\pgfpoint{0pt}{0pt}} 
\pgfpathlineto{\pgfpointpolar{30}{1pt}}
\pgfpathlineto{\pgfpointadd{\pgfpointpolar{30}{1pt}}{\pgfpoint{0pt}{2pt}}}
\pgfpathlineto{\pgfpointadd{\pgfpointpolar{30}{2pt}}{\pgfpoint{0pt}{2pt}}}
\pgfpathlineto{\pgfpointadd{\pgfpointpolar{30}{2pt}}{\pgfpoint{0pt}{1pt}}}
\pgfpathlineto{\pgfpoint{0pt}{1pt}}\pgfpathclose
\pgfusepath{fill}
}
\pgfdeclarepatternformonly{rhombus2} {\pgfpointorigin}{\pgfpointadd{\pgfpointpolar{30}{2pt}}{\pgfpoint{0pt}{2pt}}} {\pgfpointadd{\pgfpointpolar{30}{2pt}}{\pgfpoint{0pt}{2pt}}}{
\pgfpathmoveto{\pgfpoint{0pt}{3pt}} 
\pgfpathlineto{\pgfpoint{0pt}{2pt}}
\pgfpathlineto{\pgfpointpolar{30}{2pt}}
\pgfpathlineto{\pgfpointadd{\pgfpointpolar{30}{2pt}}{\pgfpoint{0pt}{-1pt}}}
\pgfpathlineto{\pgfpointpolar{30}{1pt}}
\pgfpathlineto{\pgfpointadd{\pgfpointpolar{30}{1pt}}{\pgfpoint{0pt}{2pt}}}\pgfpathclose
\pgfusepath{fill}
}
\begin{document}
\begin{tikzpicture}
\fill[cyan] (0,0) rectangle (5,5);
\fill[pattern=rhombus1, pattern color=cyan!60!black] (0,0) rectangle (5,5); 
\fill[pattern=rhombus2, pattern color=cyan!30!black] (0,0) rectangle (5,5); 
\end{tikzpicture}
\end{document}

飞涨:

3D 盒子效果图案

相关内容