tikz 自定义形状太大

tikz 自定义形状太大

我尝试使用 tikzpicture 在 1 个单位内创建自定义形状,但是当我使用它时,它几乎是 2 个单位大小。

\documentclass[border=1pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
  \definecolor{bakcolor}{RGB}{220,150,100}
  \newsavebox\myheadphone
  \begin{lrbox}{\myheadphone}
    \begin{tikzpicture}
      \def\d{5pt}
      \draw[draw=none,fill={rgb,255:red,220; green,150; blue,100}] (0,0) circle (1);
      \draw[draw=white,line width=\d,line cap=round] (-40:1) arc (-40:220:1);
      \draw[draw=white,fill=white,line width=\d,rounded corners=2pt] (-40:1) rectangle ++(-0.3,-0.6);
      \draw[draw=white,fill=white,line width=\d,rounded corners=2pt] (220:1) rectangle ++(0.3,-0.6);
    \end{tikzpicture}
  \end{lrbox}
  \draw[help lines,] (-2, -2) grid[step={(1,1)}] (2, 2);
  \node[draw] (A) {A};
  \node[circle,fill=bakcolor,right=1cm of A,minimum size=4] (B) {\usebox\myheadphone};
  \draw[->] (A) -- (B);
\end{tikzpicture}
\end{document}

输出: 在此处输入图片描述

明显地:

  1. 自定义形状的边框太宽。
  2. 整个物体太大。最小尺寸关键字不起作用。

答案1

您所做的是,首先创建一个半径略大于 1cm 的形状,然后将此形状放入一个矩形框中,最后将该框放入一个圆形中node。节点在内容和边框之间有一个inner sep填充。因此,您放置形状的节点的宽度大于 2cm。正如 marmot 正确指出的那样,定义minimum size了节点大小的下限,如果节点的内容较大,则节点会变得更大。也就是说,您设置的没有单位,在这种情况下,我相信minimum size=4默认单位是。pt

无论如何,如果您希望耳机符号适合半径为 1cm 的圆圈,请缩小它的尺寸。pic不过,您可以考虑使用 而不是 保存框,请参见下面的示例。左边是 保存框,右边是pic

保存框本身是矩形的,因此即使您将包含它的节点的形状设置为circle,箭头仍然无法到达该形状。inner sep不过,您可以使用负数来规避该问题,请尝试\node [inner sep=-8.5pt,circle] (C) at (-2,0) {\usebox\myheadphone};

代码输出

\documentclass[border=1pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\definecolor{bakcolor}{RGB}{220,150,100}

\tikzset{
  headphone/.pic={
      \def\d{5pt}
      \node[draw=none,fill=bakcolor,minimum size=2cm,circle] (-outline) at (0,0){};
      \begin{scope}[yshift=\d/2]
      \draw[draw=white,line width=\d,line cap=round] (-40:0.6) arc[start angle=-40,end angle=220,radius=0.6];
      \filldraw[white,line width=\d,rounded corners=2pt] (-40:0.6) rectangle ++(-0.2,-0.35);
      \filldraw[white,line width=\d,rounded corners=2pt] (220:0.6) rectangle ++(0.2,-0.35);
      \end{scope}
  }
}

\begin{document}
\begin{tikzpicture}
\newsavebox\myheadphone
  \begin{lrbox}{\myheadphone}
    \begin{tikzpicture}
      \def\d{5pt}
      \draw[draw=none,fill={rgb,255:red,220; green,150; blue,100}] (0,0) circle (1);
      \begin{scope}[yshift=\d/2]
      \draw[draw=white,line width=\d,line cap=round] (-40:0.6) arc[start angle=-40,end angle=220,radius=0.6];
      \filldraw[white,line width=\d,rounded corners=2pt] (-40:0.6) rectangle ++(-0.2,-0.35);
      \filldraw[white,line width=\d,rounded corners=2pt] (220:0.6) rectangle ++(0.2,-0.35);
      \end{scope}
    \end{tikzpicture}
  \end{lrbox}
  \draw[help lines,] (-2, -2) grid[step={(1,1)}] (2, 2);
  \node[draw] (A) at (0,-2){A};

  \path (A) ++(2,2) pic (B) {headphone};

  \node [inner sep=0pt] (C) at (-2,0) {\usebox\myheadphone};

  \draw[->] (A) -- (B-outline);
  \draw[->] (A) -- (C);
\end{tikzpicture}
\end{document}

这是一个可扩展的版本,其中可以将 scale 参数作为参数添加pic,例如\pic {headphone=2};使其大小增加一倍。

\documentclass[border=1pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\definecolor{bakcolor}{RGB}{220,150,100}

\tikzset{
  pics/headphone/.style={
    code={
      \def\d{5pt}
      \node[draw=none,fill=bakcolor,minimum size=2cm*#1,circle] (-outline) at (0,0){};
      \begin{scope}[yshift=\d/2*#1]
      \draw[draw=white,line width=\d*#1,line cap=round] (-40:0.6*#1) arc[start angle=-40,end angle=220,radius=0.6*#1];
      \filldraw[white,line width=\d*#1,rounded corners=2pt] (-40:0.6*#1) rectangle ++(-0.2,-0.35*#1);
      \filldraw[white,line width=\d*#1,rounded corners=2pt] (220:0.6*#1) rectangle ++(0.2,-0.35*#1);
      \end{scope}
 }},
 pics/headphone/.default=1,
}

\begin{document}
\begin{tikzpicture}
  \pic {headphone};
  \pic at (3,0) {headphone=2};
\end{tikzpicture}
\end{document}

答案2

我不明白你为什么期望最低限度size 选项会使(非常漂亮的)图片变小。您可以使用该 scale选项将其设置为任意大小。例如

\documentclass[border=1pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
  \definecolor{bakcolor}{RGB}{220,150,100}
  \newsavebox\myheadphone
  \begin{lrbox}{\myheadphone}
    \begin{tikzpicture}
      \def\d{5pt}
      \draw[draw=none,fill={rgb,255:red,220; green,150; blue,100}] (0,0) circle (1);
      \draw[draw=white,line width=\d,line cap=round] (-40:1) arc (-40:220:1);
      \draw[draw=white,fill=white,line width=\d,rounded corners=2pt] (-40:1) rectangle ++(-0.3,-0.6);
      \draw[draw=white,fill=white,line width=\d,rounded corners=2pt] (220:1) rectangle ++(0.3,-0.6);
    \end{tikzpicture}
  \end{lrbox}
  \draw[help lines,] (-2, -2) grid[step={(1,1)}] (2, 2);
  \node[draw] (A) {A};
  \node[circle,fill=bakcolor,right=1cm of A,scale=0.4] (B) {\usebox\myheadphone};
  \draw[->] (A) -- (B);
\end{tikzpicture}
\end{document}

产量

在此处输入图片描述

编辑:评论之后,我相信你更好地理解了你的问题。如果你想要一个固定的大小,你可能想偷这个不错的宏。完整代码如下

\documentclass[border=1pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usepackage{environ}
\makeatletter
\newsavebox{\measure@tikzpicture}
\NewEnviron{scaletikzpicturetowidth}[1]{%
  \def\tikz@width{#1}%
  \def\tikzscale{1}\begin{lrbox}{\measure@tikzpicture}%
  \BODY
  \end{lrbox}%
  \pgfmathparse{#1/\wd\measure@tikzpicture}%
  \edef\tikzscale{\pgfmathresult}%
  \BODY
}
\makeatother
\begin{document}
\begin{tikzpicture}
  \definecolor{bakcolor}{RGB}{220,150,100}
  \newsavebox\myheadphone
  \begin{lrbox}{\myheadphone}
    \begin{scaletikzpicturetowidth}{1cm}
    \begin{tikzpicture}[scale=\tikzscale]
      \def\d{5pt}
      \draw[draw=none,fill={rgb,255:red,220; green,150; blue,100}] (0,0) circle (1);
      \draw[draw=white,line width=\d,line cap=round] (-40:1) arc (-40:220:1);
      \draw[draw=white,fill=white,line width=\d,rounded corners=2pt] (-40:1) rectangle ++(-0.3,-0.6);
      \draw[draw=white,fill=white,line width=\d,rounded corners=2pt] (220:1) rectangle ++(0.3,-0.6);
    \end{tikzpicture}
    \end{scaletikzpicturetowidth}
  \end{lrbox}
  \draw[help lines,] (-2, -2) grid[step={(1,1)}] (2, 2);
  \node[draw] (A) {A};
  \node[circle,fill=bakcolor,right=1cm of A] (B) {\usebox\myheadphone};
  \draw[->] (A) -- (B);
\end{tikzpicture}
\end{document}

我遇到的问题是,您的精美耳机代码涉及一些绝对(或明确)长度(例如 5pt)。因此,这种缩放图片的方法并不总是能产生良好的效果。

相关内容