Tikz:创建复杂的自定义节点

Tikz:创建复杂的自定义节点

我再次来了解你们有趣的想法。

我正在尝试用我制作的绘图制作自定义节点

    \documentclass[tikz, margin=3mm]{standalone}
    \usepackage[utf8]{inputenc}
    \usepackage{pgfplots,tikz}
    \pgfplotsset{compat=1.16}
    \usetikzlibrary{calc}
    
    \tikzset{
      pics/mynodeB/.style={
         code={
            \draw[fill] (0,0.5) circle (1cm);
            \draw[line width=4pt] (0,0) circle (2.2cm) ;
            \pgfmathsetmacro{\AngleA}{52.5}
            \draw[fill] (0,-2) arc (-90:-37.8:2cm) arc (29:66.2:1.8cm) arc (-\AngleA:{-180+\AngleA}:1.2cm)  arc ({180-66.2}:{180-29}:1.8cm) arc ({-180+37.8}:-90:2cm) ;
         }
      },
        cross/.style={path picture={
            \draw[black] let
              \p1 = (path picture bounding box.south),
              \p2 = (path picture bounding box.north),
              \n1 = {veclen((\x2-\x1),(\y2-\y1))}
              in ($(path picture bounding box.south east)!0.5!(path picture bounding box.north west)$) circle (1cm);  % Change is to be made here
        }},
    }
    
    
    \begin{document}
    
      \begin{tikzpicture}
            \draw[fill] (0,0.5) circle (1cm);
            \draw[line width=4pt] (0,0) circle (2.2cm) ;
            \pgfmathsetmacro{\AngleA}{52.5}
            \draw[fill] (0,-2) arc (-90:-37.8:2cm) arc (29:66.2:1.8cm) arc (-\AngleA:{-180+\AngleA}:1.2cm)  arc ({180-66.2}:{180-29}:1.8cm) arc ({-180+37.8}:-90:2cm) ;
            
          \pic[red] at (5,0) {mynodeB};
          \node[cross,minimum size=2cm] at (10,0) {};
      \end{tikzpicture}
    
    \end{document}

它给出了这个

用户图片

第一个是我正在尝试使用的绘图。您可以看到一些奇怪的数值,因为我使用实心圆和一些裁剪/反向裁剪来绘制它,但当我尝试将其变成节点时效果不佳,所以我用圆弧来近似形状。

红色的那张是使用我定义的“pic”绘制的相同图形(我不太清楚 pic 是什么,我用了在这里找到的代码……)。问题是 pic 不是节点,我不能使用我常用的命令来操作它。

右边的圆圈基于我之前制作的一个更简单的自定义节点。我试图制作与之前相同的图形,但我不能使用固定长度(否则形状不会随节点调整大小)。你可以看到我曾尝试评估节点的cross/.style长度,但如果我将其放在何处,圆圈就会消失。\n1\n11cm

你有想法吗?

答案1

很难理解你在找什么,但我想回答一下。图片是一种节省图纸并能够重复使用它们。因此,您也可以缩放它们(就像我在紫色中所做的那样)。

一种方式姓名local bounding box=A例如,将 pic 用作节点就是为其提供参数。然后,您可以A像节点一样使用它,尤其是将另一个节点放在它旁边,就像我所做的那样(使用positioning库)。

图片作为节点

\documentclass[tikz,border=3.14mm]{standalone}
   \usetikzlibrary{positioning}
    
\tikzset{
      mypic/.pic={
            \filldraw (0,0.5) circle (1cm);
            \draw[line width=4pt] (0,0) circle (2.2cm) ;
            \pgfmathsetmacro{\AngleA}{52.5}
            \filldraw (0,-2) arc (-90:-37.8:2cm) arc (29:66.2:1.8cm) arc (-\AngleA:{-180+\AngleA}:1.2cm)  arc ({180-66.2}:{180-29}:1.8cm) arc ({-180+37.8}:-90:2cm) ;
      }
    }
   
    
\begin{document}
    
    \begin{tikzpicture}[on grid]
        \pic[red,local bounding box=A] {mypic};
        \pic[violet,scale=0.5,right=4 cm of A] {mypic};
    \end{tikzpicture}
    
\end{document}

答案2

您几乎已经完成了。您只需引入一个比例因子,这样您就可以缩放图片而无需使用密钥scale,否则如果您scale在节点上使用密钥,您可能会遇到麻烦。

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{calc}
\tikzset{
  pics/mynodeB/.style={
     code={
        \draw[fill] (0,0.5*#1) circle[radius=#1*1cm];
        \draw[line width=#1*4pt] (0,0) circle[radius=#1*2.2cm];
        \pgfmathsetmacro{\AngleA}{52.5}
        \draw[fill] (0,-2*#1) arc[start angle=-90,end angle=-37.8,radius=#1*2cm] 
         arc[start angle=29,end angle=66.2,radius=#1*1.8cm] 
         arc[start angle=-\AngleA,end angle={-180+\AngleA},radius=#1*1.2cm]  
         arc[start angle={180-66.2},end angle={180-29},radius=#1*1.8cm] 
         arc[start angle={-180+37.8},end angle=-90,radius=#1*2cm];
     }
  },pics/mynodeB/.default=1,
    cross/.style={circle,path picture={
        \path let
          \p1 = (path picture bounding box.south west),
          \p2 = (path picture bounding box.north east),
          \n1 = {scalar(veclen(\x2-\x1,\y2-\y1)/4.4cm/sqrt(2))}
          in (path picture bounding box.center)
          pic{mynodeB=\n1};
    }},
}

\begin{document}
\begin{tikzpicture}
    \draw[fill] (0,0.5) circle (1cm);
    \draw[line width=4pt] (0,0) circle (2.2cm) ;
    \pgfmathsetmacro{\AngleA}{52.5}
    \draw[fill] (0,-2) arc (-90:-37.8:2cm) arc (29:66.2:1.8cm) arc (-\AngleA:{-180+\AngleA}:1.2cm)  arc ({180-66.2}:{180-29}:1.8cm) arc ({-180+37.8}:-90:2cm) ;
    \pic[red] at (5,0) {mynodeB};
    \node[cross,minimum size=2cm] (A) at (10,0) {};
    \node[cross,minimum size=2cm,blue] (B) at (14,0) {};
    \draw[thick,orange] (A.45) to[out=45,in=-135] (B.-135);
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案3

为什么不滥用一点呢path picture?如果节点是circle具有最小尺寸的,则可以测量此尺寸并绘制与其成比例的图形。

以下代码需要进行一些调整,但它展示了这个想法

\documentclass[tikz, margin=3mm]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{calc}
    
\tikzset{
    head/.style={circle, draw, path picture={%
        \fill let \p1=($(path picture bounding box.north)-(path picture bounding box.south)$), \n1={veclen(\p1)} in ([yshift=.1*\n1]path picture bounding box.center) circle(0.22*\n1);
        \fill let \p1=($(path picture bounding box.north)-(path picture bounding box.south)$), \n1={veclen(\p1)} in 
        ([shift={(45:.25*\n1)}]path picture bounding box.-135) to[out=-45, in=-135]
        ([shift={(135:.25*\n1)}]path picture bounding box.-45) to[bend right]
        ([shift={(135:.5*\n1)}]path picture bounding box.-45) to[out=-135, in=-45]
        ([shift={(45:.5*\n1)}]path picture bounding box.-135) to[bend right] cycle
        ;
    }}
}

\begin{document}
    
\begin{tikzpicture}

\node[head, minimum size=4cm, draw, blue, line width=1mm] (a) {};

\node[head, minimum size=2cm, draw, green, line width=1mm] at (4,0) (b) {};

\node[head, minimum size=1cm, draw, red] at (4,2) (b) {};

\end{tikzpicture}
    
\end{document}

在此处输入图片描述

更新:减少代码。

以前的代码解决方案可以借助马克·维布罗的“化名”并将两个fill命令压缩为一个命令。

\documentclass[tikz, margin=3mm]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{calc}
    
\tikzset{
    alias path picture bounding box/.code=\pgfnodealias{#1}{path picture bounding box},
    head/.style={circle, draw, path picture={%
        \tikzset{alias path picture bounding box=@}
        \fill let \p1=($(@.north)-(@.south)$), \n1={veclen(\p1)} in ([yshift=.1*\n1]@.center) circle(0.22*\n1)%;
        ([shift={(45:.25*\n1)}]@.-135) to[out=-45, in=-135]
        ([shift={(135:.25*\n1)}]@.-45) to[bend right]
        ([shift={(135:.5*\n1)}]@.-45) to[out=-135, in=-45]
        ([shift={(45:.5*\n1)}]@.-135) to[bend right] cycle
        ;
    }}
}

\begin{document}
    
\begin{tikzpicture}

\node[head, minimum size=4cm, draw, blue, line width=1mm] (a) {};

\node[head, minimum size=2cm, draw, green, line width=1mm] at (4,0) (b) {};

\node[head, minimum size=1cm, draw, red] at (4,2) (b) {};

\end{tikzpicture}
    
\end{document}

相关内容