在 TikZ 中使用节点重用电路代码

在 TikZ 中使用节点重用电路代码

我是 TikZ/PGF 的新手(大约一周),但很喜欢它。到目前为止,我已经成功地制作了图形,但对于在单个图形中包含子电路的多个副本的最佳实践有一个疑问。并且以一种允许与子电路的输入/输出节点进行简单连接的方式进行。

作为一个非常基本的例子(请原谅自由绘画),其中我有一个带有两个重复子电路(包含在一个矩形内)的绘画。

手绘电路

因此,在此示例中,我想定义一次放大器电路,然后将其放置在图中两次,并将电线连接到其输入和输出节点。这是否需要我开发一个库,或者是否可以将子电路直接写入 .tex 文件然后重复使用?

我确实看到了关于使用 \newsavebox 的帖子这里,但我不确定如何使用该方法访问电路中的节点。

任何帮助都非常感谢。非常感谢。

\documentclass{article}
\usepackage{tikz}

\usetikzlibrary{circuits.logic.US,circuits.ee.IEC,positioning,fit}

\begin{document}
\begin{tikzpicture}[circuit ee IEC,circuit logic US,x=3cm,y=2cm,semithick,
    set resistor graphic=var resistor IEC graphic]

  % Box on the left (non circuit stuff)                                     
  \draw (0,0) rectangle (2,2);
  \draw (1,1) rectangle (1.8,1.8);
  \draw (0.3,0.2) rectangle (0.5,0.5);

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                        
  % Begin the sub-circuit to be replicated                                  
  \node[contact] (A) at (2.5,0) {};
  \node[contact] [right=1.5cm of A] (B) {};
  \node[contact] [above=1.5cm of B] (C) {};
  \node[contact] [right=1.0cm of B] (D) {};
  \node[contact] [right=1.5cm of D] (E) {};
  \node[buffer gate] [right=0.1 of D] (amp) {};
  % Problem #1:  there is whitespace between the amp output and the line to node E
  \draw (A) to [resistor] (B) (B) to [capacitor] (D) (D) to (amp) (amp) to (E);
  \draw (B) to [resistor] (C);
  % Problem #2: had to tune 0.54 to get vertical line to node E.  (output of amp)
  % Must be a better way ...
  \draw (D) -- ++(0,0.5) to [capacitor] ++(right:0.54) to (E);
  \tikzset{black box/.style={draw=black, rectangle}};
  \node(preampbox) [black box, fit=(A) (C) (E) (amp), inner sep=0.4cm] {};
  %%%%%%%%%%%%%%  end subcircuit  %%%%%%%%%%%%%%%%%%                        

\end{tikzpicture}
\end{document}

代码输出

答案1

绘制节点仅会产生外部矩形,但它用于定义所有内部坐标和接触锚点。 \drawMyamp 负责内部电路。按照传统,原点与所有接触锚点对齐。

\documentclass{article}
\usepackage{tikz}

\usetikzlibrary{circuits.logic.US,circuits.ee.IEC,positioning,fit}

\newcommand{\UseGlobalScale}
 {\pgfgettransformentries{\xscale}{\@tempa}{\@tempa}{\yscale}{\@tempa}{\@tempa}}

\let\xscale=*
\let\yscale=*

% ***************************** myamp node *********************************
% contact anchor points: left, above, out
% internal anchor points: A, B, C, D, E, F, G

\pgfdeclareshape{myamp}{

\savedmacro{\resize}{   % restore global scale factor
 \if*\xscale \relax \else \pgftransformxscale{\xscale} \fi
 \if*\yscale \relax \else \pgftransformyscale{\yscale} \fi
}

\anchor{center}{\pgfpointorigin}    % within the node, (0,0) is the center

\anchor{text} % this is required to center text in the node (not used here)
 {\pgfpoint{-.5\wd\pgfnodeparttextbox}{-.5\ht\pgfnodeparttextbox}}

\anchor{left}{\pgfpoint{-2cm}{0cm}}
\anchor{above}{\pgfpoint{0cm}{2cm}}
\anchor{out}{\pgfpoint{3cm}{0cm}}

\anchor{A}{\pgfpoint{-1.5cm}{0cm}}
\anchor{B}{\pgfpointorigin}
\anchor{C}{\pgfpoint{0cm}{1.5cm}}
\anchor{D}{\pgfpoint{1cm}{0cm}}
\anchor{E}{\pgfpoint{2.5cm}{0cm}}
\anchor{F}{\pgfpoint{1cm}{1cm}}
\anchor{G}{\pgfpoint{2.5cm}{1cm}}

\foregroundpath{ % draw border 
 \pgfpathrectanglecorners{\pgfpoint{-1.75cm}{-1cm}}{\pgfpoint{2.75cm}{1.75cm}}
 \pgfusepath{draw}}
}

%************************ draw myamp components ****************************
% component names = #1 R1, #1 R2, #1 C1, #1 C2 and #1 opamp

\newcommand{\drawMyamp}[2]{ % #1 = node name, #2 = rotation angle
 \draw 
  node[contact] at(#1.A){}
  node[contact] at(#1.B){}
  node[contact] at(#1.C){}
  node[contact] at(#1.D){}
  node[contact] at(#1.E){}
  node[resistor,rotate=#2](#1 R1) at($(#1.A)!.5!(#1.B)$){}
  node[resistor,rotate={90+#2}](#1 R2) at($(#1.B)!.5!(#1.C)$){}
  node[capacitor,rotate=#2](#1 C1) at($(#1.B)!.5!(#1.D)$){}
  node[capacitor,rotate=#2](#1 C2) at($(#1.F)!.5!(#1.G)$){}
  node[buffer gate,rotate=#2](#1 opamp) at($(#1.D)!.5!(#1.E)$){};
 \draw[thin]
  (#1.left) -- (#1.A) -- (#1 R1.west)
  (#1 R1.east) -- (#1.B) -- (#1 R2.west)
  (#1 R2.east) -- (#1.C) -- (#1.above)
  (#1.B) -- (#1 C1.west)
  (#1 C1.east) -- (#1.D) -- (#1 opamp.west)
  (#1.D) -- (#1.F) -- (#1 C2.west)
  (#1 C2.east) -- (#1.G) -- (#1.E) -- (#1 opamp.east)
  (#1.E) -- (#1.out);
}

%*************************************************************************

\begin{document}

\begin{tikzpicture}[circuit ee IEC,circuit logic US,x=3cm,y=2cm,semithick,
 set resistor graphic=var resistor IEC graphic]

\UseGlobalScale % save scale factor for myamp

% Box on the left (non circuit stuff)                                     
  \draw (0,0) rectangle (2,2);
  \draw (1,1) rectangle (1.8,1.8);
  \draw (0.3,0.2) rectangle (0.5,0.5);

 \draw (3,0) node[myamp,thick,dashed](amp1){};
 \drawMyamp{amp1}{0}

 \draw (3.1,2) node[myamp,color=red,rotate=90](amp2){};
 \drawMyamp{amp2}{90}

 \draw (amp1 R1.south) node[below]{$100 K\Omega$};
\end{tikzpicture}

\end{document}

有两种方法可以给组件添加标签。你可以给宏添加很多参数,也可以在锚点处的节点中放置标签。

答案2

好吧,您可以将所有的\nodes 和路径打包到一个宏中并重新使用它。

但是使用 TikZ,您可以保存整个路径(您可以在一条路径上完成所有操作)并在以后重新使用。接触的起点(A)是路径上的当前坐标。

代替

(D) edge[to path={-- ++ (up:.5) to[capacitor] ([shift=(up:.5)] E) -- (E)}] (E)

你也可以

(D) edge[to path={-- ++ (up:.5) coordinate (aux) to[capacitor] (aux -| E) -- (E)}] (E)

(顺便说一下,(E)该选项之后的终极目标被忽略了。)edge

代码

\documentclass[tikz]{standalone}
\usetikzlibrary{circuits.logic.US,circuits.ee.IEC,positioning,fit}
\tikzset{
  saveuse path/.code 2 args={%
    \pgfkeysalso{#1/.estyle={/tikz/insert path={#2}}}%
    \global\expandafter\let\csname pgfk@\pgfkeyscurrentpath/.@cmd\expandafter\endcsname % not optimal as it is now global through out the document
                           \csname pgfk@\pgfkeyscurrentpath/.@cmd\endcsname
    \pgfkeysalso{#1}}}
\begin{document}
\begin{tikzpicture}[
  circuit ee IEC,
  circuit logic US,
  x=3cm, y=2cm, semithick,
  set resistor graphic=var resistor IEC graphic
]
  \path (2.5,0)
    [saveuse path={subcirc}{{
      [nodes=contact, node distance=1.5cm]
      node                 (A) {}
      node[right=    of A] (B) {}
      node[above=    of B] (C) {}
      node[right=1cm of B] (D) {}
      node[right=    of D] (E) {} }
    (D)   edge[buffer gate={name=amp}] (E)
    (A)   edge [resistor]  (B)
    (B)   edge [capacitor] (D)
    (B)   edge [resistor]  (C)
    (D) edge[to path={-- ++ (up:.5) to[capacitor] ([shift=(up:.5)] E) -- (E)}] (E)
    node[draw=black, rectangle, fit=(A)(C)(E)(amp.south west)] (box) {}}]
    (A) [late options={alias=A'}]
    (2.5,2) [subcirc]
    (A) [late options={alias=A''}]
  ;

  \draw (A') to[bend left=90] (A'');
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

相关内容