Currently, PGF does not support adding a transformation matrix to pattern, so a general rotation isn't possible.
One could (with some computational overhead) use path pictures.
However, the following shows one (admittedly very bad) way of achieving rotated patterns by hacking the system layer to include a transformation matrix for patterns and exploiting the fact that "mutable" patterns (which aren't actually mutable) are created just before they are applied depending on value of the variables supplied in the pattern definition.
\documentclass[tikz, border=5]{standalone}
\usetikzlibrary{patterns}
\makeatletter
\def\pgfsys@patternmatrix{1.0 0.0 0.0 1.0 0.0 0.0}
\def\pgfsys@declarepattern#1#2#3#4#5#6#7#8#9{%
% Start building the pattern dictionary:
\pgf@xa=#2\relax%
\pgf@ya=#3\relax%
\pgf@xb=#4\relax%
\pgf@yb=#5\relax%
\pgf@xc=#6\relax%
\pgf@yc=#7\relax%
\pgf@sys@bp@correct\pgf@xa%
\pgf@sys@bp@correct\pgf@ya%
\pgf@sys@bp@correct\pgf@xb%
\pgf@sys@bp@correct\pgf@yb%
\pgf@sys@bp@correct\pgf@xc%
\pgf@sys@bp@correct\pgf@yc%
% Now create the pattern object:
\immediate\pdfobj stream
attr
{
/Type /Pattern
/PatternType 1
/PaintType \ifnum#9=0 2 \else 1 \fi
/TilingType 1
/BBox [\pgf@sys@tonumber\pgf@xa\space\pgf@sys@tonumber\pgf@ya\space\pgf@sys@tonumber\pgf@xb\space\pgf@sys@tonumber\pgf@yb]
/XStep \pgf@sys@tonumber\pgf@xc\space
/YStep \pgf@sys@tonumber\pgf@yc\space
/Matrix [\pgfsys@patternmatrix]
/Resources << >> %<<
}
{#8}%
\pgfutil@addpdfresource@patterns{/pgfpat#1\space \the\pdflastobj\space 0 R}%
}
\def\pgf@sp{ }%
\def\pgftransformextractmatrix#1#2{%
\begingroup%
\pgftransformreset%
#2%
\xdef\pgf@tmp{\pgf@pt@aa\pgf@sp\pgf@pt@ab\pgf@sp\pgf@pt@ba\pgf@sp\pgf@pt@bb\pgf@sp\pgf@sys@tonumber\pgf@pt@x\pgf@sp\pgf@sys@tonumber\pgf@pt@y}%
\endgroup%
\let#1=\pgf@tmp}
\pgfdeclarepatternformonly[\patternangle]{rotated hatch}%
{\pgfqpoint{-.1pt}{-1.pt}}{\pgfqpoint{5pt}{5pt}}
{\pgfqpoint{5pt}{5pt}}
{
\pgfsetlinewidth{.5pt}
\pgfpathmoveto{\pgfqpoint{-.1pt}{-.1pt}}
\pgfpathlineto{\pgfqpoint{5pt}{5pt}}
\pgfpathmoveto{\pgfqpoint{5pt}{-.1pt}}
\pgfpathlineto{\pgfqpoint{-.1pt}{5pt}}
\pgfusepath{stroke}
}
\tikzset{%
pattern angle/.code={%
\pgfmathparse{#1}\let\patternangle=\pgfmathresult
\pgftransformextractmatrix\pgfsys@patternmatrix{\pgftransformrotate{\patternangle}}%
},
pattern angle=0
}
\begin{document}
\begin{tikzpicture}[x=3cm,y=3cm];
\foreach \i [count=\j from 0] in {0,7,...,105}{
\draw [pattern=rotated hatch, pattern angle=\i]
({mod(\j,4)}, {floor(\j/4)}) rectangle ++(0.75,0.75)
node [above] {$\i^\circ$};
}
\end{tikzpicture}
\end{document}
Or...
Here is an incomplete implementation of mutable patterns with transformations. It looks a bit different as I tried to translate the way the new arrows.meta
library creates arrows to a new way of defining patterns:
\pgfdeclarepattern{name=hatch,
type=uncolored,
parameters={\hatchsize, \hatchangle, \hatchlinewidth},
bottom left={x=-.1pt, y=-.1pt},
top right={x=\hatchsize+.1pt, y=\hatchsize+.1pt},
tile size={width=\hatchsize, height=\hatchsize},
transformation={rotate=\hatchangle},
code={
\pgfsetlinewidth{\hatchlinewidth}
\pgfpathmoveto{\pgfpoint{-.1pt}{-.1pt}}
\pgfpathlineto{\pgfpoint{\hatchsize+.1pt}{\hatchsize+.1pt}}
\pgfpathmoveto{\pgfpoint{-.1pt}{\hatchsize+.1pt}}
\pgfpathlineto{\pgfpoint{\hatchsize+.1pt}{-.1pt}}
\pgfusepath{stroke}
}}
The parameters
can be macros or dimensions and so on, but if dimensions or counts are used they must be prefixed with \the
. It is possible (I haven't tried it) that keys could be included using \pgfkeysvalueof{mykey}
.
It hacks both the system layer and the basic layer so you have been warned...
\documentclass[tikz, border=5]{standalone}
\usetikzlibrary{patterns}
\makeatletter
% Alternate system layer pattern definition.
% Takes 15(!) arguments
\def\pgfsys@declarepattern@alt#1#2#3#4#5#6#7{%
% Start building the pattern dictionary:
\pgf@xa=#2\relax%
\pgf@ya=#3\relax%
\pgf@xb=#4\relax%
\pgf@yb=#5\relax%
\pgf@xc=#6\relax%
\pgf@yc=#7\relax%
\pgf@sys@bp@correct\pgf@xa%
\pgf@sys@bp@correct\pgf@ya%
\pgf@sys@bp@correct\pgf@xb%
\pgf@sys@bp@correct\pgf@yb%
\pgf@sys@bp@correct\pgf@xc%
\pgf@sys@bp@correct\pgf@yc%
\pgfsys@@declarepattern@alt{#1}}
\def\pgfsys@@declarepattern@alt#1#2#3#4#5#6#7#8#9{%
\pgfutil@tempdima=#6\relax%
\pgfutil@tempdimb=#7\relax%
\pgf@sys@bp@correct\pgf@xa%
\pgf@sys@bp@correct\pgf@ya%
% Now create the pattern object:
\immediate\pdfobj stream
attr
{
/Type /Pattern
/PatternType 1
/PaintType \ifnum#9=0 2 \else 1 \fi
/TilingType 1
/BBox [\pgf@sys@tonumber\pgf@xa\space\pgf@sys@tonumber\pgf@ya\space\pgf@sys@tonumber\pgf@xb\space\pgf@sys@tonumber\pgf@yb]
/XStep \pgf@sys@tonumber\pgf@xc\space
/YStep \pgf@sys@tonumber\pgf@yc\space
/Matrix [#2\space#3\space#4\space#5\space\pgf@sys@tonumber\pgfutil@tempdima\space\pgf@sys@tonumber\pgfutil@tempdimb]
/Resources << >> %<<
}
{#8}%
\pgfutil@addpdfresource@patterns{/pgfpat#1\space \the\pdflastobj\space 0 R}%
}
% Pattern keys
\pgfkeys{/pgf/patterns/.cd,
name/.code=\edef\pgf@pat@name{#1},
type/.is choice,
type/uncolored/.code=\def\pgf@pat@type{0},
type/colored/.code=\def\pgf@pat@type{1},
parameters/.store in=\pgf@pat@parameters,
bottom left/.store in=\pgf@pat@bottomleft,
top right/.store in=\pgf@pat@topright,
tile size/.store in=\pgf@pat@tilesize,
transformation/.store in=\pgf@pat@transformation,
code/.store in=\pgf@pat@code,
name=,
type=uncolored,
parameters=,
bottom left=,
top right=,
transformation=,
code=,
points/.style={/pgf/patterns/points/.cd, #1},
transformations/.style={/pgf/patterns/transformations/.cd,#1},
/pgf/patterns/points/.cd,
x/.store in=\pgf@pat@x,
y/.store in=\pgf@pat@y,
width/.store in=\pgf@pat@x,
height/.store in=\pgf@path@y,
/pgf/patterns/transformations/.cd,
rotate/.code=\pgftransformrotate{#1},
xscale/.code=\pgftransformxscale{#1},
yscale/.code=\pgftransformyscale{#1},
% Plus others...
}
% Points can be specified using PGF commands
% or x and y keys
\def\pgf@pat@processpoint#1{%
\def\pgf@marshal{\pgfutil@in@=}%
\expandafter\pgf@marshal\expandafter{#1}%
\ifpgfutil@in@%
\pgfkeys{/pgf/patterns/points/.expanded=#1}%
\pgf@process{\pgfpoint{\pgf@pat@x}{\pgf@pat@y}}%
\else%
\pgf@process{#1}%
\fi%
}
% Transformations can be specified using PGF commands
% or keys (currently only rotate, xscale and yscale)
\def\pgf@pat@processtransformations#1{%
\def\pgf@marshal{\pgfutil@in@=}%
\expandafter\pgf@marshal\expandafter{#1}%
\ifpgfutil@in@%
\pgfkeys{/pgf/patterns/transformations/.expanded=#1}%
\else%
#1%
\fi%
}
% New pattern definition command
%
% #1 is a list of keys.
\def\pgfdeclarepattern#1{%
\begingroup%
\def\pgf@pat@opts{#1}%
\pgfkeys{/pgf/patterns/.cd,#1}%
\pgfutil@ifundefined{pgf@pattern@name\pgf@pat@name}{%
\ifx\pgf@pat@parameters\pgfutil@empty%
\expandafter\global\expandafter\let\csname pgf@pattern@name@\pgf@pat@name @parameters\endcsname=\pgfutil@empty%
\pgf@declarepattern%
\else%
\expandafter\global\expandafter\let\csname pgf@pattern@name@\pgf@pat@name @parameters\endcsname=\pgf@pat@parameters
\expandafter\global\expandafter\let\csname pgf@pattern@name@\pgf@pat@name\endcsname=\pgf@pat@opts%
\fi%
}{%
\pgferror{Pattern `\pgf@pat@type' already defined}%
}%
\endgroup%
}
\def\pgf@declarepattern{%
\pgfsysprotocol@getcurrentprotocol\pgf@pattern@temp%
{%
\pgfinterruptpath%
\pgfpicturetrue%
\pgf@relevantforpicturesizefalse%
\pgftransformreset%
\pgfsysprotocol@setcurrentprotocol\pgfutil@empty%
\pgfsysprotocol@bufferedtrue%
\pgfsys@beginscope%
\pgfsetarrows{-}%
\pgf@pat@code%
\pgfsys@endscope%
\pgfsysprotocol@getcurrentprotocol\pgf@pattern@code%
\global\let\pgf@pattern@code=\pgf@pattern@code%
\endpgfinterruptpath%
\pgf@pat@processpoint{\pgf@pat@bottomleft}%
\pgf@xa=\pgf@x%
\pgf@ya=\pgf@y%
\pgf@pat@processpoint{\pgf@pat@topright}%
\pgf@xb=\pgf@x%
\pgf@yb=\pgf@y%
\pgf@pat@processpoint{\pgf@pat@tilesize}%
\pgf@xc=\pgf@x%
\pgf@yc=\pgf@y%
\begingroup%
\pgftransformreset%
\pgf@pat@processtransformations\pgf@pat@transformation%
\pgfgettransformentries\aa\ab\ba\bb\shiftx\shifty%
\global\edef\pgf@pattern@matrix{{\aa}{\ab}{\ba}{\bb}{\shiftx}{\shifty}}%
\endgroup%
% Now, build a name for the pattern
\pgfutil@tempcnta=\pgf@pattern@number%
\advance\pgfutil@tempcnta by1\relax%
\xdef\pgf@pattern@number{\the\pgfutil@tempcnta}%
\expandafter\xdef\csname pgf@pattern@name@\pgf@pat@name\endcsname{\the\pgfutil@tempcnta}%
\expandafter\xdef\csname pgf@pattern@type@\pgf@pat@name\endcsname{\pgf@pat@type}%
\xdef\pgf@marshal{\noexpand\pgfsys@declarepattern@alt%
{\csname pgf@pattern@name@\pgf@pat@name\endcsname}
{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xb}{\the\pgf@yb}{\the\pgf@xc}{\the\pgf@yc}\pgf@pattern@matrix{\pgf@pattern@code}{\pgf@pat@type}}%
}%
\pgf@marshal%
\pgfsysprotocol@setcurrentprotocol\pgf@pattern@temp%
}
\def\pgfsetfillpattern#1#2{%
\pgfutil@ifundefined{pgf@pattern@name@#1}%
{%
\pgferror{Undefined pattern `#1'}%
}%
{%
% Patterns from library won't have pgf@pattern@name@#1@parameters
\pgfutil@ifundefined{pgf@pattern@name@#1@parameters}{%
\pgf@set@fillpattern{#1}{#2}%
}{%
\expandafter\ifx\csname pgf@pattern@name@#1@parameters\endcsname\pgfutil@empty%
\pgf@set@fillpattern{#1}{#2}%
\else
\edef\pgf@pat@currentparameters{\csname pgf@pattern@name@#1@parameters\endcsname}%
\edef\pgf@pat@mutablename{#1@\pgf@pat@currentparameters}%
\pgfutil@ifundefined{pgf@pattern@name@\pgf@pat@mutablename}%
{%
\expandafter\expandafter\expandafter\pgfdeclarepattern\expandafter\expandafter\expandafter{\csname pgf@pattern@name@#1\endcsname,
name=\pgf@pat@mutablename,parameters=}%
}%
{}%
\expandafter\pgf@set@fillpattern\expandafter{\pgf@pat@mutablename}{#2}%
\fi%
}%
}%
}
\def\pgf@set@fillpattern#1#2{%
% Pattern types are 0 (uncolored) or 1 (colored)
\ifcase\csname pgf@pattern@type@#1\endcsname\relax%
\pgfutil@colorlet{pgf@tempcolor}{#2}%
\pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgf@tempcolor}}%
\pgfutil@extractcolorspec{pgf@tempcolor}{\pgf@tempcolor}%
\expandafter\pgfutil@convertcolorspec\pgf@tempcolor{rgb}{\pgf@rgbcolor}%
\expandafter\pgf@set@fill@patternuncolored\pgf@rgbcolor\relax{#1}%
\or
\pgfsys@setpatterncolored{\csname pgf@pattern@name@#1\endcsname}%
\else
\fi
}
\def\tikzdeclarepattern#1{%
\begingroup%
\pgfkeys{/pgf/patterns/code/.code={\def\pgf@pat@code{%
\let\tikz@transform=\relax\tikz@installcommands##1}}}
\pgfdeclarepattern{#1,type=colored}%
\endgroup%
}
\makeatother
\pgfdeclarepattern{name=hatch,
type=uncolored,
parameters={\hatchsize, \hatchangle, \hatchlinewidth},
bottom left={x=-.1pt, y=-.1pt}, % or \pgfqpoint{-.1pt}{-.1pt} will also work
top right={x=\hatchsize+.1pt, y=\hatchsize+.1pt},
tile size={width=\hatchsize, height=\hatchsize},
transformation={rotate=\hatchangle},
code={
\pgfsetlinewidth{\hatchlinewidth}
\pgfpathmoveto{\pgfpoint{-.1pt}{-.1pt}}
\pgfpathlineto{\pgfpoint{\hatchsize+.1pt}{\hatchsize+.1pt}}
\pgfpathmoveto{\pgfpoint{-.1pt}{\hatchsize+.1pt}}
\pgfpathlineto{\pgfpoint{\hatchsize+.1pt}{-.1pt}}
\pgfusepath{stroke}
}}
\tikzset{%
hatch size/.store in=\hatchsize,
hatch angle/.store in=\hatchangle,
hatch line width/.store in=\hatchlinewidth,
hatch size=5pt,
hatch angle=0pt,
hatch line width=.5pt,
}
\begin{document}
\begin{tikzpicture}
\foreach \r in {1,...,4}
\draw [pattern=hatch, pattern color=red]
(\r*3,0) rectangle ++(2,2);
\foreach \r in {1,...,4}
\draw [pattern=hatch, pattern color=green, hatch size=2pt]
(\r*3,3) rectangle ++(2,2);
\foreach \r in {1,...,4}
\draw [pattern=hatch, pattern color=blue, hatch size=10pt, hatch angle=21]
(\r*3,6) rectangle ++(2,2);
\foreach \r in {1,...,4}
\draw [pattern=hatch, pattern color=orange, hatch line width=2pt]
(\r*3,9) rectangle ++(2,2);
\end{tikzpicture}
\end{document}
In addition, it opens up the possibility of patterns being specified using TikZ (the code for \tikzdeclarepattern
is included above):
\tikzdeclarepattern{name=flower,
type=uncolored,
bottom left={x=-.1pt, y=-.1pt},
top right={x=10.1pt, y=10.1pt},
tile size={width=10pt, height=10pt},
code={
\tikzset{x=1pt,y=1pt}
\path [draw=green] (5,2.5) -- (5, 7.5);
\foreach \i in {0,60,...,300}
\path [fill=pink, shift={(5,7.5)}, rotate=-\i]
(0,0) .. controls ++(120:4) and ++(60:4) .. (0,0);
\path [fill=red] (5,7.5) circle [radius=1];
\foreach \i in {-45,45}
\path [fill=green, shift={(5,2.5)}, rotate=-\i]
(0,0) .. controls ++(120:4) and ++(60:4) .. (0,0);
}}
Which is then used in the usual way:
\tikz\draw [pattern=flower] circle [radius=1];
and produces:
You are using circuitikz
inside a node. The circuitikz
environment is nothing but a tikzpicture
environment in disguise. Using tikzpicture
inside a node
is not a good idea and it will cause odd things. You can use a box
instead. I have created \mycircuita
and \mycircuitb
boxes (with 0 and 20V) and used them inside the callout node.
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{positioning,%
shapes,shapes.callouts%
}
\usepackage{fouriernc}
\usepackage[scaled=0.83]{helvet}
\usepackage[scaled=0.82]{luximono}
\usepackage{marvosym,pifont}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
%---------------------------------------------------------------%
\usepackage[european,siunitx]{circuitikz}
\usepackage{circuitikz}
%---------------------------------------------------------------%
\newsavebox{\mycircuita}
\sbox{\mycircuita}{%
\begin{circuitikz}[sharp corners]
\draw[ultra thick, blue] plot[smooth,domain=-0.25*pi:-0.75*pi, samples=36] (0.25*pi+\x,{-1*sin(2*\x r)});
\draw[ultra thick, red] plot[smooth,domain=-0.25*pi:-0.75*pi, samples=36] (0.25*pi+\x,{+1*sin(2*\x r)});
\draw[ultra thick, red] plot[smooth,domain=-0.75*pi:-1.25*pi, samples=36] (0.25*pi+\x,{+1*sin(2*\x r)});
\draw[ultra thick, blue] plot[smooth,domain=-0.75*pi:-1.25*pi, samples=36] (0.25*pi+\x,{-1*sin(2*\x r)});
\draw (0,3) node[right] {\SI{+5}{V}}
to [R=$R_s$,o-] (0,+1) node[right] {A}
to [R=$R_k$,*-*] (0,-1) node[right] {B}
to [R=$R_s$, -o] (0,-3)
node[right] {\SI{0}{V}};
\end{circuitikz}
}
\newsavebox{\mycircuitb}
\sbox{\mycircuitb}{%
\begin{circuitikz}[sharp corners]
\draw[ultra thick, blue] plot[smooth,domain=-0.25*pi:-0.75*pi, samples=36] (0.25*pi+\x,{-1*sin(2*\x r)});
\draw[ultra thick, red] plot[smooth,domain=-0.25*pi:-0.75*pi, samples=36] (0.25*pi+\x,{+1*sin(2*\x r)});
\draw[ultra thick, red] plot[smooth,domain=-0.75*pi:-1.25*pi, samples=36] (0.25*pi+\x,{+1*sin(2*\x r)});
\draw[ultra thick, blue] plot[smooth,domain=-0.75*pi:-1.25*pi, samples=36] (0.25*pi+\x,{-1*sin(2*\x r)});
\draw (0,3) node[right] {\SI{+5}{V}}
to [R=$R_s$,o-] (0,+1) node[right] {A}
to [R=$R_k$,*-*] (0,-1) node[right] {B}
to [R=$R_s$, -o] (0,-3)
node[right] {\SI{20}{V}};
\end{circuitikz}
}
\begin{document}
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (4,0);
\draw (1,-0.1) -- (1,0.1);
\draw (2,-0.1) -- (2,0.1);
\draw (3,-0.1) -- (3,0.1);
\draw[ultra thick,*-*] (a) -- (b);
\node[shape=rectangle callout,
draw, rounded corners,
callout pointer width=3.3 mm,
callout pointer shorten=-2mm,
font=\sffamily\footnotesize,
align=center,
callout absolute pointer={(b)},
scale=0.5] at ([xshift=19mm,yshift=3mm] b)
{termination circuit\\
\usebox{\mycircuita}
};
\node[shape=rectangle callout,
draw, rounded corners,
callout pointer width=3.3 mm,
callout pointer shorten=-2mm,
font=\sffamily\footnotesize,
align=center,
callout absolute pointer={(a)},
scale=0.5] at ([xshift=-19mm,yshift=3mm] a)
{termination circuit\\
\usebox{\mycircuitb}
};
\end{tikzpicture}
\end{document}
As an alternative, you could also use pic
facility of tikz
but using a box
is simpler in this case.
Best Answer
I had a go at not only duplicating the style but also simplifying the code for increased ease of consistency/reusability.
I defined three
style
s:transition
,state
, andstatecolor
.transition
is to be used for connecting arrows, andstate
for plain states such asE
in this diagram.statecolor
inherits all settings from thestate
style, but addsfill
anddraw
colors based on an argument passed into the style key like so:statecolor=red
.>=stealth
setsstealth
arrow tips globally.node distance=2, on grid
sets thepositioning
library up for nodes2cm
apart, center-to-center.I converted each positioned
node
to use the preferred=of
syntax for use with thepositioning
library. I also added thecalc
library to negate the need for the temporary coordinates on the node edges. If many states have multiple transitions, it may be convenient to add additional anchors to the shape, as described in Add more anchors to standard Tikz nodes.The complete revised code: