2

I have defined a biopole device called galvanometer, which is rotation corrected. It means it displays a circled 'G' letter which is always readable, no matter in which orientation the device is drawn.

I want this code to generate myammeter (which will print 'A') or myvoltmeter (which will print 'V'). However I want to reuse the same code as a template and issue directives like \newcircleddevice{myvoltmeter}{V} or \newcircleddevice{myammmeter}{A} instead of simply copy-pasting the code and changing 'G' to 'V' or 'A' (I am currently using this approach).

Just the simple definition using \newcommand doesn't work. How do I achieve a templatized definition?

This is my MWE. This is a perfectly compilable code.

\documentclass[tikz]{standalone}
\usepackage[siunitx]{circuitikz}

% rotation corrected galvanometer
\ctikzset{bipoles/galvanometer/height/.initial=.60}
\ctikzset{bipoles/galvanometer/width/.initial=.60}
\makeatletter
\def\pgf@circ@galvanometer@path#1{\pgf@circ@bipole@path{galvanometer}{#1}}
\tikzset{galvanometer/.style = {\circuitikzbasekey, /tikz/to
        path=\pgf@circ@galvanometer@path}}
\pgfcircdeclarebipole{}{\ctikzvalof{bipoles/voltmeter/height}}{galvanometer}
{\ctikzvalof{bipoles/galvanometer/height}}{\ctikzvalof{bipoles/galvanometer/width}}
{
    \pgfpathmoveto{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@zero}}
    \pgfpointorigin   \pgf@circ@res@other =  \pgf@x
    \advance \pgf@circ@res@other by -\pgf@circ@res@up
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@zero}}
    \pgfusepath{draw}
    \pgfgetlastxy{\tempx}{\tempy}
    \pgfsetlinewidth{\pgfkeysvalueof{/tikz/circuitikz/bipoles/thickness}
        \pgfstartlinewidth}
    \pgfscope
    \pgfpathcircle{\pgfpointorigin}{\pgf@circ@res@up}
    \pgfusepath{draw}
    \endpgfscope
    \pgfsetlinewidth{\pgfstartlinewidth}
    \pgfgetlastxy{\XCoord}{\YCoord}
    \ifdim \XCoord < \tempx
        \ifdim \YCoord < \tempy
            \def\pgf@circ@temp{UP} % these are debgging variables
            \pgftransformrotate{180}
        \else
            \def\pgf@circ@temp{RIGHT}
            \pgftransformrotate{-90}
        \fi
    \else
        \ifdim \YCoord < \tempy
            \def\pgf@circ@temp{LEFT}
            \pgftransformrotate{90}
        \else
            \def\pgf@circ@temp{DOWN}
            %\pgftransformrotate{90}
        \fi
    \fi
    %\pgfnode{circle}{center}{\textbf{G}\pgf@circ@temp}{}{}% for testing
    \pgfnode{circle}{center}{\textbf{G}}{}{}
}
\makeatother


\begin{document}

    \begin{circuitikz}
        \draw (0,0) to[galvanometer] ++(5,0) to[galvanometer] ++(0,5) to[galvanometer] ++(-5,0) to[galvanometer] ++(0,-5);
        \draw (2.5,0.5) node[above] {A};
        \draw (7,0) to[galvanometer] ++(5,0) to[galvanometer] ++(0,5) to[galvanometer] ++(-5,0) to[galvanometer] ++(0,-5);
        \draw (7.5,2.5) node[right] {B};
        \draw (0,-7) to[galvanometer] ++(5,0) to[galvanometer] ++(0,5) to[galvanometer] ++(-5,0) to[galvanometer] ++(0,-5);
        \draw (7,-7) to[galvanometer] ++(5,0) to[galvanometer] ++(0,5) to[galvanometer] ++(-5,0) to[galvanometer] ++(0,-5);
        \draw (7,-20) to[galvanometer] ++(10,0) to[galvanometer] ++(0,10) to[galvanometer] ++(-10,0) to[galvanometer] ++(0,-10);
        %\draw (17,30) to[galvanometer] ++(5,0) to[galvanometer] ++(0,5) to[galvanometer] ++(-5,0) to[galvanometer] ++(0,-5);
    \end{circuitikz}
\end{document}

enter image description here

magguu
  • 917
  • 4
  • 10

1 Answers1

2

Since around version 0.9.1 you have a generic rotation-invariant instrument rmeter; I can't see why you can't use it directly... :

\documentclass[border=10pt]{standalone}
\usepackage[siunitx, RPvoltages]{circuitikz}
\begin{document}
\begin{circuitikz}[
    galvanometer/.style={rmeter, t=G},
    ammeter/.style={rmeter, t=A},
    ]
   \draw (0,0) to[galvanometer] ++(5,0) to[galvanometer] ++(0,5) to[galvanometer] ++(-5,0) to[galvanometer] ++(0,-5);
   \draw (7,0) to[ammeter] ++(5,0) to[ammeter] ++(0,5) to[ammeter] ++(-5,0) to[ammeter] ++(0,-5);
\end{circuitikz}
\end{document}

enter image description here

...or with a metering arrow, changing the styles with

    galvanometer/.style={rmeterwa, t=G},
    ammeter/.style={rmeterwa, t=A},

enter image description here

Anyway, one solution for your code could be to use a key (like I do here); do something like

\ctikzset{myletter/.initial=G}

and then use \ctikzvalof{myletter} in your code instead of the plain "G"; when you want to change it you can use

    to[galvanometer, /circuitikz/myletter=A]

...or create a style.

Rmano
  • 40,848
  • 3
  • 64
  • 125
  • I didn't know this. My version is 0.8.5. I am afraid of updating my texlive lest it breaks my code. Thanks for this info. I will see how best i can update. – magguu Apr 19 '20 at 02:11
  • 1
    0.8.5 does not exist... I suppose you have 0.8.3, which was in TeXLive 2017. I tried hard not to break backward compatibility, but circuitikz changed a lot since then. You can look at https://tex.stackexchange.com/questions/524328/i-need-to-use-a-different-version-of-circuitikz-how-can-i-do-that, there is a (hackish but safe) way to test newer versions. – Rmano Apr 19 '20 at 08:35
  • Yes you are right. It is 0.8.3. i am very much dependent on circuitikz (and in general on latex) ... so many of my documents might fail to compile if i update recklessly. I usually save only the source code, not compiled PDF. but i will find a way to update without using any hacks. – magguu Apr 19 '20 at 12:54