pgf、tikz、circuitikz:定义一个新组件

pgf、tikz、circuitikz:定义一个新组件

我正在尝试创建一个新组件以与 circuitikz 包一起使用。我是 pgf 的新手,所以我不掌握新组件的创建。我需要构建一个通用四极子(我经常在我的课程中使用它),所以我找到了一个现成的模板这里

\documentclass{standalone}
\usepackage{circuitikz}

\makeatletter
% ************************** blackbox *****************************
\ctikzset{quadpoles/blackbox/.is family}
\ctikzset{quadpoles/blackbox/height/.initial=.5}
\ctikzset{quadpoles/blackbox/width/.initial=.5}
\ctikzset{quadpoles/blackbox/sep/.initial=2pt}
\ctikzset{quadpoles/blackbox/lead/.initial=.5}

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

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

\savedmacro{\resize}{\pgf@circ@res@temp=\ctikzvalof{bipoles/length}% scale
  \pgf@circ@res@temp=0.5\pgf@circ@res@temp
  \pgf@circ@res@right=\ctikzvalof{quadpoles/blackbox/width}\pgf@circ@res@temp
  \pgf@circ@res@step=0.5\wd\pgfnodeparttextbox
  \advance\pgf@circ@res@step by \ctikzvalof{quadpoles/blackbox/sep}%
  \ifdim\pgf@circ@res@right<\pgf@circ@res@step \pgf@circ@res@right=\pgf@circ@res@step\fi
  \pgf@circ@res@left=-\pgf@circ@res@right
  \pgf@circ@res@up=\ctikzvalof{quadpoles/blackbox/height}\pgf@circ@res@temp
  \pgf@circ@res@step=0.5\ht\pgfnodeparttextbox
  \advance\pgf@circ@res@step by \ctikzvalof{quadpoles/blackbox/sep}%
  \ifdim\pgf@circ@res@up<\pgf@circ@res@step \pgf@circ@res@up=\pgf@circ@res@step\fi
  \pgf@circ@res@down=-\pgf@circ@res@up
  \pgfstartlinewidth=\pgflinewidth% don't know why this is needed
}

\savedanchor{\northeast}{\pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@up}}
\savedanchor{\southwest}{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@down}}

\anchor{north east}{\northeast}
\anchor{south west}{\southwest}
\anchor{north}{\pgfextracty{\pgf@circ@res@up}{\northeast}\pgfpoint{0cm}{\pgf@circ@res@up}}
\anchor{north west}{\pgfextracty{\pgf@circ@res@up}{\northeast}\pgfextractx{\pgf@circ@res@left}{\southwest}\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@up}}
\anchor{west}{\pgfextractx{\pgf@circ@res@left}{\sosuthwest}\pgfpoint{\pgf@circ@res@left}{0cm}}
\anchor{south}{\pgfextracty{\pgf@circ@res@down}{\southwest}\pgfpoint{0cm}{\pgf@circ@res@down}}
\anchor{south east}{\pgfextracty{\pgf@circ@res@down}{\southwest}\pgfextractx{\pgf@circ@res@right}{\northeast}\pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@down}}
\anchor{east}{\pgfextractx{\pgf@circ@res@right}{\northeast}\pgfpoint{\pgf@circ@res@right}{0cm}}

\savedanchor{\inone}{%
  \pgf@circ@res@step=-\ctikzvalof{quadpoles/blackbox/lead}\pgf@circ@res@temp
  \advance\pgf@circ@res@step by \pgf@circ@res@left
  \pgfpoint{\pgf@circ@res@step}{0.5\pgf@circ@res@up}
}
\anchor{in1}{\inone}

\savedanchor{\intwo}{%
  \pgf@circ@res@step=-\ctikzvalof{quadpoles/blackbox/lead}\pgf@circ@res@temp
  \advance\pgf@circ@res@step by \pgf@circ@res@left
  \pgfpoint{\pgf@circ@res@step}{0.5\pgf@circ@res@down}
}
\anchor{in2}{\intwo}

\savedanchor{\outone}{%
  \pgf@circ@res@step=\ctikzvalof{quadpoles/blackbox/lead}\pgf@circ@res@temp
  \advance\pgf@circ@res@step by \pgf@circ@res@right
  \pgfpoint{\pgf@circ@res@step}{0.5\pgf@circ@res@up}
}
\anchor{out1}{\outone}

\savedanchor{\outtwo}{%
  \pgf@circ@res@step=\ctikzvalof{quadpoles/blackbox/lead}\pgf@circ@res@temp
  \advance\pgf@circ@res@step by \pgf@circ@res@right
  \pgfpoint{\pgf@circ@res@step}{0.5\pgf@circ@res@down}
}
\anchor{out2}{\outtwo}

\foregroundpath{% border and leads drawn here
  \pgfextractx{\pgf@circ@res@right}{\northeast}
  \pgfextracty{\pgf@circ@res@up}{\northeast}
    \pgfextractx{\pgf@circ@res@left}{\southwest}
    \pgfextracty{\pgf@circ@res@down}{\southwest}

  \pgfsetlinewidth{\pgfkeysvalueof{/tikz/circuitikz/bipoles/thickness}\pgfstartlinewidth}%
  \pgfpathrectanglecorners{\southwest}{\northeast}%
  \pgfusepath{draw}%
  \pgfscope
    \pgfsetlinewidth{\pgfstartlinewidth}%
    \pgfpathmoveto{\inone}%
    \pgfextracty{\pgf@circ@res@step}{\inone}%
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@step}}%
    \pgfpathmoveto{\intwo}%
    \pgfextracty{\pgf@circ@res@step}{\intwo}%
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@step}}%
    \pgfpathmoveto{\outone}%
    \pgfextracty{\pgf@circ@res@step}{\outone}%
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@step}}%
    \pgfpathmoveto{\outtwo}%
    \pgfextracty{\pgf@circ@res@step}{\outtwo}%
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@step}}%
    \pgfusepath{draw}%
  \endpgfscope
}}
\makeatother

\begin{document}
\begin{circuitikz}% or tikzpicture
\node[blackbox] (A) at (0,0) {text};
\node[blackbox,anchor=in1] (B) at (A.out1) {more text};
\end{circuitikz}
\end{document}

不幸的是,我收到了这个错误

! Missing number, treated as zero.
<to be read again> 
                   \pgfk@/tikz/circuitikz/bipoles/length 
l.103 \node[blackbox] (A) at (0,0) {text};

我尝试调试,但徒劳无功...我\ctikzvalof{bipoles/length}用手动长度(例如 1cm)替换了,但它抱怨一个未知的宏\savedanchor

相反,我尝试找到另一个可行的示例。例如,下面的代码在调用时编译良好\savedanchor

\documentclass[border=1pt]{standalone}
\usepackage{circuitikz}

\makeatletter
% ************************** multipoles *****************************

\ctikzset{multipoles/.is family}
\ctikzset{multipoles/pin spacing/.initial = 5mm} % default value
\ctikzset{multipoles/gate spacing/.initial = 1cm} % default value

\pgfkeys{/tikz/pin spacing/.initial = 0mm}
\pgfkeys{/tikz/pin spacing/.default = 0mm}

\newlength{\IClen}  % scale factor
\newcommand{\pinsize}{\ifdim\IClen<3.5mm \tiny \else \scriptsize \fi}

\newcommand{\Compass}% define anchors for compass points
{\anchor{north east}{\northeast}
\anchor{south west}{\southwest}
\anchor{north}{\pgfextracty{\pgf@circ@res@up}{\northeast}\pgfpoint{0cm}{\pgf@circ@res@up}}
\anchor{north west}{\pgfextracty{\pgf@circ@res@up}{\northeast}\pgfextractx{\pgf@circ@res@left}{\southwest}\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@up}}
\anchor{west}{\pgfextractx{\pgf@circ@res@left}{\sosuthwest}\pgfpoint{\pgf@circ@res@left}{0cm}}
\anchor{south}{\pgfextracty{\pgf@circ@res@down}{\southwest}\pgfpoint{0cm}{\pgf@circ@res@down}}
\anchor{south east}{\pgfextracty{\pgf@circ@res@down}{\southwest}\pgfextractx{\pgf@circ@res@right}{\northeast}\pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@down}}
\anchor{east}{\pgfextractx{\pgf@circ@res@right}{\northeast}\pgfpoint{\pgf@circ@res@right}{0cm}}}

% ***************************** dip 28 *********************************
\pgfdeclareshape{dip28}{
\anchor{center}{\pgfpointorigin}    % within the node, (0,0) is the center

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

\savedmacro{\resize}{   % called automatically
 \setlength{\IClen}{\pgfkeysvalueof{/tikz/pin spacing}} % from node[]
 \ifdim\IClen=0mm \setlength{\IClen}
  {\pgfkeysvalueof{/tikz/circuitikz/multipoles/pin spacing}} \fi    % from \ctikzset{}
}
\savedanchor\icpina{\pgfpoint{-6.5\IClen}{-2.5\IClen}}  % pin 1
\anchor{p1}{\icpina}
\savedanchor\icpinb{\pgfpoint{-5.5\IClen}{-2.5\IClen}}  % pin 2
\anchor{p2}{\icpinb}
\savedanchor\icpinc{\pgfpoint{-4.5\IClen}{-2.5\IClen}}  % pin 3
\anchor{p3}{\icpinc}
\savedanchor\icpind{\pgfpoint{-3.5\IClen}{-2.5\IClen}}  % pin 4
\anchor{p4}{\icpind}
\savedanchor\icpine{\pgfpoint{-2.5\IClen}{-2.5\IClen}}  % pin 5
\anchor{p5}{\icpine}
\savedanchor\icpinf{\pgfpoint{-1.5\IClen}{-2.5\IClen}}  % pin 6
\anchor{p6}{\icpinf}
\savedanchor\icping{\pgfpoint{-.5\IClen}{-2.5\IClen}}   % pin 7
\anchor{p7}{\icping}
\savedanchor\icpinh{\pgfpoint{.5\IClen}{-2.5\IClen}}    % pin 8
\anchor{p8}{\icpinh}
\savedanchor\icpini{\pgfpoint{1.5\IClen}{-2.5\IClen}}   % pin 9
\anchor{p9}{\icpini}
\savedanchor\icpinj{\pgfpoint{2.5\IClen}{-2.5\IClen}}   % pin 10
\anchor{p10}{\icpinj}
\savedanchor\icpink{\pgfpoint{3.5\IClen}{-2.5\IClen}}   % pin 11
\anchor{p11}{\icpink}
\savedanchor\icpinl{\pgfpoint{4.5\IClen}{-2.5\IClen}}   % pin 12
\anchor{p12}{\icpinl}
\savedanchor\icpinm{\pgfpoint{5.5\IClen}{-2.5\IClen}}   % pin 13
\anchor{p13}{\icpinm}
\savedanchor\icpinn{\pgfpoint{6.5\IClen}{-2.5\IClen}}   % pin 14
\anchor{p14}{\icpinn}
\savedanchor\icpino{\pgfpoint{6.5\IClen}{2.5\IClen}}    % pin 15
\anchor{p15}{\icpino}
\savedanchor\icpinp{\pgfpoint{5.5\IClen}{2.5\IClen}}    % pin 16
\anchor{p16}{\icpinp}
\savedanchor\icpinq{\pgfpoint{4.5\IClen}{2.5\IClen}}    % pin 17
\anchor{p17}{\icpinq}
\savedanchor\icpinr{\pgfpoint{3.5\IClen}{2.5\IClen}}    % pin 18
\anchor{p18}{\icpinr}
\savedanchor\icpins{\pgfpoint{2.5\IClen}{2.5\IClen}}    % pin 19
\anchor{p19}{\icpins}
\savedanchor\icpint{\pgfpoint{1.5\IClen}{2.5\IClen}}    % pin 20
\anchor{p20}{\icpint}
\savedanchor\icpinu{\pgfpoint{.5\IClen}{2.5\IClen}} % pin 21
\anchor{p21}{\icpinu}
\savedanchor\icpinv{\pgfpoint{-.5\IClen}{2.5\IClen}}    % pin 22
\anchor{p22}{\icpinv}
\savedanchor\icpinw{\pgfpoint{-1.5\IClen}{2.5\IClen}}   % pin 23
\anchor{p23}{\icpinw}
\savedanchor\icpinx{\pgfpoint{-2.5\IClen}{2.5\IClen}}   % pin 24
\anchor{p24}{\icpinx}
\savedanchor\icpiny{\pgfpoint{-3.5\IClen}{2.5\IClen}}   % pin 25
\anchor{p25}{\icpiny}
\savedanchor\icpinz{\pgfpoint{-4.5\IClen}{2.5\IClen}}   % pin 26
\anchor{p26}{\icpinz}
\savedanchor\icpinaa{\pgfpoint{-5.5\IClen}{2.5\IClen}}  % pin 27
\anchor{p27}{\icpinaa}
\savedanchor\icpinab{\pgfpoint{-6.5\IClen}{2.5\IClen}}  % pin 28
\anchor{p28}{\icpinab}

\savedanchor{\northeast}{\pgfpoint{7\IClen}{2.5\IClen}}
\savedanchor{\southwest}{\pgfpoint{-7\IClen}{-2.5\IClen}}
\Compass% standard anchors

\foregroundpath{ % border and pin numbers are drawn here
 \pgfsetlinewidth{.1\IClen} % line thickness 
 \pgfpathrectanglecorners{\southwest}{\northeast}
 \pgfusepath{draw}  %draw rectangle
 \pgfsetlinewidth{.06\IClen} % line thickness 
 \pgfpathmoveto{\pgfpoint{-7\IClen}{-.6\IClen}}
 \pgfpatharc{-90}{90}{.6\IClen}
 \pgfusepath{draw}  %draw semicircle
 \pgftext[bottom,at={\pgfpoint{-6.5\IClen}{-2.2\IClen}}]{\pinsize 1}
 \pgftext[bottom,at={\pgfpoint{-5.5\IClen}{-2.2\IClen}}]{\pinsize 2}
 \pgftext[bottom,at={\pgfpoint{-4.5\IClen}{-2.2\IClen}}]{\pinsize 3}
 \pgftext[bottom,at={\pgfpoint{-3.5\IClen}{-2.2\IClen}}]{\pinsize 4}
 \pgftext[bottom,at={\pgfpoint{-2.5\IClen}{-2.2\IClen}}]{\pinsize 5}
 \pgftext[bottom,at={\pgfpoint{-1.5\IClen}{-2.2\IClen}}]{\pinsize 6}
 \pgftext[bottom,at={\pgfpoint{-.5\IClen}{-2.2\IClen}}]{\pinsize 7}
 \pgftext[bottom,at={\pgfpoint{.5\IClen}{-2.2\IClen}}]{\pinsize 8}
 \pgftext[bottom,at={\pgfpoint{1.5\IClen}{-2.2\IClen}}]{\pinsize 9}
 \pgftext[bottom,at={\pgfpoint{2.5\IClen}{-2.2\IClen}}]{\pinsize 10}
 \pgftext[bottom,at={\pgfpoint{3.5\IClen}{-2.2\IClen}}]{\pinsize 11}
 \pgftext[bottom,at={\pgfpoint{4.5\IClen}{-2.2\IClen}}]{\pinsize 12}
 \pgftext[bottom,at={\pgfpoint{5.5\IClen}{-2.2\IClen}}]{\pinsize 13}
 \pgftext[bottom,at={\pgfpoint{6.5\IClen}{-2.2\IClen}}]{\pinsize 14}
 \pgftext[top,at={\pgfpoint{6.5\IClen}{2.2\IClen}}]{\pinsize 15}
 \pgftext[top,at={\pgfpoint{5.5\IClen}{2.2\IClen}}]{\pinsize 16}
 \pgftext[top,at={\pgfpoint{4.5\IClen}{2.2\IClen}}]{\pinsize 17}
 \pgftext[top,at={\pgfpoint{3.5\IClen}{2.2\IClen}}]{\pinsize 18}
 \pgftext[top,at={\pgfpoint{2.5\IClen}{2.2\IClen}}]{\pinsize 19}
 \pgftext[top,at={\pgfpoint{1.5\IClen}{2.2\IClen}}]{\pinsize 20}
 \pgftext[top,at={\pgfpoint{.5\IClen}{2.2\IClen}}]{\pinsize 21}
 \pgftext[top,at={\pgfpoint{-.5\IClen}{2.2\IClen}}]{\pinsize 22}
 \pgftext[top,at={\pgfpoint{-1.5\IClen}{2.2\IClen}}]{\pinsize 23}
 \pgftext[top,at={\pgfpoint{-2.5\IClen}{2.2\IClen}}]{\pinsize 24}
 \pgftext[top,at={\pgfpoint{-3.5\IClen}{2.2\IClen}}]{\pinsize 25}
 \pgftext[top,at={\pgfpoint{-4.5\IClen}{2.2\IClen}}]{\pinsize 26}
 \pgftext[top,at={\pgfpoint{-5.5\IClen}{2.2\IClen}}]{\pinsize 27}
 \pgftext[top,at={\pgfpoint{-6.5\IClen}{2.2\IClen}}]{\pinsize 28}
}}
\makeatother

\begin{document}
\begin{circuitikz}
\draw (2,3.5) node[dip28] (Q) {MCP23017};
 \draw
(Q.p1) -- +(0,-.5)
(Q.p2) -- +(0,-.5)
(Q.p3) -- +(0,-.5)
(Q.p4) -- +(0,-.5)
(Q.p5) -- +(0,-.5)
(Q.p6) -- +(0,-.5)
(Q.p7) -- +(0,-.5)
(Q.p8) -- +(0,-.5)
(Q.p9) -- +(0,-.5)
(Q.p10) -- +(0,-.5)
(Q.p11) -- +(0,-.5)
(Q.p12) -- +(0,-.5)
(Q.p13) -- +(0,-.5)
(Q.p14) -- +(0,-.5)
(Q.p15) -- +(0,.5)
(Q.p16) -- +(0,.5)
(Q.p17) -- +(0,.5)
(Q.p18) -- +(0,.5)
(Q.p19) -- +(0,.5)
(Q.p20) -- +(0,.5)
(Q.p21) -- +(0,.5)
(Q.p22) -- +(0,.5)
(Q.p23) -- +(0,.5)
(Q.p24) -- +(0,.5)
(Q.p25) -- +(0,.5)
(Q.p26) -- +(0,.5)
(Q.p27) -- +(0,.5)
(Q.p28) -- +(0,.5);
\end{circuitikz}
\end{document}


感谢您的帮助!

答案1

该错误是由于该键circuititz/bipoles/length不是正常的“值”键,而只是一个.code设置内部变量的键pgf@circ@Rlen

因此你必须替换以下行:

\pgf@circ@res@temp=\ctikzvalof{bipoles/length}

 \pgf@circ@res@temp=\pgf@circ@Rlen

错误就消失了。

答案2

您可以使用dipchipqfpchip绘制四极子。

在此处输入图片描述

\documentclass[margin=3mm]{standalone}
\usepackage{circuitikz}

\begin{document}
\begin{circuitikz}
\draw (0,0) node[dipchip,num pins=4,external pins width=0.0,no topmark,](C1){IC1};
\draw (0,-2) node[qfpchip,num pins=4,external pins width=0.0,no topmark,](C2){IC1};

\draw (C1.pin 1) to[short] ++(-1,0) |- (C2.pin 1);
\draw (C1.pin 4) to[short] ++(1,0) |- (C2.pin 3);

\end{circuitikz}
\end{document}

编辑

可以为锚点指定别名,例如input 1代替pin 1。请参阅以下问题的答案:重命名预定义形状中的锚点。您可以隐藏默认引脚编号并为这些引脚指定所需的名称。请参阅 MWE:

\documentclass[margin=3mm]{standalone}
\usepackage{circuitikz}
\makeatletter
\newcommand*\pgfdeclareanchoralias[3]{%
    \expandafter\def\csname pgf@anchor@#1@#3\expandafter\endcsname
            \expandafter{\csname pgf@anchor@#1@#2\endcsname}}
\makeatother            

\pgfdeclareanchoralias{dipchip}{pin 1}{input 1}
\pgfdeclareanchoralias{dipchip}{pin 2}{input 2}
\pgfdeclareanchoralias{dipchip}{pin 4}{output 1}
\pgfdeclareanchoralias{dipchip}{pin 3}{output 2}

\begin{document}
\begin{circuitikz}
\draw (0,0) node[dipchip,num pins=4,external pins width=0.0,no topmark,hide numbers](C1){IC1};
\draw (0,-2) node[qfpchip,num pins=4,external pins width=0.0,no topmark,](C2){IC1};

\node [right, font=\tiny] at (C1.bpin 1) {IN1};
\node [right, font=\tiny] at (C1.bpin 2) {IN2};
\node [left, font=\tiny] at (C1.bpin 4) {OUT1};
\node [left, font=\tiny] at (C1.bpin 3) {OUT2};

\draw (C1.input 1) to[short] ++(-1,0) |- (C2.pin 1);
\draw (C1.output 2) to[short] ++(1,0) |- (C2.pin 3);

\end{circuitikz}
\end{document}

在此处输入图片描述

相关内容