我想在 TikZcircuit
库中使用自定义逻辑符号。例如 7400 系列的一些符号。轻松创建无法与circuit
库一起使用的不同符号的最佳方法是什么?
这里是 74hc238 的一个示例:
答案1
代码
\documentclass[tikz]{standalone}
\usetikzlibrary{circuits.ee.IEC}
\makeatletter
\let\pgfutil@Alph\@Alph % should be the proper definition for use outside of LaTeX
\let\pgfutil@alph\@alph % dito
\pgfmathdeclarefunction{Alph}{1}{%
\begingroup\edef\pgfmathresult{\pgfutil@Alph{#1}}%
\pgfmath@smuggleone\pgfmathresult\endgroup}
\pgfmathdeclarefunction{alph}{1}{%
\begingroup\edef\pgfmathresult{\pgfutil@alph{#1}}%
\pgfmath@smuggleone\pgfmathresult\endgroup}
\pgfdeclareshape{gLogic}{%
\savedmacro\gLogicparameters{%
\pgfmathtruncatemacro\eports{\pgfkeysvalueof{/pgf/gLogic east ports}}%
\pgfmathtruncatemacro\wports{\pgfkeysvalueof{/pgf/gLogic west ports}}%
\pgfmathtruncatemacro\nports{\pgfkeysvalueof{/pgf/gLogic north ports}}%
\pgfmathtruncatemacro\sports{\pgfkeysvalueof{/pgf/gLogic south ports}}%
\addtosavedmacro\eports \addtosavedmacro\wports
\addtosavedmacro\nports \addtosavedmacro\sports
\let\pgf@gLogic@i\relax
\let\pgf@gLogic@n\relax
\edef\efunction{\pgfkeysvalueof{/pgf/@gLogic east function/.@cmd}{\pgf@gLogic@i}{\pgf@gLogic@n}\pgfeov}
\edef\wfunction{\pgfkeysvalueof{/pgf/@gLogic west function/.@cmd}{\pgf@gLogic@i}{\pgf@gLogic@n}\pgfeov}
\edef\nfunction{\pgfkeysvalueof{/pgf/@gLogic north function/.@cmd}{\pgf@gLogic@i}{\pgf@gLogic@n}\pgfeov}
\edef\sfunction{\pgfkeysvalueof{/pgf/@gLogic south function/.@cmd}{\pgf@gLogic@i}{\pgf@gLogic@n}\pgfeov}
\addtosavedmacro\efunction \addtosavedmacro\wfunction
\addtosavedmacro\nfunction \addtosavedmacro\sfunction
}
\saveddimen\pinlength{\pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/gLogic pin length}}}%
\inheritsavedanchors[from=rectangle ee]
\inheritanchor[from=rectangle ee]{center}
\inheritanchor[from=rectangle ee]{north}
\inheritanchor[from=rectangle ee]{south}
\inheritanchor[from=rectangle ee]{east}
\inheritanchor[from=rectangle ee]{west}
\inheritanchor[from=rectangle ee]{north east}
\inheritanchor[from=rectangle ee]{north west}
\inheritanchor[from=rectangle ee]{south east}
\inheritanchor[from=rectangle ee]{south west}
\inheritanchor[from=rectangle ee]{input} % eh?
\inheritanchor[from=rectangle ee]{output}% eh?
\inheritanchorborder[from=rectangle ee]
\inheritbackgroundpath[from=rectangle ee]
\behindbackgroundpath{%
\pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/gLogic pin length}}%
\pgfmathtruncatemacro\pgf@gLogic@t{\eports+\nports+\wports+\sports}%
\pgfextract@process\southeast{\csname pgf@anchor@gLogic@south east\endcsname}%
\pgfextract@process\northwest{\csname pgf@anchor@gLogic@north west\endcsname}%
\c@pgf@counta\eports
\let\pgf@gLogic@n\eports
\pgfmathloop\ifnum\c@pgf@counta>0
\let\pgf@gLogic@i\pgfmathcounter
\pgfextract@process\pgf@temp{\pgfpointlineattime{\efunction}{\southeast}{\northeast}}%
\pgfpathmoveto{\pgf@temp}%
\pgfpathlineto{\pgfpointadd{\pgf@temp}{\pgfqpoint{\pgfutil@tempdima}{0pt}}}%
\advance\c@pgf@counta-1
\pgftext[bottom,left,at=\pgf@temp,y=2\pgflinewidth,x=2\pgflinewidth]{\pgfkeysvalueof{/pgf/@gLogic east label/.@cmd}{\pgf@gLogic@i}{\pgf@gLogic@n}{\pgf@gLogic@t}\pgfeov}
\repeatpgfmathloop
\pgf@gLogic@makeanchors{e}{\csname pgf@anchor@gLogic@south east\endcsname}{\csname northeast\endcsname}{\noexpand\pinlength}{0pt}%
%
\c@pgf@counta\nports
\let\pgf@gLogic@n\nports
\pgfmathloop\ifnum\c@pgf@counta>0
\let\pgf@gLogic@i\pgfmathcounter
\pgfextract@process\pgf@temp{\pgfpointlineattime{\nfunction}{\northeast}{\northwest}}%
\pgfpathmoveto{\pgf@temp}%
\pgfpathlineto{\pgfpointadd{\pgf@temp}{\pgfqpoint{0pt}{\pgfutil@tempdima}}}%
\advance\c@pgf@counta-1
\pgftext[right,bottom,at=\pgf@temp,x=-2\pgflinewidth,y=2\pgflinewidth]{\pgfkeysvalueof{/pgf/@gLogic north label/.@cmd}{\pgf@gLogic@i}{\pgf@gLogic@n}{\pgf@gLogic@t}\pgfeov}
\repeatpgfmathloop
\pgf@gLogic@makeanchors{n}{\csname northeast\endcsname}{\csname pgf@anchor@gLogic@north west\endcsname}{0pt}{\noexpand\pinlength}%
%
\c@pgf@counta\wports
\let\pgf@gLogic@n\wports
\pgfmathloop\ifnum\c@pgf@counta>0
\let\pgf@gLogic@i\pgfmathcounter
\pgfextract@process\pgf@temp{\pgfpointlineattime{\wfunction}{\northwest}{\southwest}}%
\pgfpathmoveto{\pgf@temp}%
\pgfpathlineto{\pgfpointadd{\pgf@temp}{\pgfqpoint{-\pgfutil@tempdima}{0pt}}}%
\advance\c@pgf@counta-1
\pgftext[bottom,right,at=\pgf@temp,y=2\pgflinewidth,x=-2\pgflinewidth]{\pgfkeysvalueof{/pgf/@gLogic west label/.@cmd}{\pgf@gLogic@i}{\pgf@gLogic@n}{\pgf@gLogic@t}\pgfeov}
\repeatpgfmathloop
\pgf@gLogic@makeanchors{w}{\csname pgf@anchor@gLogic@north west\endcsname}{\csname southwest\endcsname}{-\noexpand\pinlength}{0pt}%
%
\c@pgf@counta\sports
\let\pgf@gLogic@n\sports
\pgfmathloop\ifnum\c@pgf@counta>0
\let\pgf@gLogic@i\pgfmathcounter
\pgfextract@process\pgf@temp{\pgfpointlineattime{\sfunction}{\southwest}{\southeast}}%
\pgfpathmoveto{\pgf@temp}%
\pgfpathlineto{\pgfpointadd{\pgf@temp}{\pgfqpoint{0pt}{-\pgfutil@tempdima}}}%
\advance\c@pgf@counta-1
\pgftext[right,top,at=\pgf@temp,x=-2\pgflinewidth,y=-2\pgflinewidth]{\pgfkeysvalueof{/pgf/@gLogic south label/.@cmd}{\pgf@gLogic@i}{\pgf@gLogic@n}{\pgf@gLogic@t}\pgfeov}%
\repeatpgfmathloop
\pgf@gLogic@makeanchors{s}{\csname southwest\endcsname}{\csname pgf@anchor@gLogic@south east\endcsname}{0pt}{-\noexpand\pinlength}%
}
}
\def\pgf@gLogic@makeanchors#1#2#3#4#5{%
\c@pgf@counta\pgf@gLogic@n
\let\pgf@gLogic@n\relax
\pgfmathloop%
\ifnum\c@pgf@counta>0\relax%
\pgfutil@ifundefined{pgf@anchor@gLogic@#1Pin\space\the\c@pgf@counta}{%
\expandafter\xdef\csname pgf@anchor@gLogic@#1Pin\space\the\c@pgf@counta\endcsname{%
\noexpand\gLogicparameters
\let\noexpand\pgf@gLogic@n\expandafter\noexpand\csname #1ports\endcsname
\edef\noexpand\pgf@gLogic@i{\the\c@pgf@counta}%
\noexpand\pgfpointadd{\noexpand\pgfpointlineattime
{\expandafter\noexpand\csname #1function\endcsname}{\expandafter\noexpand#2}{\expandafter\noexpand#3}}{\noexpand\pgfqpoint{#4}{#5}}%
}%
}{\c@pgf@counta0\relax}%
\advance\c@pgf@counta-1\relax%
\repeatpgfmathloop%
}
\makeatother
\pgfset{
gLogic east ports/.initial =2,
gLogic west ports/.initial =2,
gLogic north ports/.initial=2,
gLogic south ports/.initial=2,
gLogic ports/.style args={#1:#2:#3:#4}{
/pgf/gLogic east ports ={#1},/pgf/gLogic west ports ={#3},
/pgf/gLogic north ports={#2},/pgf/gLogic south ports={#4}},
set gLogic east function/.style ={/pgf/@gLogic east function/.code 2 args={#1}},
set gLogic west function/.style ={/pgf/@gLogic west function/.code 2 args={#1}},
set gLogic north function/.style={/pgf/@gLogic north function/.code 2 args={#1}},
set gLogic south function/.style={/pgf/@gLogic south function/.code 2 args={#1}},
set gLogic east function ={(#1)/(#2+1)}, set gLogic west function ={(#1)/(#2+1)},
set gLogic north function={(#1)/(#2+1)}, set gLogic south function={(#1)/(#2+1)},
gLogic pin length/.initial=+2\tikzcircuitssizeunit,
set gLogic west label/.style={/pgf/@gLogic west label/.code n args={3}{#1}},
set gLogic east label/.style={/pgf/@gLogic east label/.code n args={3}{#1}},
set gLogic north label/.style={/pgf/@gLogic north label/.code n args={3}{#1}},
set gLogic south label/.style={/pgf/@gLogic south label/.code n args={3}{#1}},
set gLogic east label ={\scriptsize\pgfmathprint{Alph(#1)}},%
set gLogic north label={\scriptsize\pgfmathprint{Alph(\eports+#1)}},%
set gLogic west label ={\scriptsize\pgfmathprint{Alph(\eports+\nports+#1)}},%
set gLogic south label={\scriptsize\pgfmathprint{Alph(\eports+\nports+\wports+#1)}},%
}
\tikzset{
circuit declare symbol=gLogic,
set gLogic graphic={draw, shape=gLogic, circuit symbol size=width 6 height 15, outer sep=+.5\pgflinewidth}
}
\begin{document}
\begin{tikzpicture}
\node[gLogic,
gLogic ports=8:0:6:0,
align=center,
set gLogic west function={ifthenelse(#1<4,#1,(#1+2))/9},
set gLogic east label={\scriptsize$Y_{\pgfmathprint{int(\eports-#1+1)}}$},
set gLogic west label={\scriptsize\ifnum#1<4\pgfmathprint{Alph(#1)}\else$E_{\pgfmathprint{int(#1-3)}}$\fi}] (n) {R2D2-\\Decoder};
\draw (n.ePin 1) to[bend right] (n.ePin 8);
\draw (n.wPin 1) to [bend right] (n.wPin 3);
\node[gLogic, circuit symbol size=width 4 height 8] (m) at (4,0) {};
\draw (m.ePin 1) to [bend right] (m.ePin 2);
\draw (m.wPin 1) to [bend right] (m.wPin 2);
\draw[line cap=rect] (n.ePin 2) --++ (right:.5cm) |- (m.sPin 1);
\end{tikzpicture}
\end{document}
输出
答案2
我刚刚开始创建自定义形状。结果看起来还不错:
实际上我只有很少的时间和一点 TeX 经验。无论如何我都会发布它,但要注意:有龙!只有勇敢的灵魂才能继续。任何提示和帮助都值得感激 ;)
\documentclass{article}
\usepackage{etoolbox}
\usepackage{tikz}
\usetikzlibrary{circuits.ee.IEC}
\usetikzlibrary{positioning}
\makeatletter
%TODO allow easier usage, like:
%\node[glogic={parameter=name,...}] {};
%TODO better input?
%TODO remove max values
\def\maxVPins{20}
\def\maxHPins{20}
\newcounter{pinCounter}
\def\getPinNumber#1{\csname #1Pin\Roman{pinCounter}\endcsname}
\tikzset{%
gLogic/pin spacing/.initial=3mm,
gLogic/contact length/.initial=10pt,
gLogic/horizontal pins/.initial=2,
gLogic/vertical pins/.initial=2,
gLogic/pin labels/.initial={},
gLogic/bottom text/.initial=\empty,
}
\pgfdeclareshape{gLogic}{
\savedanchor{\upperrightcorner}{
\pgf@y=.5\ht\pgfnodeparttextbox %
\pgf@x=.5\wd\pgfnodeparttextbox %
}
\anchor{text}{%
\upperrightcorner%
\pgf@x=-\pgf@x%
\pgf@y=-\pgf@y%
}
\anchor{center}{\pgfpointorigin}
\def\pinspacing{\noexpand\pgfkeysvalueof{/tikz/gLogic/pin spacing}}
\def\myWidth{\pinspacing*\noexpand\pgfkeysvalueof{/tikz/gLogic/horizontal pins}}
\def\myHight{\pinspacing*\noexpand\pgfkeysvalueof{/tikz/gLogic/vertical pins}}
%create some anchors to make the positioning library happy ;)
\edef\defineAnchors{%
\noexpand\deferredanchor{south west}{\noexpand\pgfpoint{-\myHight/2}{-\myWidth/2}}%
\noexpand\anchor{south}{\noexpand\pgfpoint{0pt}{-\myWidth/2}}%
\noexpand\anchor{south east}{\noexpand\pgfpoint{\myHight/2}{-\myWidth/2}}%
\noexpand\anchor{east}{\noexpand\pgfpoint{\myHight/2}{0pt}}%
\noexpand\anchor{north east}{\noexpand\pgfpoint{\myHight/2}{\myWidth/2}}%
\noexpand\anchor{north}{\noexpand\pgfpoint{0pt}{\myWidth/2}}%
\noexpand\anchor{north west}{\noexpand\pgfpoint{-\myHight/2}{\myWidth/2}}%
\noexpand\anchor{west}{\noexpand\pgfpoint{-\myHight/2}{0pt}}}
\defineAnchors
%TODO make this prettier...
\def\createAnchorsB{%
\noexpand\savedanchor\getPinNumber{b}{\noexpand\pgfpoint{\pinspacing * (\n-.5)-\myWidth/2}{-\myHight/2}}%
\noexpand\anchor{pinB\n}{\getPinNumber{b}}%
}
\def\createAnchorsT{%
\noexpand\savedanchor\getPinNumber{t}{\noexpand\pgfpoint{-\pinspacing * (\n-.5)+\myWidth/2}{\myHight/2}}%
\noexpand\anchor{pinT\n}{\getPinNumber{t}}%
}
\def\createAnchorsL{%
\noexpand\savedanchor\getPinNumber{l}{\noexpand\pgfpoint{-\myWidth/2}{-\pinspacing * (\n-.5)+\myHight/2}}%
\noexpand\anchor{pinL\n}{\getPinNumber{l}}%
}
\def\createAnchorsR{%
\noexpand\savedanchor\getPinNumber{r}{\noexpand\pgfpoint{\myWidth/2}{\pinspacing * (\n-.5)-\myHight/2}}%
\noexpand\anchor{pinR\n}{\getPinNumber{r}}%
}
%TODO remove max values and use the real values (some expansion problem)
\foreach \n in {1,...,\maxVPins} {
\pgfmathsetcounter{pinCounter}{\n}
\edef\expandThis{%
\createAnchorsL
\createAnchorsR
}
\expandThis
}
\foreach \n in {1,...,\maxHPins} {
\pgfmathsetcounter{pinCounter}{\n}
\edef\expandThis{%
\createAnchorsB%
\createAnchorsT
}
\expandThis
}
\foregroundpath{
\edef\myLabels{\pgfkeysvalueof{/tikz/gLogic/pin labels}}
%TODO look for a cleaner solution
\foreach \x [count=\n] in \myLabels {
\ifx \x\empty\else%don't draw connectors without label
\ifnumcomp{\n}{<}{\pgfkeysvalueof{/tikz/gLogic/horizontal pins}+1}{
%bootom row
\pgfmathsetcounter{pinCounter}{\n}
\pgfpathmoveto{\getPinNumber{b}}
\pgftext[top, right,at= \pgfpointadd{\pgfpoint{-1pt}{-1pt}}{\getPinNumber{b}}]{\scriptsize \x}
\pgfpathlineto{\pgfpointadd{\getPinNumber{b}}{\pgfpoint{0}{-\pgfkeysvalueof{/tikz/gLogic/contact length}}}}
}{\ifnumcomp{\n}{<}{\pgfkeysvalueof{/tikz/gLogic/horizontal pins}+\pgfkeysvalueof{/tikz/gLogic/vertical pins}+1}{
%right column
\pgfmathparse{\n-\pgfkeysvalueof{/tikz/gLogic/horizontal pins}};
\pgfmathsetcounter{pinCounter}{\pgfmathresult}
\pgftext[base, left,at= \pgfpointadd{\pgfpoint{2pt}{1pt}}{\getPinNumber{r}}]{\scriptsize \x}
\pgfpathmoveto{\getPinNumber{r}}
\pgfpathlineto{\pgfpointadd{\getPinNumber{r}}{\pgfpoint{\pgfkeysvalueof{/tikz/gLogic/contact length}}{0}}}
}{\ifnumcomp{\n}{<}{2*\pgfkeysvalueof{/tikz/gLogic/horizontal pins}+\pgfkeysvalueof{/tikz/gLogic/vertical pins}+1}{
%top row
\pgfmathparse{\n-\pgfkeysvalueof{/tikz/gLogic/horizontal pins}-\pgfkeysvalueof{/tikz/gLogic/vertical pins}};
\pgfmathsetcounter{pinCounter}{\pgfmathresult}
\pgftext[bottom, right, at=\pgfpointadd{\pgfpoint{-1pt}{1pt}}{\getPinNumber{t}}]{\scriptsize \x}
\pgfpathmoveto{\getPinNumber{t}}
\pgfpathlineto{\pgfpointadd{\getPinNumber{t}}{\pgfpoint{0}{\pgfkeysvalueof{/tikz/gLogic/contact length}}}}
}{\ifnumcomp{\n}{<}{2*\pgfkeysvalueof{/tikz/gLogic/horizontal pins}+2*\pgfkeysvalueof{/tikz/gLogic/vertical pins}+1}{
%left column
\pgfmathparse{\n-2*\pgfkeysvalueof{/tikz/gLogic/horizontal pins}-\pgfkeysvalueof{/tikz/gLogic/vertical pins}};
\pgfmathsetcounter{pinCounter}{\pgfmathresult}
\pgftext[base, right, at=\pgfpointadd{\pgfpoint{-2pt}{1pt}}{\getPinNumber{l}}]{\scriptsize \x}
\pgfpathmoveto{\getPinNumber{l}}
\pgfpathlineto{\pgfpointadd{\getPinNumber{l}}{\pgfpoint{-\pgfkeysvalueof{/tikz/gLogic/contact length}}{0}}}
}{}}}}\fi%closing all the ifs ;-/
}
%TODO don't define them twice with different expanding behaviours?
\def\myWidth{\pgfkeysvalueof{/tikz/gLogic/horizontal pins}%
*\pgfkeysvalueof{/tikz/gLogic/pin spacing}}
\def\myHight{\pgfkeysvalueof{/tikz/gLogic/vertical pins}%
*\pgfkeysvalueof{/tikz/gLogic/pin spacing}}
\pgftext[bottom, at=\pgfpoint{-0pt}{-\myHight/2+2pt}]{\footnotesize \pgfkeysvalueof{/tikz/gLogic/bottom text}}
% rectangle around the logic gate
\pgfpathrectanglecorners{\pgfpoint{-\myWidth/2}{-\myHight/2}}%
{\pgfpoint{\myWidth/2}{\myHight/2}}
\pgfusepath{draw}% draw all the lines :D
}
}
\makeatother
\begin{document}
\def\labels{A,B,C,D,E, F, G, H, I, J,K, L, M, N,O, P, Q, R, S, T}
\begin{tikzpicture}[circuit ee IEC]
\node[gLogic, gLogic/pin spacing=7mm, gLogic/horizontal pins=3, gLogic/pin labels={A,B,~,D,,F}] (IC1) {funny IC};
\node[gLogic, gLogic/pin spacing=5mm, gLogic/horizontal pins=4, gLogic/vertical pins=6, gLogic/pin labels=\labels, gLogic/bottom text=IC-42-42, above right=3 of IC1] (IC2) {IC};
\draw (IC1.pinR1) to [diode={light emitting, name=LED}] ($(IC1.pinR1)+(2,0)$) -| (IC2.pinB4);
\end{tikzpicture}
\end{document}