tikz:拼图边界形状

tikz:拼图边界形状

这个问题导致了一个新的方案的出现:
jigsaw

我想绘制一个拼图边界层,理想情况下连接两个半圆段。这两个段应通过一个弯曲的典型拼图边界连接,如下图所示:

免版税 shutterstock 图片

我找不到这种形状的任何 tikz 样板代码,除了此处的简化版本tex.sx

如果您已经画出这样的形状,请分享!

答案1

还有一个带 s 的版本pic。这可能会让构建完整的拼图变得更容易一些。

\documentclass[tikz,border=3.14mm]{standalone}
\begin{document}
\tikzset{pics/.cd,
  jigsaw/.style={
    code={
\fill[#1] (-2,-0.35) to[out=90,in=135] (-1.5,-0.45) arc(-135:135:0.6 and
{0.45*sqrt(2)}) to[out=-135,in=-90] (-2,0.35) |- (-0.35,2)
to[out=0,in=-45] (-0.45,2.5) arc(225:-45:{0.45*sqrt(2)} and 0.6)
to[out=-135,in=180] (0.35,2) -| (2,0.35) 
to[out=-90,in=225] (2.5,0.45) arc(135:-135:0.6 and {0.45*sqrt(2)})
to[out=135,in=90] (2,-0.35) |- (0.35,-2)
to[out=180,in=-135] (0.45,-1.5) arc(-45:225:{0.45*sqrt(2)} and 0.6) 
to[out=-45,in=0] (-0.35,-2) -| cycle;
}}}
\begin{tikzpicture}
\draw (-2,-2) pic{jigsaw=blue} (2,-2) pic{jigsaw=red}
(-2,2) pic[rotate=90]{jigsaw=purple} (2,2) pic[rotate=90]{jigsaw=green!60!black};
\end{tikzpicture}
\end{document}

在此处输入图片描述

更新:使用多用途拼图:语法是

pic{multipurpose jigsaw=fill <color> and <left>/<top>/<right>/<bottom>}

其中<color>确定填充颜色,其他参数指定凸耳:-1表示凸耳进入,1表示凸耳向外,0表示无凸耳。(还尝试改进颜色。;-)

\documentclass[x11names, svgnames, dvipsnames,tikz,border=3.14mm]{standalone}
\begin{document}
\tikzset{pics/.cd,
  jigsaw/.style={
    code={
\fill[#1] (-2,-0.35) to[out=90,in=135] (-1.5,-0.45) arc(-135:135:0.6 and
{0.45*sqrt(2)}) to[out=-135,in=-90] (-2,0.35) |- (-0.35,2)
to[out=0,in=-45] (-0.45,2.5) arc(225:-45:{0.45*sqrt(2)} and 0.6)
to[out=-135,in=180] (0.35,2) -| (2,0.35) 
to[out=-90,in=225] (2.5,0.45) arc(135:-135:0.6 and {0.45*sqrt(2)})
to[out=135,in=90] (2,-0.35) |- (0.35,-2)
to[out=180,in=-135] (0.45,-1.5) arc(-45:225:{0.45*sqrt(2)} and 0.6) 
to[out=-45,in=0] (-0.35,-2) -| cycle;
}},
multipurpose jigsaw/.style args={fill #1 and #2/#3/#4/#5}{
    code={%
\fill[#1] (-2,-0.35) to[out=90,in={90+#2*45}] ({-2+0.5*#2},-0.45) 
arc({-135-(#2-1)*45}:{(#2-1)*180+135+(#2-1)*45}:0.6 and
{0.45*sqrt(2)}) to[out=-90-#2*45,in=-90] (-2,0.35) |- (-0.35,2)
to[out=0,in={0+#3*45}] (-0.45,2-0.5*#3) arc(180-#3*45:{(#3+1)*180+#3*45}:{0.45*sqrt(2)} and 0.6)
to[out=-180-#3*45,in=180] (0.35,2) -| (2,0.35) 
to[out=-90,in=270+#4*45] (2-#4*0.5,0.45) 
arc(90-#4*45:{(#4+1)*180-90+#4*45}:0.6 and {0.45*sqrt(2)})
to[out=90-#4*45,in=90] (2,-0.35) |- (0.35,-2)
to[out=180,in=-180+#5*45] (0.45,-2+#5*0.5) arc(-#5*45:{(#5-1)*180+180+#5*45}:{0.45*sqrt(2)} and 0.6) 
to[out=-#5*45,in=0] (-0.35,-2) -| cycle;
}}}
% order : left/top/right/bottom and -1 is out, 1 is in, 0 none
\begin{tikzpicture}
\draw (-4,-4) pic{multipurpose jigsaw=fill FireBrick and 0/-1/1/0}
(0,-4) pic{multipurpose jigsaw=fill Blue and -1/-1/1/0}
(4,-4) pic{multipurpose jigsaw=fill ForestGreen and -1/1/0/0}
(-4,0) pic{multipurpose jigsaw=fill ForestGreen and 0/1/-1/1}
(0,0) pic{multipurpose jigsaw=fill FireBrick and 1/-1/1/1}
(4,0) pic{multipurpose jigsaw=fill Blue and -1/1/0/-1}
(-4,4) pic{multipurpose jigsaw=fill Blue and 0/0/1/-1}
(0,4) pic{multipurpose jigsaw=fill ForestGreen and -1/0/1/1}
(4,4) pic{multipurpose jigsaw=fill FireBrick and -1/0/0/-1};
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

基于单侧,可以轻松绘制拼图碎片。在以下示例中,\piece可以使用宏绘制所需形状的碎片。对于所有四侧,可以控制鼻子是朝外(-1)还是朝内(1)或朝直线(0)。

\documentclass{standalone}

\usepackage{tikz}

\newcommand{\side}[1]{
(0.0,#1*0.00) .. controls (0.0,#1*0.00) and (0.4,#1*-0.04) .. 
(0.4,#1*0.04) .. controls (0.4,#1*0.11) and (0.2,#1*0.26) .. 
(0.5,#1*0.26) .. controls (0.8,#1*0.26) and (0.6,#1*0.11) .. 
(0.6,#1*0.04) .. controls (0.6,#1*-0.04) and (1.0,#1*0.00) .. 
(1.0,#1*0.00)
}

\newcommand{\piece}[4]{
    \draw 
    \side{#1}
    [rotate around={90:(0.5,0.5)}] \side{#2} 
    [rotate around={180:(0.5,0.5)}] \side{#3} 
    [rotate around={270:(0.5,0.5)}] \side{#4};
}

\begin{document}

\begin{tikzpicture}[scale=3]
\piece{1}{1}{1}{1}
\end{tikzpicture}

\begin{tikzpicture}[scale=3]
\piece{1}{-1}{1}{1}
\end{tikzpicture}


\begin{tikzpicture}[scale=3]
\piece{1}{-1}{-1}{1}
\end{tikzpicture}


\begin{tikzpicture}[scale=3]
\piece{1}{-1}{-1}{-1}
\end{tikzpicture}


\begin{tikzpicture}[scale=3]
\piece{-1}{-1}{-1}{-1}
\end{tikzpicture}


\begin{tikzpicture}[scale=3]
\piece{-1}{1}{-1}{1}
\end{tikzpicture}

\end{document}

在此处输入图片描述

这些碎片也可以用来拼拼图:

\documentclass{standalone}

\usepackage{tikz}

\newcommand{\side}[1]{
(0.5,0.5) -- 
(0.0,#1*0.00) .. controls (0.0,#1*0.00) and (0.4,#1*-0.04) .. 
(0.4,#1*0.04) .. controls (0.4,#1*0.11) and (0.2,#1*0.26) .. 
(0.5,#1*0.26) .. controls (0.8,#1*0.26) and (0.6,#1*0.11) .. 
(0.6,#1*0.04) .. controls (0.6,#1*-0.04) and (1.0,#1*0.00) .. 
(1.0,#1*0.00)
}

\newcommand{\piece}[5][white]{
    \fill[#1] 
    \side{#2}
    [rotate around={90:(0.5,0.5)}] \side{#3} 
    [rotate around={180:(0.5,0.5)}] \side{#4} 
    [rotate around={270:(0.5,0.5)}] \side{#5} 
    -- cycle;
}

\begin{document}

\begin{tikzpicture}

\begin{scope}
    \piece[red]{1}{1}{0}{0}
\end{scope}
\begin{scope}[xshift=1cm]
    \piece[blue]{1}{-1}{-1}{0}
\end{scope}
\begin{scope}[xshift=2cm]
    \piece[green]{1}{0}{1}{0}
\end{scope}

\begin{scope}[yshift=-1cm]
    \piece[green]{1}{-1}{0}{-1}
\end{scope}
\begin{scope}[xshift=1cm,yshift=-1cm]
    \piece[red]{1}{-1}{1}{-1}
\end{scope}
\begin{scope}[xshift=2cm,yshift=-1cm]
    \piece[blue]{-1}{0}{1}{-1}
\end{scope}

\begin{scope}[yshift=-2cm]
    \piece[blue]{0}{-1}{0}{-1}
\end{scope}
\begin{scope}[xshift=1cm,yshift=-2cm]
    \piece[green]{0}{-1}{1}{-1}
\end{scope}
\begin{scope}[xshift=2cm,yshift=-2cm]
    \piece[red]{0}{0}{1}{1}
\end{scope}

\end{tikzpicture}

\end{document}

在此处输入图片描述

或者制作一个随机谜题:

\documentclass{standalone}

\usepackage{tikz}
\pgfmathparse{int(random(1,120))}

\newcommand{\side}[1]{
(0.0,#1*0.00) .. controls (0.0,#1*0.00) and (0.4,#1*-0.04) .. 
(0.4,#1*0.04) .. controls (0.4,#1*0.11) and (0.2,#1*0.26) .. 
(0.5,#1*0.26) .. controls (0.8,#1*0.26) and (0.6,#1*0.11) .. 
(0.6,#1*0.04) .. controls (0.6,#1*-0.04) and (1.0,#1*0.00) .. 
(1.0,#1*0.00)
}

\newcommand{\piece}[2]{
    \draw[ultra thick] \side{#1} [rotate around={90:(0.5,0.5)}] \side{#2};
}

\pgfmathdeclarerandomlist{inout}{{-1}{1}}

\begin{document}

\begin{tikzpicture}[scale=5]

    \def\xmax{10}
    \def\ymax{10}


    \foreach \x in {0,...,\xmax}{
        \foreach \y in {0,...,\ymax}{

            \ifnum\y=0
                \def\bottom{0}
            \else
                \pgfmathrandomitem{\bottom}{inout}%
            \fi

            \ifnum\x=\xmax
                \def\right{0}
            \else
                \pgfmathrandomitem{\right}{inout}%
            \fi

            \begin{scope}[xshift=\x cm, yshift=\y cm]
                \piece{\bottom}{\right}
            \end{scope}
        }
    }

    \draw (0,0) -- (0,\ymax+1) -- (\xmax+1,\ymax+1);

\end{tikzpicture}

\end{document}

在此处输入图片描述

带有背景图像

\documentclass{standalone}

\usepackage{tikz}
\pgfmathparse{int(random(1,120))}

\newcommand{\side}[1]{
(0.0,#1*0.00) .. controls (0.0,#1*0.00) and (0.4,#1*-0.04) .. 
(0.4,#1*0.04) .. controls (0.4,#1*0.11) and (0.2,#1*0.26) .. 
(0.5,#1*0.26) .. controls (0.8,#1*0.26) and (0.6,#1*0.11) .. 
(0.6,#1*0.04) .. controls (0.6,#1*-0.04) and (1.0,#1*0.00) .. 
(1.0,#1*0.00)
}

\newcommand{\piece}[2]{
    \draw[thick] \side{#1} [rotate around={90:(0.5,0.5)}] \side{#2};
}

\pgfmathdeclarerandomlist{inout}{{-1}{1}}

\begin{document}

\begin{tikzpicture}

    \node at (5.5,4) {\includegraphics[width=11cm,height=8cm]{example-image-duck}};

    \def\xmax{10}
    \def\ymax{7}


    \foreach \x in {0,...,\xmax}{
        \foreach \y in {0,...,\ymax}{

            \ifnum\y=0
                \def\bottom{0}
            \else
                \pgfmathrandomitem{\bottom}{inout}%
            \fi

            \ifnum\x=\xmax
                \def\right{0}
            \else
                \pgfmathrandomitem{\right}{inout}%
            \fi

            \begin{scope}[xshift=\x cm, yshift=\y cm]
                \piece{\bottom}{\right}
            \end{scope}
        }
    }

    \draw (0,0) -- (0,\ymax+1) -- (\xmax+1,\ymax+1);

\end{tikzpicture}

\end{document}

在此处输入图片描述

答案3

使用坐标计算来绘制旋转形状的选项[out=Angle,in=Angle,out looseness=Value,in looseness=Value];然后使用其他技巧来控制大小、角度、位置和颜色。

结果:

在此处输入图片描述

梅威瑟:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,calc,fit,shapes}

\begin{document}
    \begin{tikzpicture}
    \def\JigzawPiece(#1)[#2]#3#4{
    \begin{scope}[shift={(#1)},rotate=#4,transform shape]
    \coordinate (a) at (0:#2);\coordinate (b) at (90:#2);\coordinate (c) at (180:#2);\coordinate (d) at (270:#2);
    \foreach \nodA/\nodB in {a/b,b/c,c/d,d/a}{
    \coordinate (\nodA\nodB1) at ($ (\nodA)!{0.4}!(\nodB) $);
    \coordinate (\nodA\nodB2) at ($ (\nodA)!{0.6}!(\nodB) $); 
    \coordinate (\nodA\nodB3) at ($ (\nodA)!{0.5}!(\nodB) $);
    \coordinate (\nodA\nodB4) at ($(\nodA\nodB3)!0.5*#2 cm!90:(\nodA)$);
    \coordinate (\nodA\nodB5) at ($(\nodA\nodB3)!-0.5*#2 cm!90:(\nodA)$);
    }
    \draw[fill=#3]
        (a) -- (ab1) 
            to [out=133,in=-45,out looseness=1,in looseness=2] (ab5) 
            to [out=135,in=-45,out looseness=2,in looseness=1] (ab2) --
        (b) -- (bc1) 
            to [out=-135,in=45,out looseness=1,in looseness=2] (bc4) 
            to [out=-135,in=45,out looseness=2,in looseness=1] (bc2) --
        (c) -- (cd1) 
            to [out=-45,in=135,out looseness=1,in looseness=2] (cd4) 
            to [out=-45,in=135,out looseness=2,in looseness=1] (cd2) --
        (d) -- (da1) 
            to [out=45,in=-135,out looseness=1,in looseness=2] (da5) 
            to [out=45,in=-135,out looseness=2,in looseness=1] (da2) --(a);
    \end{scope}
    }

    \foreach \x in {0,1,...,7}{
        \foreach \y in {0,1,...,5}{
        \pgfmathparse{0.9*rnd+0.3}
             \definecolor{Rcolor}{rgb}{\pgfmathresult,\pgfmathresult,\pgfmathresult} % from https://tex.stackexchange.com/a/37279/154390
            \JigzawPiece(\x,\y)[0.5]{blue!50!Rcolor}{0}
            \JigzawPiece(\x+0.5,\y+0.5)[0.5]{blue!30!Rcolor}{0}
        }
    }
    \foreach \ang [count=\j from 0] in {0,90,180,270} {
        \JigzawPiece(0.5+\j*2,7)[1]{red}{\ang}
    }

    \foreach \ang [count=\j from 0] in {-45,45,45,-45,-45} {
        \JigzawPiece(0.5+\j*1.4142,9)[1]{red}{\ang}
    }
    \end{tikzpicture}

\end{document}

相关内容