在 tikz 中绘制非周期性平铺形状

在 tikz 中绘制非周期性平铺形状

我需要一个由看起来像帽子的碎片组成的网格,在 tikz 中。这是有四顶帽子的碎片。你能帮忙吗?我们可以使用 tikzlibrary 来平铺它吗?

非周期性平铺

\documentclass[border=3pt]{standalone}

\usepackage{tikz}

\begin{document}
    
    
\begin{tikzpicture}[rotate=-0]
\def\ra{1}
    \coordinate(O) at(0,0);
\coordinate(A1) at(0:\ra);
\coordinate(A2) at(60:\ra);
\coordinate(A3) at(120:\ra);
\path(A2)--(A1)--([turn]-60:\ra/2)coordinate(A01);
\draw[fill=yellow!6, thick](O)--(A01)--(A1)--(A2)--++(-\ra/2,0)--++(0,\ra)--([turn]60:\ra)--([turn]90:\ra/2)--([turn]60:\ra/2)--([turn]-90:\ra)--++(0,-\ra)coordinate(A3)--++(\ra/2,0)coordinate(A4)--([turn]-60:\ra/2)coordinate(A5)--cycle;

\draw[fill=gray!6, thick](O)--(A5)--(A4)--(A3)--++(-\ra/2,0)--([turn]60:\ra/2)coordinate(B1)--([turn]90:\ra)coordinate(B2) --++(0,-\ra)coordinate(B3)--++(\ra/2,0)coordinate(B4)--([turn]-60:\ra/2)coordinate(B5)--([turn]90:\ra)coordinate(B6)--++(0,\ra)coordinate(B7)--++(\ra/2,0)coordinate(B8)--(A01)--cycle;

\draw[fill=purple!6, thick](A01)--(B8)--(B7)--(B6)--(B5)--([turn]90:\ra/2)coordinate(D1)--++(\ra, 0)--([turn]60:\ra/2)--([turn]-90:\ra)--([turn]60:\ra)--([turn]90:\ra/2)--++(-\ra/2,0)--++(0,\ra)--(A01); 

\draw[fill=teal!6, thick](B5)--(B4)--(B3)--(B2)--(B1)--([turn]90:\ra/2)coordinate(C1)--([turn]60:\ra/2)--([turn]-90:\ra)--++(0,-\ra)--([turn]90:\ra/2)--([turn]-60:\ra/2)--([turn]90:\ra)--([turn]-60:\ra)--(D1)--cycle;

\end{tikzpicture}

\end{document}

答案1

有一个 TikZ 库可以实现这个功能,最初是为彭罗斯拼贴设计的,https://tex.stackexchange.com/a/440412/86,我正在更新它以适应新的图块。目前,我有帽子和乌龟,以及用于定义 的命令Tile(a,b),以及元和超级集群图块。我现在正在研究超级集群的替换系统,并对子集群感到疑惑。

您可以找到最新版本在 github 上, 有一个发布包含所有必要的文件,或者对于前沿版本,密钥文件是penrose_code.dtx,下载并运行tex penrose_code.dtx以生成必要的文件。

\documentclass{article}
%\url{https://tex.stackexchange.com/q/681708/86}
\usepackage{tikz}
\usetikzlibrary{
  tilings.polykite,
  calc,
}

\tikzset{
  hexagon/.pic={
    \path[pic actions] (1,0)
    foreach \k in {1,...,6} { -- (\k*60:1)}
    foreach \k in {1,...,6} {(0,0) -- (\k*60:1)}
    foreach \k in {1,...,6} {(0,0) -- (\k*60+30:{sqrt(3)/2})}
    ;
  },
  every tile/.style={draw}
}

\begin{document}

\begin{tikzpicture}[
  every aperiodical hat/.style={
    draw,
    ultra thick
  },
]
\pic[draw=none,fill=gray!50] {aperiodical hat};
\pic[draw,gray] at (-1,0) {hexagon};
\pic[draw,gray] at (60:1) {hexagon};
\pic[draw,gray] at (-60:1) {hexagon};
\pic[aperiodical hat,name=hat-a];
\pic[aperiodical hat,name=hat-b,align with=hat-a along 11 using 4];
\pic[aperiodical hat,name=hat-c,align with=hat-a along 26 using 7];
\pic[aperiodical hat,name=hat-d,align with=hat-a along 24 using 5];
\pic[aperiodical hat,name=hat-e,align with=hat-a along 13 using 2];
\pic[aperiodical hat,name=hat-f,align with=hat-a along 16 using 5];
\pic[red,flip tile,aperiodical hat,name=hat-g,align with=hat-a along 21 using 3];
\pic[aperiodical hat,name=hat-h,align with=hat-g back along 14 using 6];
\end{tikzpicture}
\end{document}

上述代码生成:

使用 penrose 包的非周期帽子

答案2

首先,让我们更精确地绘制图块,并选择一个角作为坐标零:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}

\draw (0,0) coordinate (-i0)
    -- ++(60:1/2) coordinate (-i1)
    -- ++(120:1) coordinate (-i2)
    -- ++(180:1/2) coordinate (-i3)
    -- ++(90:{sin(60)}) coordinate (-i4)
    -- ++(150:{sin(60)}) coordinate (-i5)
    -- ++(240:1/2) coordinate (-i6)
    -- ++(300:1/2) coordinate (-i7)
    -- ++(210:{sin(60)}) coordinate (-i8)
    -- ++(270:{sin(60)}) coordinate (-i9) 
    -- ++(0:1/2) coordinate (-i10)
    -- ++(300:1/2) coordinate (-i11)
    -- ++(30:{sin(60)}) coordinate (-i12)
    -- cycle;

% adding the labels
\foreach \i in {0,...,12} {
    \pgfmathparse{int(\i == 3 || \i == 9 ? 1 : 0)}
    \draw[red] (-i\i) circle[radius=2pt];
    \ifnum\pgfmathresult=1\relax
        \node[below, red, font=\ttfamily\tiny] at (-i\i) {(-i\i)};
    \else
        \node[right, red, font=\ttfamily\tiny] at (-i\i) {(-i\i)};
    \fi
}

\end{tikzpicture}
\end{document}

在此处输入图片描述

有了这个,我们可以pic从中创建一个。由于我们想要镜像和旋转它pic,并将其相对于其他对象放置,我们需要以特殊的方式创建它,以便我们首先创建坐标,然后绘制可以移动和旋转坐标的路径:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\newif\ifaperiodicalhatmirrored
\tikzset{
    pics/aperiodical hat/.style={
        code={
            \tikzset{
                aperiodical hat/.cd, 
                #1,
                coordinate transformation/.style={
                    rotate around={\pgfkeysvalueof{/tikz/aperiodical hat/rotate around inner anchor}:(-inner anchor)},
                    shift={($(-outer anchor)-(-inner anchor)$)},
                }
            }
            \ifaperiodicalhatmirrored
                \path[xscale=-1]
            \else
                \path
            \fi
                (0,0) coordinate (-i0)
                -- ++(60:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}/2}) coordinate (-i1)
                -- ++(120:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}}) coordinate (-i2)
                -- ++(180:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}/2}) coordinate (-i3)
                -- ++(90:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}*sin(60)}) coordinate (-i4)
                -- ++(150:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}*sin(60)}) coordinate (-i5)
                -- ++(240:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}/2}) coordinate (-i6)
                -- ++(300:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}/2}) coordinate (-i7)
                -- ++(210:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}*sin(60)}) coordinate (-i8)
                -- ++(270:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}*sin(60)}) coordinate (-i9) 
                -- ++(0:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}/2}) coordinate (-i10)
                -- ++(300:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}/2}) coordinate (-i11)
                -- ++(30:{\pgfkeysvalueof{/tikz/aperiodical hat/base unit}*sin(60)}) coordinate (-i12)
                -- cycle;
            \coordinate (-inner anchor) at (\pgfkeysvalueof{/tikz/aperiodical hat/inner anchor});
            \coordinate (-outer anchor) at (\pgfkeysvalueof{/tikz/aperiodical hat/outer anchor});
            \path[pic actions]
                ([aperiodical hat/coordinate transformation]-i0) coordinate (-o0)
                    foreach \x in {1,...,12} { 
                        -- ([aperiodical hat/coordinate transformation]-i\x) coordinate (-o\x)
                    } -- cycle;
        }
    },
    aperiodical hat/base unit/.initial={1},
    aperiodical hat/inner anchor/.initial={0,0},
    aperiodical hat/outer anchor/.initial={0,0},
    aperiodical hat/rotate around inner anchor/.initial={0},
    aperiodical hat/mirrored/.is if={aperiodicalhatmirrored}
}

\begin{document}
\begin{tikzpicture}

\pic[draw, fill=yellow!6] (tile1) {aperiodical hat};

\pic[draw, fill=black!6] (tile2) {aperiodical hat={inner anchor={-i5}, rotate around inner anchor=-60, mirrored}};

\pic[draw, fill=red!6] (tile3) {aperiodical hat={inner anchor={-i9}, rotate around inner anchor=240}};

\pic[draw, fill=green!6] (tile4) {aperiodical hat={inner anchor={-i2}, outer anchor={tile2-o10}}};

\end{tikzpicture}
\end{document}

在此处输入图片描述

该图片aperiodical hat有以下选项:

  • base unit:缩放瓷砖的因子。
  • inner anchor:当前图块的锚点。
  • outer anchor:指定的锚点inner anchor应位于另一个图块(或某个坐标)的锚点上。
  • rotate around inner anchor:图块应围绕指定的坐标旋转度数inner anchor
  • mirrored:如果使用,则瓷砖会被镜像。

每个 中有两组锚点pic。第一组是-i0-i12和 表示图块在旋转和移动之前(但在镜像之后)的角。第二组是-o0-o12和 表示应用所有变换之后的图块的角。对于inner anchor第一组,通常应使用(-i0到),对于第二组,应使用(到)。-i12outer anchor-o0-o12

有了这个功能,我认为应该可以创建更大的平铺......

答案3

另一个\pic版本。这个版本使用带有坐标的六边形网格来放置瓷砖。由于我们有一个“非周期性平铺”,所以我们需要手动放置瓷砖,但网格可以帮助我们做到这一点。

例如,尝试复制部分第一张图片在这里代码可能是:

\documentclass[tikz]{standalone}
\usetikzlibrary{calc}

\tikzset
{%
  tile1/.style={thick,draw=black,fill=blue!40!cyan},
  tile2/.style={thick,draw=black,fill=cyan!50},
  tile3/.style={thick,draw=black,fill=gray!30},
  tile4/.style={thick,draw=black,fill=white},
  pics/tile/.style={
    code={%
    \path[pic actions] (0,0)            --++ (330:{cos(30)})  --++ (60:0.5)  --++ (120:1)   -|++
                       (-0.5,{cos(30)}) --++ (150:{cos(30)})  --++ (240:0.5) --++ (300:0.5) --++
                       (210:{cos(30)})  |-++ (0.5,{-cos(30)}) --++ (300:0.5) -- cycle;
    % to show the hexagons, remove it or comment it if you want
    \draw[very thin,gray] (30:{cos(30)}) -- (0,0) -- (150:{2*cos(30)})
                     (0,0) -- (90:{cos(30)}) --++ (180:0.5) --++ (120:0.5) --++ (30:{cos(30)})
                     (-1,0) --++ (60:1);
    }}
}

\begin{document}
\begin{tikzpicture}
% grid and clip
\foreach\i in {0,...,9} \foreach[count=\j]\jj in {A,...,H} 
  \coordinate (\jj\i) at ({\j+0.5*mod(\i,2)},{\i*cos(30)});
\clip[draw] ($(A1)+(-0.2,0.2)$) rectangle ($(G8)+(0.2,-0.2)$);
% tiles
\pic[tile2]                      at (B1) {tile};
\pic[tile2,rotate=240]           at (D2) {tile};
\pic[tile4,rotate=120]           at (G2) {tile};
\pic[tile1,rotate=300,xscale=-1] at (B3) {tile};
\pic[tile3,rotate=300]           at (E3) {tile};
\pic[tile2,rotate=60]            at (H3) {tile};
\pic[tile4,rotate=120]           at (A4) {tile};
\pic[tile2]                      at (D4) {tile};
\pic[tile4,rotate=60]            at (B5) {tile};
\pic[tile3]                      at (E5) {tile};
\pic[tile4,rotate=180]           at (G6) {tile};
\pic[tile3,rotate=240]           at (B7) {tile};
\pic[tile3,rotate=180]           at (A8) {tile};
\pic[tile2,rotate=120]           at (G8) {tile};
\pic[tile4,rotate=120]           at (E9) {tile};
% to show the grid
%\foreach\i in {0,...,9} \foreach[count=\j]\jj in {A,...,H} 
%  \fill (\jj\i) node[right] {\footnotesize$\jj\i$} circle (0.4mm);
\end{tikzpicture}
\end{document}

并产生: 在此处输入图片描述

更新:帮助放置瓷砖的“地图”可以是 在此处输入图片描述

相关内容