3

So, I'm trying to make a Saturation Block, to use in a tikz block diagram, like the following:

Saturation Block

I tried adapting this answer, but I'm not able to make the left side of the figure. I know I must use the \pgfusepath{stroke} to use different widths in the shape. This are my atempts:

\pgfdeclareshape{satnode}{
\inheritsavedanchors[from={rectangle}]
\inheritbackgroundpath[from={rectangle}]
\inheritanchorborder[from={rectangle}]
\foreach \x in {center,north east,north west,north,south,south east,south west}{
    \inheritanchor[from={rectangle}]{\x}
}
\foregroundpath{
    \pgfpointdiff{\northeast}{\southwest}
    \pgf@xa=\pgf@x \pgf@ya=\pgf@y
    \northeast
    \pgfsetnonzerorule
    \pgfsetlinewidth{0.4pt}
    \pgfpathmoveto{\pgfpoint{0}{0.45\pgf@ya}}
    \pgfpathlineto{\pgfpoint{0}{-0.45\pgf@ya}}
    \pgfpathmoveto{\pgfpoint{-0.4\pgf@xa}{0}}
    \pgfpathlineto{\pgfpoint{0\pgf@xa}{0}}
    \pgfusepath{stroke}
    \pgfsetlinewidth{1pt}
    \pgfpathmoveto{\pgfpoint{0.3\pgf@xa}{0\pgf@ya}}
    \pgfpathlineto{\pgfpoint{0\pgf@xa}{0\pgf@ya}}
    \pgfpathlineto{\pgfpointadd{\northeast}{\pgfpoint{-0.7\pgf@xa}{-0.3\pgf@ya}}}
    \pgfpathlineto{\pgfpointadd{\northeast}{\pgfpoint{-0.4\pgf@xa}{-0.3\pgf@ya}}}

    }
}

With the following result:

Fail Number one

Or, if I switch the order:

\pgfdeclareshape{satnode}{
\inheritsavedanchors[from={rectangle}]
\inheritbackgroundpath[from={rectangle}]
\inheritanchorborder[from={rectangle}]
\foreach \x in {center,north east,north west,north,south,south east,south west}{
    \inheritanchor[from={rectangle}]{\x}
}
\foregroundpath{
    \pgfpointdiff{\northeast}{\southwest}
    \pgf@xa=\pgf@x \pgf@ya=\pgf@y
    \northeast
    \pgfsetlinewidth{1pt}
    \pgfpathmoveto{\pgfpoint{0.3\pgf@xa}{0\pgf@ya}}
    \pgfpathlineto{\pgfpoint{0\pgf@xa}{0\pgf@ya}}
    \pgfpathlineto{\pgfpointadd{\northeast}{\pgfpoint{-0.7\pgf@xa}{-0.3\pgf@ya}}}
    \pgfpathlineto{\pgfpointadd{\northeast}{\pgfpoint{-0.4\pgf@xa}{-0.3\pgf@ya}}}
    \pgfusepath{stroke}
    \pgfsetlinewidth{0.4pt}
    \pgfpathmoveto{\pgfpoint{0}{0.45\pgf@ya}}
    \pgfpathlineto{\pgfpoint{0}{-0.45\pgf@ya}}
    \pgfpathmoveto{\pgfpoint{-0.4\pgf@xa}{0}}
    \pgfpathlineto{\pgfpoint{0.4\pgf@xa}{0}}
    }
}

I get the following:

Fail Number two

Edit: I am trying to use it like a node for a block diagram in tikz. This would be an example of a use case:

\node[satnode, right of=other_node,draw,minimum size=1cm] (mysatnode) {label};

2 Answers2

2

How about this?

PS: If you use it several times in your document, a pic should be used.

enter image description here

\documentclass[tikz,border=5mm]{standalone}
\begin{document}
\begin{tikzpicture}[>=latex,font=\sffamily]
\def\a{1.5} \def\b{1} 
\draw 
(.8*\a,0)--(-.8*\a,0) (0,.8*\b)--(0,-.8*\b);
\draw[thick,cyan]
(-.5*\a,0)--(0,0)--(.5*\a,.8*\b)--(.8*\a,.8*\b);
\draw[very thick] (-\a,-\b) rectangle (\a,\b);
\draw[->|] (\a,0)--+(0:.3) node[below left,scale=.5]{+};
\draw[<-] (-\a,0)--+(180:.3);
\path (0,\b) node[above,xscale=.7]{DRIVING BLOCK};
\end{tikzpicture}
\end{document}
Black Mild
  • 17,569
2

Yes, you are right, you need to use two different \pgfusepath{stroke} commands. I cannot really tell you what I changed in your code because I started from percusse's answer but I really more or less did what you describe in words. I also added two anchors that were not there in percusse's answer but are relevant for positioning.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{positioning}
\makeatletter
\pgfdeclareshape{satnode}{
\inheritsavedanchors[from={rectangle}]
\inheritbackgroundpath[from={rectangle}]
\inheritanchorborder[from={rectangle}]
\foreach \x in {center,north east,north west,north,south,south east,south
west,west,east}{
\inheritanchor[from={rectangle}]{\x}
}
\foregroundpath{
\pgfpointdiff{\northeast}{\southwest}
\pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast
\pgfpathmoveto{\pgfpoint{0}{0.45\pgf@ya}}
\pgfpathlineto{\pgfpoint{0}{-0.45\pgf@ya}}
\pgfpathmoveto{\pgfpoint{0.45\pgf@xa}{0}}
\pgfpathlineto{\pgfpoint{-0.45\pgf@xa}{0}}
\pgfusepath{stroke}
\pgfsetlinewidth{1pt}
\pgfpathmoveto{\pgfpointadd{\southwest}{\pgfpoint{-0.3\pgf@xa}{-1\pgf@ya}}}
\pgfpathlineto{\pgfpointadd{\southwest}{\pgfpoint{-\pgf@xa}{-1\pgf@ya}}}
\pgfpathlineto{\pgfpointadd{\northeast}{\pgfpoint{-0.5\pgf@xa}{-0.3\pgf@ya}}}
\pgfpathlineto{\pgfpointadd{\northeast}{\pgfpoint{-0.2\pgf@xa}{-0.3\pgf@ya}}}
\pgfusepath{stroke}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}[nodes={minimum width=2cm,minimum
    height=1cm,draw,font=\sffamily},>=latex]
\node (A){A};
\node[satnode,right=of A] (B){};
\node[right=of B] (C){C};
\draw[->] (A) -- (B);
\draw[->] (B) -- (C);
\end{tikzpicture}
\end{document}

enter image description here

P.S. I know one could use chains here but I feel this would distract from the (IMHO very nice) question about the declaration of shapes.