编辑

编辑

我正在尝试在 TikZ 中围绕节点制作一个自动缩放的矩形云形状。下面的第一次尝试给出了一个椭圆形的云,但我不喜欢那样。我希望它是矩形的,就像第二次尝试一样。但那一次失败了;角是错误的,边缘是内外颠倒的。

两个失败的思维泡沫

\documentclass{book}
\usepackage{tikz}
\usetikzlibrary{shapes,positioning,decorations.pathmorphing}

\newcommand{\thinkA}[1] {
  \begin{tikzpicture}
    \node[cloud, draw, align=left, cloud puffs=20,cloud puff arc=110, aspect=2, inner sep=0mm]{#1};
  \end{tikzpicture}
}

\newcommand{\thinkB}[1] {
  \begin{tikzpicture}
    \node [rectangle, draw, decoration=bumps, decorate, align=left, inner sep=4mm] {#1};
  \end{tikzpicture}
}

\begin{document}
\thinkA{$3+5=8$\\$8+1=9$\\$9+6=15$}

\thinkB{$3+5=8$\\$8+1=9$\\$9+6=15$}
\end{document}

编辑:

感谢您迄今为止的反馈。这些解决方案看起来很有希望,但与提供的示例相比,其他内容存在一些缺陷:

一些缺陷

我试图制定一个我可以使用的内容的计划:最好是一个带有三个参数的命令;第一个是内容,第二个是边距,第三个是圆的直径,如下图所示:

在此处输入图片描述

必须计算绿色填充,以便边缘周围的圆圈图案能够正常工作。在上图中,边距设置为 2 毫米,圆圈直径为 5 毫米。内容恰好是 32 毫米宽和 16 毫米高。因此,我们需要 4 毫米额外宽度和 0 毫米额外高度来使圆圈匹配。

我尝试过做类似的东西,但我在编写 TikZ 程序时真的很吃力。下面的示例是我找到的修改版本别处在论坛上:

圆圈云

\documentclass{book}
\usepackage{tikz}
\usetikzlibrary{shapes,positioning,decorations.pathmorphing,calc}
\begin{document}
\begin{tikzpicture}[x=1mm,y=1mm]
\coordinate (NW) at (-30,20);
\coordinate (NE) at (30,20);
\coordinate (SW) at (-30,-20);
\coordinate (SE) at (30,-20);
\foreach \i in {0,2,...,12}{
    \draw[black] ([xshift=\i*5mm]NW) circle (5mm); % Draw circles on top
    \draw[black] ([xshift=\i*5mm]SW) circle (5mm); % Draw circles on bottom
}
\foreach \i in {2,4,...,6}{
    \draw[black] ([yshift=-\i*5mm]NW) circle (5mm); % Draw circles on left
    \draw[black] ([yshift=-\i*5mm]NE) circle (5mm); % Draw circles on right
}
\fill[white] (NW) rectangle (SE);
\node {contents};
\end{tikzpicture}
\end{document}

编辑2:

我正在努力理解 let 命令,并将其与循环结合起来,沿边缘绘制一系列圆弧。哎呀:我甚至无法计算两点之间的距离!我真的很烂。我意识到实际上不需要三个参数,我很乐意让边距在命令中使用 inner sep 固定,并为圆半径设置另一个固定大小,因为我可能会一直使用相同的半径。

编辑3:

有时你只需要咬紧牙关,坐下来研究文档。所以我这样做了,并制定了以下解决方案。如果云弧半径与内容的宽度和高度相比非常大,则代码很丑陋并且不起作用,但这个解决方案对我来说是有效的:

\documentclass{book}
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand{\think}[1] {
\begin{tikzpicture}
  \node (X) [rectangle, align=left, inner sep=2mm] {#1};
  \def\R{1.7mm}% Radius of cloud arcs
  \draw let
    \p1 = ($ (X.north east) - (X.north west) $),
    \p2 = ($ (X.north east) - (X.south east) $),
    \n{width} = {veclen(\x1,\y1)},
    \n{height}= {veclen(\x2,\y2)},
    \n{wnum} = {ceil(\n{width}/(2*\R)) - 1},
    \n{hnum} = {ceil(\n{height}/(2*\R)) - 1},
    \n{newwidth}  = {(2*\R) * (\n{wnum}+1)},
    \n{newheight} = {(2*\R) * (\n{hnum}+1)},
    \p3 = ($ (X.center) + (-\n{newwidth}/2,\n{newheight}/2) $)
    in
    \foreach \m in {1,2,...,\n{wnum}} {
        ($(\p3) + (\R+\m*2*\R,0)$) arc(0:180:\R)
        ($(\p3) + (-\R+\m*2*\R,-\n{newheight})$) arc(180:360:\R)
    }
    \foreach \m in {1,2,...,\n{hnum}} {
        ($(\p3) + (0,\R-\m*2*\R)$) arc(90:270:\R)
        ($(\p3) + (\n{newwidth},-\R-\m*2*\R)$) arc(-90:90:\R)
    }
    ($ (\p3) + (\R,0) $) arc(0:270:\R)% top left corner
    ($ (\p3) + (\n{newwidth},-\R) $) arc(-90:180:\R)% top right corner
    ($ (\p3) + (0,-\n{newheight}+\R) $) arc(90:360:\R)% bottom left corner
    ($ (\p3) + (\n{newwidth}-\R,-\n{newheight}) $) arc(-180:90:\R);% bottom right corner
\end{tikzpicture}
}

\begin{document}
\think{$3+5=8$\\$8+1=9$\\$9+6=15$}
\end{document}

解决方案

答案1

以下示例从矩形节点中删除线条绘制。相反,它会在之后绘制装饰线。通过将角替换为四分之一圆来修复角:

\documentclass{book}
\usepackage{tikz}
\usetikzlibrary{shapes,positioning,decorations.pathmorphing}
\usetikzlibrary{calc}

\newcommand{\thinkC}[1] {
  \begin{tikzpicture}
    \node (X) [rectangle,
      % draw,
      % rounded corners,
      % decoration={snake, amplitude=2pt},
      % decorate,
      align=left, inner sep=4mm] {#1};
    \def\R{11pt}
    \draw[
      decoration={bumps,segment length=8.1192pt},
      decorate,
    ]
      ($(X.south west) + (\R, 0)$) arc(270:180:\R) --
      ($(X.north west) + (0, -\R)$) arc(180:90:\R) --
      ($(X.north east) + (-\R, 0)$) arc(90:0:\R) --
      ($(X.south east) + (0, \R)$) arc(0:-90:\R) --
      cycle
    ;
  \end{tikzpicture}
}

\begin{document}
  \thinkC{$3+5=8$\\$8+1=9$\\$9+6=15$}
\end{document}

结果

缺点:需要仔细选择段长度以避免路径末端出现直线,因为剩余空间太小而无法形成完整的“凸起”。

以下方法使用带有 的装饰矩形path has corners。然后矩形稍微变大一些,宽度和高度都适合整数个凸起,请参阅代码中的注释:

\documentclass{book}
\usepackage{tikz}
\usetikzlibrary{shapes,positioning,decorations.pathmorphing}
\usetikzlibrary{calc}

\newcommand*{\StartSegmentLength}{8pt}

\newcommand{\thinkC}[1] {
  \begin{tikzpicture}
    % The rectangle node without frame
    \node (X) [
      rectangle,
      align=left,
      inner sep=4mm,
    ] {#1};

    % Get the width \WD and height \HT of the rectangle
    \pgfpointdiff{\pgfpointanchor{X}{south west}}{\pgfpointanchor{X}{north east}}
    \pgfgetlastxy\WD\HT

    % The shorter lenght of \WD and \HT is used to adapt the
    % segment length. \L is the shorter of \WD and \HT.
    % It is assumed that both \WD and \HT are large enough to contain
    % quite a few bumps, thus that the recalculated segment length
    % does not change too much. Also it is assumed, that enlarging the
    % larger length (width or height) is visually noticed less than
    % enlarging the smaller length.
    \ifdim\WD<\HT
      \let\L\WD
    \else
      \let\L\HT
    \fi

    % Recalculate the segment length.
    % Option "segment length" seems to cover *two* bumps.
    % Thus the calculations/roundings are done with half of the segment
    % length.
    \pgfmathsetlengthmacro\SegmentLength{\L / round(\L*2/\StartSegmentLength)}

    % Calculate the new height and width as multiple of half of
    % the segment length.
    % The addition of .1pt should protect from rounding errors.
    \pgfmathsetlengthmacro\newHT{
      round(\HT/\SegmentLength) * \SegmentLength + .1pt
    }
    \pgfmathsetlengthmacro\newWD{
      round(\WD/\SegmentLength) * \SegmentLength + .1pt
    }

    % Calculate the offsets for the corner points of the rectangle
    \pgfmathsetlengthmacro\XOff{(\newWD - \WD)/2}
    \pgfmathsetlengthmacro\YOff{(\newHT - \HT)/2}

    % Full segment length
    \pgfmathsetlengthmacro\SegmentLength{2 * \SegmentLength}

    % Now the decoration:
    \draw[
      decoration={
        bumps,
        segment length=\SegmentLength,
        path has corners,
      },
      decorate,
      line join=round,
    ]
      ($(X.south west) - (\XOff, \YOff)$) rectangle
      ($(X.north east) + (\XOff, \YOff)$)
    ;

    % Debugging only: The red box shows the original rectangle.
    % \draw[very thin, red] (X.south west) rectangle (X.north east);
  \end{tikzpicture}
}

\begin{document}
  \centering

  \thinkC{$3+5=8$\\$8+1=9$\\$9+6=15$}

  \thinkC{21212121212121}

\end{document}

结果

更新: line join=round增加了凸块之间的更好连接。

修复原始解决方案中的圆角问题

可以通过定义宏来配置每个角的凸起数量\BumpsPerCorner

\documentclass{book}
\usepackage{tikz}
\usetikzlibrary{shapes,positioning,decorations.pathmorphing}
\usetikzlibrary{calc}

\newcommand{\thinkC}[1]{
  \begin{tikzpicture}
    % The rectangle node without frame
    \node (X) [
      rectangle,
      align=left,
      inner sep=4mm,
    ] {#1};

    \def\SegmentLength{8pt}
    \def\BumpsPerCorner{4}

    % A bump uses half of the segment length
    \pgfmathsetlengthmacro\BumpLength{\SegmentLength/2}

    % Calculate radius, large enough for specified \BumpsPerCorner
    % Addition of .1pt should protect from rounding errors
    \pgfmathsetlengthmacro\R{
      \BumpsPerCorner * 2 * \BumpLength / pi + .1pt
    }

    % Get the width \WD and height \HT of the rectangle
    \pgfpointdiff{\pgfpointanchor{X}{south west}}
                 {\pgfpointanchor{X}{north east}}
    \pgfgetlastxy\WD\HT

    % Get \WD and \HT as length of the straight lines
    \pgfmathsetlengthmacro\WD{\WD - 2 * \R}
    \pgfmathsetlengthmacro\HT{\HT - 2 * \R}

    % Calculate new lengths as integer factor of the Bump length
    \pgfmathsetlengthmacro\newWD{
      round(\WD/\BumpLength) * \BumpLength + .1pt
    }
    \pgfmathsetlengthmacro\newHT{
      round(\HT/\BumpLength) * \BumpLength + .1pt
    }

     % Calculate the offsets for the corner points of the rectangle
    \pgfmathsetlengthmacro\XOff{(\newWD - \WD)/2}
    \pgfmathsetlengthmacro\YOff{(\newHT - \HT)/2}

    % Full segment length
    \pgfmathsetlengthmacro\SegmentLength{2 * \BumpLength}

    % Now the decoration:
    \draw[
      decoration={
        bumps,
        segment length=\SegmentLength,
        path has corners,
      },
      decorate,
      line join=round,
    ]
      ($(X.south west) + (-\XOff, -\YOff) + (\R, 0)$) arc(270:180:\R) --
      ($(X.north west) + (-\XOff, \YOff) + (0, -\R)$) arc(180:90:\R) --
      ($(X.north east) + (\XOff, \YOff) + (-\R, 0)$) arc(90:0:\R) --
      ($(X.south east) + (\XOff, -\YOff) + (0, \R)$) arc(0:-90:\R) --
      cycle
    ;

    % Debugging only: The red box shows the original rectangle.
    % \draw[very thin, red] (X.south west) rectangle (X.north east);
    \iffalse
      \draw[red, very thin]
        ($(X.south west) + (-\XOff, -\YOff) + (\R, 0)$) arc(270:180:\R) --
        ($(X.north west) + (-\XOff, \YOff) + (0, -\R)$) arc(180:90:\R) --
        ($(X.north east) + (\XOff, \YOff) + (-\R, 0)$) arc(90:0:\R) --
        ($(X.south east) + (\XOff, -\YOff) + (0, \R)$) arc(0:-90:\R) --
        cycle
      ;
    \fi
  \end{tikzpicture}
}

\begin{document}
  \centering

  \thinkC{$3+5=8$\\$8+1=9$\\$9+6=15$}

  \thinkC{21212121212121}

\end{document}

每个角落的凸起数:4

每个角有四个凸起的结果

每角凸起数:6

每个角有 6 个凸起的结果

答案2

像这样吗?

矩形云

装饰代码改为

decoration={bumps, path has corners, amplitude=-2.5pt, segment length=15pt}

2.5pt是默认值amplitude。将其设为负数会导致凸起朝相反方向凸起。默认值为segment length10pt因此15pt会稍微拉伸凸起。但是,请小心使用,因为值越大,失真越大。path has corners使 TiZ 会“更加小心地”绕过拐角,并且当路径有尖角时通常会改善结果。

完整代码:

\documentclass[border=10pt,multi,tikz]{standalone}
\usetikzlibrary{decorations.pathmorphing}
\newcommand{\thinkB}[1]{%
  \begin{tikzpicture}
    \node [rectangle, draw, decoration={bumps, path has corners, amplitude=-2.5pt, segment length=15pt}, decorate, align=left, inner sep=4mm] {#1};
  \end{tikzpicture}%
}
\begin{document}
\thinkB{$3+5=8$\\$8+1=9$\\$9+6=15$}
\end{document}

答案3

该解决方案基于Heiko 的一个。它不使用 ,decoration而是使用绘制节点的命令\ThinkA,然后使用cloud。此命令有一个强制参数(节点内容)和一个可选参数,用于定义凸块的直径(默认为 5mm)。

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning, calc}

\newcommand{\ThinkA}[2][5mm]{%
\begin{tikzpicture}
    \node[align=left, inner sep=4mm] (X) {#2}; 

    % Get the width \WD and height \HT of the rectangle
    \pgfpointdiff{\pgfpointanchor{X}{south west}}{\pgfpointanchor{X}{north east}}
    \pgfgetlastxy\WD\HT

    % Define diameter for bumps
    \pgfmathsetlengthmacro\Diameter{#1}

    % Calculate the new height and width as multiple of 
    % the radius
    \pgfmathsetlengthmacro\newHT{
      round(\HT/\Diameter) * \Diameter + .1pt
    }
    \pgfmathsetlengthmacro\newWD{
      round(\WD/\Diameter) * \Diameter + .1pt
    }

    % Calculate the offsets for the corner points of the rectangle
    \pgfmathsetlengthmacro\XOff{(\newWD - \WD)/2}
    \pgfmathsetlengthmacro\YOff{(\newHT - \HT)/2}

     \path ([shift={(-\XOff,\YOff)}]X.north west) coordinate (X1) rectangle ([shift={(\XOff,-\YOff)}]X.south east) coordinate (X2);

     \pgfmathsetmacro{\HBumps}{\newWD/\Diameter-1}
     \pgfmathsetmacro{\VBumps}{\newHT/\Diameter-1}

    % Draw upper and lower bumps
     \foreach \i in {1,...,\HBumps}{
        \draw ([xshift=-\Diameter/2+\i*\Diameter]X1) arc(180:0:\Diameter/2); 
        \draw ([xshift=\Diameter/2-\i*\Diameter]X2) arc(0:-180:\Diameter/2); 
    }

    % Draw left and right bumps
    \foreach \i in {1,...,\VBumps}{
        \draw ([yshift=\Diameter/2-\i*\Diameter]X1) arc(90:270:\Diameter/2); 
        \draw ([yshift=-\Diameter/2+\i*\Diameter]X2) arc(-90:90:\Diameter/2); 
    }

    % Draw corners bumps
    \draw ([xshift=\Diameter/2]X1) arc(0:270:\Diameter/2); 
    \draw ([xshift=-\Diameter/2]X1-|X2) arc(180:-90:\Diameter/2); 
    \draw ([yshift=\Diameter/2]X1|-X2) arc(90:360:\Diameter/2); 
    \draw ([yshift=\Diameter/2]X2) arc(90:-180:\Diameter/2); 
\end{tikzpicture}
}

\begin{document}

\ThinkA{$3+5=8$\\$8+1=9$\\$9+6=15$}

\ThinkA[4mm]{$3+5=8$\\$8+1=9$\\$9+6=15$}

\ThinkA[7mm]{21212121212121}
\end{document}

在此处输入图片描述

答案4

编辑

第二次尝试

正如 cfr 评论的那样,这可能不是您的本意。但是,您可以更改选项,decorate使其反映模式。然后,您还可以使用 设置每个装饰的大小,segment length并使用 指示您的节点有角path has corners。不幸的是,您必须设置一个minimum widthminimum height因此它是n*(segment length-tiny bit)

我希望这能满足你的需要。

结果

在此处输入图片描述

代码

\documentclass[convert]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,positioning,decorations.pathmorphing}
\newcommand{\thinkB}[1] {%
  \begin{tikzpicture}%
    \node [rectangle, draw, decoration={mirror, bumps, segment length=0.495cm, path has corners=true}, decorate, align=left, minimum width=2.5cm, minimum height=2.5cm] {#1};%
  \end{tikzpicture}%
}
\begin{document}
    \thinkB{$3+5=8$\\$8+1=9$\\$9+6=15$}
\end{document}

上一个答案

改变aspect=1

代码

\documentclass[convert]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,positioning,decorations.pathmorphing}
\newcommand{\thinkA}[1]{%
  \begin{tikzpicture}%
    \node[cloud, draw, align=left, cloud puffs=20,cloud puff arc=110, aspect=1, inner sep=0mm]{#1};%
  \end{tikzpicture}%
}%
\begin{document}
\thinkA{$3+5=8$\\$8+1=9$\\$9+6=15$}
\end{document}

输出

圆云

相关内容