我是 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
好吧,您可以将所有的\node
s 和路径打包到一个宏中并重新使用它。
但是使用 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}