6

I have a figure where coloring should be gradient along the wires. To be precise, the coloring should be like sinusoidal function.

\documentclass[border=2mm]{standalone}

\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand\wireheight{2} % height of one segment
\newcommand\wirewidth{1}  % width of a segment
\newcommand\wiredist{0.5} % distance between wires
\pgfmathsetmacro\pairdist{2*(\wirewidth+\wiredist)} % distance between pairs of wires

% \wire[options]{name}{start}{height}{width}
\newcommand\wire[5][]%
{\draw[#1]
    (#3)            coordinate (#2-0)
    -- ++(0,#4)     coordinate (#2-1)
    -- ++(#5,0)     coordinate (#2-2)
    -- ++(0,#4)     coordinate (#2-3)
    -- ++(-#5,0)    coordinate (#2-4)
    -- ++(0,#4)     coordinate (#2-5)
    -- ++(#5,0)     coordinate (#2-6)
    -- ++(0,0.5*#4) coordinate (#2-7);
}

\begin{document}
    \begin{tikzpicture}[rounded corners,>=stealth, shorten >=1pt, shorten <=1pt]
    \foreach \i in {0,...,2}
    {
        \wire[thick,red]{G-\i}{{(\i)*\pairdist-\wiredist},0}{\wireheight}{-\wirewidth}
        \wire[thick,blue]{B-\i}{\i*\pairdist,0}{\wireheight}{\wirewidth}
    }
    \draw[<->] ($(G-1-2)!0.5!(G-1-3)$) -- +(-0.5,0) node[midway,above]{$\kappa_{2}$};
    \draw[<->] ($(G-1-2)!-0.5!(G-2-3)$) -- +(-0.5,0) node[midway, above]{$\kappa_{1}$};
    \end{tikzpicture}
\end{document}

I would like a gradient coloring for both blue and red. Like it is zero at the bottom and then it increases along the wires and after one period comes to the initial value and likewise. Just to show what I mean. This is one period. enter image description here I just tried to show the intensity of the color from the thickness of the wire(didn't have anything else to show)

  • Would you also be interested in a solution based on pgfplots? I guess there it would be rather straightforward to achieve this with point meta. – user121799 Jul 8 '18 at 17:20
  • One more thing: here is a way to change the stroke color along a path. Unfortunately, I could not make it work for your paths because of some dimension too large errors. – user121799 Jul 8 '18 at 18:26
  • @marmot Actually I don't want that kind of widening(on the link you wrote). Just color gradient, intensity of the color tells us about the value of $\sin$ magnitude. Widening was just to give an idea(I realize it was very badly presented) – Shamina Jul 8 '18 at 18:41
  • Sorry, but what does a sinusoidol function look like? What's the formula? – cfr Jul 8 '18 at 21:04
  • I should have clarified that I understand you don't want a widening, but to the best of my knowledge this is the best TikZ color changer (apart from pgfplots). @cfr I guess what is meant is something like blue!sin(distance)!red, @shamina please correct me if that's wrong. – user121799 Jul 8 '18 at 21:29
4

I tried to use Alain Matthes nice trick for your MWE but it did not work because of dimension too large errors. More precisely, I tried to use the coloring part. In fact, he mentions that he learned the coloring part from Mark Wilbrow, but I could not identify the corresponding post. If someone reading this knows it, then it would be great if you could let me know such that I can give proper credit.

In any case, one can make it work by abandoning the rounded corners and drawing them by hand with arcs. Then one can take a slightly modified version of the Mark-Wibrow-Alain-Matthes decoration and use a sine (instead of a linear) function to determine the composition of the colors.

\documentclass[border=2mm,tikz]{standalone}
\usetikzlibrary{calc}

\newcommand\wireheight{2} % height of one segment
\newcommand\wirewidth{1}  % width of a segment
\newcommand\wiredist{0.5} % distance between wires
\pgfmathsetmacro\pairdist{2*(\wirewidth+\wiredist)} % distance between pairs of wires

% \wire[options]{name}{start}{height}{width}
\newcommand\wire[5][]%
{\draw[#1]
    (#3)            coordinate (#2-0)
    -- ++(0,#4-#5)     coordinate (#2-1)
    arc(00:90:#5/2) arc(-90:-180:#5/2)    coordinate (#2-2)
    -- ++(0,#4-#5)     coordinate (#2-3)
    arc(180:90:#5/2) arc(-90:00:#5/2)    coordinate (#2-4)
    -- ++(0,#4-#5)     coordinate (#2-5)
    arc(00:90:#5/2) arc(-90:-180:#5/2)    coordinate (#2-6)
    -- ++(0,0.5*#4) coordinate (#2-7);
}

\usetikzlibrary{decorations}
\begin{document}

\makeatletter % starting point: from https://tex.stackexchange.com/a/14295/121799

\pgfkeys{/pgf/decoration/.cd,
         start color/.store in =\startcolor,
         end color/.store in   =\endcolor
}
\newcounter{alongline}

\pgfdeclaredecoration{sinoidal color change}{initial}{
 \state{initial}[width=0pt, next state=line]{\setcounter{alongline}{0}}
 \state{line}[width=0.5pt]{%
   %\pgfsetarrows{-}%
   \stepcounter{alongline}
   \pgfmathsetmacro{\x}{100*sin(1.8*\thealongline*(50pt/\pgfdecoratedpathlength))}
   % \typeout{\thealongline:\x,\pgfdecoratedpathlength}
   \pgfpathmoveto{\pgfpointorigin}%
   \pgfpathlineto{\pgfqpoint{.75pt}{0pt}}%
   \pgfsetstrokecolor{\endcolor!\x!\startcolor}%
   \pgfusepath{stroke}%
 }
 \state{final}{%
   %\pgfsetlinewidth{\pgflinewidth}%
   \pgfpathmoveto{\pgfpointorigin}%
   %\color{\endcolor!\x!\startcolor}%
   \pgfusepath{stroke}% 
 }
}

\makeatother
    \begin{tikzpicture}[>=stealth, shorten >=1pt, shorten <=1pt]
    \foreach \i in {0,...,2}
    {
       \begin{scope}[xscale=-1]
        \wire[thick,decoration={sinoidal color change,   
start color=red, end color=blue},decorate]{G-\i}{{-(\i)*\pairdist-\wiredist},0}{\wireheight}{\wirewidth}
       \end{scope}
        \wire[thick,decoration={sinoidal color change,   
start color=yellow, end color=red},decorate]{B-\i}{\i*\pairdist,0}{\wireheight}{\wirewidth}
    }
    \draw[black,<->] ($(G-1-2)!0.5!(G-1-3)$) -- ($(G-2-2)!0.5!(G-2-3)$) node[midway,above]{$\kappa_{2}$};
    %\draw[<->] ($(G-1-2)!-0.5!(G-2-3)$) -- +(-0.5,0) node[midway, above]{$\kappa_{1}$};
    \end{tikzpicture}

\end{document}

enter image description here

I tried to approximate your wires. If this is the way you want to go, I'll be happy to refine the decoration.

EDIT: Here is a version in which the color oscillates between two "boundary colors". The number of oscillations is given by the number \NumMax.

\documentclass[border=2mm,tikz]{standalone}
\usetikzlibrary{calc}

\newcommand\wireheight{2} % height of one segment
\newcommand\wirewidth{1}  % width of a segment
\newcommand\wiredist{0.5} % distance between wires
\pgfmathsetmacro\pairdist{2*(\wirewidth+\wiredist)} % distance between pairs of wires

% \wire[options]{name}{start}{height}{width}
\newcommand\wire[5][]%
{\draw[#1]
    (#3)            coordinate (#2-0)
    -- ++(0,#4-#5)     coordinate (#2-1)
    arc(00:90:#5/2) arc(-90:-180:#5/2)    coordinate (#2-2)
    -- ++(0,#4-#5)     coordinate (#2-3)
    arc(180:90:#5/2) arc(-90:00:#5/2)    coordinate (#2-4)
    -- ++(0,#4-#5)     coordinate (#2-5)
    arc(00:90:#5/2) arc(-90:-180:#5/2)    coordinate (#2-6)
    -- ++(0,0.5*#4) coordinate (#2-7);
}

\usetikzlibrary{decorations}
\begin{document}

\makeatletter % starting point: from https://tex.stackexchange.com/a/14295/121799

\pgfkeys{/pgf/decoration/.cd,
         start color/.store in =\startcolor,
         end color/.store in   =\endcolor
}
\newcounter{alongline}

\pgfmathsetmacro{\NumMax}{3}
\pgfdeclaredecoration{sinoidal color change}{initial}{
 \state{initial}[width=0pt, next state=line]{\setcounter{alongline}{0}}
 \state{line}[width=0.5pt]{%
   %\pgfsetarrows{-}%
   \stepcounter{alongline}
   \pgfmathsetmacro{\x}{50*(1+cos(\NumMax*1.8*\thealongline*(50pt/\pgfdecoratedpathlength)))}
   % \typeout{\thealongline:\x,\pgfdecoratedpathlength}
   \pgfpathmoveto{\pgfpointorigin}%
   \pgfpathlineto{\pgfqpoint{.75pt}{0pt}}%
   \pgfsetstrokecolor{\endcolor!\x!\startcolor}%
   \pgfusepath{stroke}%
 }
 \state{final}{%
   %\pgfsetlinewidth{\pgflinewidth}%
   \pgfpathmoveto{\pgfpointorigin}%
   %\color{\endcolor!\x!\startcolor}%
   \pgfusepath{stroke}% 
 }
}

\makeatother
    \begin{tikzpicture}[>=stealth, shorten >=1pt, shorten <=1pt]
    \foreach \i in {0,...,2}
    {
       \begin{scope}[xscale=-1]
        \wire[thick,decoration={sinoidal color change,   
start color=red, end color=blue},decorate]{G-\i}{{-(\i)*\pairdist-\wiredist},0}{\wireheight}{\wirewidth}
       \end{scope}
        \wire[thick,decoration={sinoidal color change,   
start color=yellow, end color=red},decorate]{B-\i}{\i*\pairdist,0}{\wireheight}{\wirewidth}
    }
    \draw[black,<->] ($(G-1-2)!0.5!(G-1-3)$) -- ($(G-2-2)!0.5!(G-2-3)$) node[midway,above]{$\kappa_{2}$};
    %\draw[<->] ($(G-1-2)!-0.5!(G-2-3)$) -- +(-0.5,0) node[midway, above]{$\kappa_{1}$};
    \end{tikzpicture}

\end{document}

enter image description here

  • 1
    I also tried unsuccessfully to find the original Mark Wilbrow post .... – cfr Jul 8 '18 at 22:36
  • Thanks a lot @marmot. Just a minute change, because of |sin| coloring. After one period colors will be restored. To make point clear. Sorry for being unclear :) – Shamina Jul 9 '18 at 9:08
  • @Shamina |sin(x)| or 1+sin(x)? The latter looks like a wave whereas the first one has a non-continuous slope. – user121799 Jul 9 '18 at 10:19
  • Let us not focus on the slope for time being but on the function, so color intensity plot will be something like |sin(x)| only. May be this one is clear, I am not able to put in properly. – Shamina Jul 9 '18 at 11:04
  • 1
    @Shamina I made an update, please have a look. You may have to change the value of \NumMax. – user121799 Jul 9 '18 at 11:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.