1

I have to implement an array made up of cylindrical like elements. However, below code can only provide a straight cylinder (code credit goes to this link), instead I would like the cylinder to be modulated in a periodic way, for e.g. in a sinusoidal way similar to case of this link. But I couldn't seem to succeed. I couldn't even seem to increase the number of cylinder from one to more.(this question is in continuation to my previous question where Schrödinger's cat gave a very nice answer). In this question the output differs to some extent.

\documentclass[border=2mm]{standalone}
\usepackage{xcolor}
\definecolor{mycolor}{RGB}{8,108,131}
\usepackage{tikz} 
\usetikzlibrary{positioning}
\usetikzlibrary{backgrounds}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{calc}
\tikzset{cylinder end fill/.style={path picture={
            \pgftransformshift{\centerpoint}%
            \pgftransformrotate{\rotate}%  
            \pgfpathmoveto{\beforetop}%
            \pgfpatharc{90}{-270}{\xradius and \yradius}%
            \pgfpathclose
            \pgfsetfillcolor{#1}%
            \pgfusepath{fill}}
}}
\begin{document}
    \begin{tikzpicture}
    \begin{scope}[on background layer]
    \path let \p1=(0.2,8.4),
    \n1={atan2(\y1,\x1)},\n2={veclen(\y1,\x1)} in
    node[cylinder, rotate=270,
    minimum height=0.85*\n2,minimum width=1cm,aspect=1.0,
    cylinder end fill=red,
    left color=red!30,right color=black,middle color=red!80, opacity=0.7,
    draw] at (0.8,4.7) {1};
    \end{scope}
    \end{tikzpicture}
\end{document} 

enter image description here

Shamina
  • 1,078

1 Answers1

1

This may (or may not) be a step in the right direction.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{decorations} 
\newcounter{icoord}
\pgfkeys{/tikz/.cd,
    curved cylinder/.cd,
    radius/.store in=\CurvedCylinderRadius,
    radius=10pt,
    step/.store in=\CurvedCylinderStep,
    step=1pt,
    shade/.style={left color=red!30,right color=black,middle color=red!80}
}

\pgfdeclaredecoration{curved cylinder}{initial}
{% 
\state{initial}[width=\CurvedCylinderStep,next state=cont] {%
    \pgfmoveto{\pgfpoint{\CurvedCylinderStep}{\CurvedCylinderRadius}}%
    \pgfpathlineto{\pgfpoint{0.3\pgflinewidth}{\CurvedCylinderRadius}}%
    \setcounter{icoord}{0}%
    \pgfcoordinate{lastup-\number\value{icoord}}{\pgfpoint{1pt}{\CurvedCylinderRadius}}%
    \pgfcoordinate{lastdown-\number\value{icoord}}{\pgfpoint{1pt}{-1*\CurvedCylinderRadius}}%
  }
  \state{cont}[width=\CurvedCylinderStep]{%
     \stepcounter{icoord}%
     \pgfcoordinate{lastup-\number\value{icoord}}{\pgfpoint{\CurvedCylinderStep}{\CurvedCylinderRadius}}
     \pgfcoordinate{lastdown-\number\value{icoord}}{\pgfpoint{\CurvedCylinderStep}{-1*\CurvedCylinderRadius}}
     \pgfcoordinate{tmpup}{\pgfpoint{\CurvedCylinderStep+0.3pt}{\CurvedCylinderRadius}}
     \pgfcoordinate{tmpdown}{\pgfpoint{\CurvedCylinderStep+0.3pt}{-1*\CurvedCylinderRadius}}
     \pgfmathanglebetweenlines{\pgfpointanchor{lastup-\the\numexpr\value{icoord}-1}{center}}%
      {\pgfpointanchor{lastup-\number\value{icoord}}{center}}%
      {\pgfpointanchor{Y}{center}}%
      {\pgfpointanchor{O}{center}}%
     \pgfmathsetmacro\myshadingangle{\pgfmathresult}%
     \path[curved cylinder/shade,shading angle=\myshadingangle] 
        (lastup-\the\numexpr\value{icoord}-1) 
     -- (tmpup) to[out=180,in=180] (tmpdown) -- (lastdown-\the\numexpr\value{icoord}-1)
     to[out=180,in=180] cycle;%
     \pgfmoveto{\pgfpointanchor{lastup-\the\numexpr\value{icoord}-1}{center}}%
     \pgfpathlineto{\pgfpointanchor{lastup-\number\value{icoord}}{center}}%
     \pgfmoveto{\pgfpointanchor{lastdown-\the\numexpr\value{icoord}-1}{center}}%
     \pgfpathlineto{\pgfpointanchor{lastdown-\number\value{icoord}}{center}}%
  }
  \state{final}[width=\CurvedCylinderStep]
  { % perhaps unnecessary but doesn't hurt either
    \pgfmoveto{\pgfpointdecoratedpathlast}
    \fill (tmpup) to[out=0,in=0] (tmpdown) to[out=-180,in=-180] cycle;
  }
}

\begin{document}
  \begin{tikzpicture}[scale=1]
   \path (0,0) coordinate (O) (0,1) coordinate (Y);
    \draw[decorate,decoration=curved cylinder,curved cylinder/radius=1cm] 
     (0,0) to[out=90,in=-90] (1,4)  to[out=90,in=-90] (0,8);
    \draw[decorate,decoration=curved cylinder,
        curved cylinder/radius=1cm,
        curved cylinder/shade/.style={left color=blue!30,right
        color=black,middle color=blue!80},looseness=0.7] 
     (4,0) to[out=90,in=-90] (5,4)  to[out=90,in=-90] (4,8);
  \end{tikzpicture}
\end{document}

enter image description here

Or

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{decorations} 
\newcounter{icoord}
\pgfkeys{/tikz/.cd,
    curved cylinder/.cd,
    radius/.store in=\CurvedCylinderRadius,
    radius=10pt,
    step/.store in=\CurvedCylinderStep,
    step=1pt,
    shade/.style={left color=red!30,right color=black,middle color=red!80}
}

\pgfdeclaredecoration{curved cylinder}{initial}
{% 
\state{initial}[width=\CurvedCylinderStep,next state=cont] {%
    \pgfmoveto{\pgfpoint{\CurvedCylinderStep}{\CurvedCylinderRadius}}%
    \pgfpathlineto{\pgfpoint{0.3\pgflinewidth}{\CurvedCylinderRadius}}%
    \setcounter{icoord}{0}%
    \pgfcoordinate{lastup-\number\value{icoord}}{\pgfpoint{1pt}{\CurvedCylinderRadius}}%
    \pgfcoordinate{lastdown-\number\value{icoord}}{\pgfpoint{1pt}{-1*\CurvedCylinderRadius}}%
  }
  \state{cont}[width=\CurvedCylinderStep]{%
     \stepcounter{icoord}%
     \pgfcoordinate{lastup-\number\value{icoord}}{\pgfpoint{\CurvedCylinderStep}{\CurvedCylinderRadius}}
     \pgfcoordinate{lastdown-\number\value{icoord}}{\pgfpoint{\CurvedCylinderStep}{-1*\CurvedCylinderRadius}}
     \pgfcoordinate{tmpup}{\pgfpoint{\CurvedCylinderStep+0.3pt}{\CurvedCylinderRadius}}
     \pgfcoordinate{tmpdown}{\pgfpoint{\CurvedCylinderStep+0.3pt}{-1*\CurvedCylinderRadius}}
     \pgfmathanglebetweenlines{\pgfpointanchor{lastup-\the\numexpr\value{icoord}-1}{center}}%
      {\pgfpointanchor{lastup-\number\value{icoord}}{center}}%
      {\pgfpointanchor{Y}{center}}%
      {\pgfpointanchor{O}{center}}%
     \pgfmathsetmacro\myshadingangle{\pgfmathresult}%
     \path[curved cylinder/shade,shading angle=\myshadingangle] 
        (lastup-\the\numexpr\value{icoord}-1) 
     -- (tmpup) to[out=180,in=180] (tmpdown) -- (lastdown-\the\numexpr\value{icoord}-1)
     to[out=180,in=180] cycle;%
     \pgfmoveto{\pgfpointanchor{lastup-\the\numexpr\value{icoord}-1}{center}}%
     \pgfpathlineto{\pgfpointanchor{lastup-\number\value{icoord}}{center}}%
     \pgfmoveto{\pgfpointanchor{lastdown-\the\numexpr\value{icoord}-1}{center}}%
     \pgfpathlineto{\pgfpointanchor{lastdown-\number\value{icoord}}{center}}%
  }
  \state{final}[width=\CurvedCylinderStep]
  { % perhaps unnecessary but doesn't hurt either
    \pgfmoveto{\pgfpointdecoratedpathlast}
    \fill (tmpup) to[out=0,in=0] (tmpdown) to[out=-180,in=-180] cycle;
  }
}

\begin{document}
  \begin{tikzpicture}[scale=1]
   \path (0,0) coordinate (O) (0,1) coordinate (Y);
    \draw[decorate,decoration=curved cylinder,curved cylinder/radius=1cm
    ,looseness=0.7] 
     (0,0) foreach \X in {1,2,3} 
     {to[out=90,in=-90] ++ (1,4)  to[out=90,in=-90] ++(-1,4)};
    \draw[decorate,decoration=curved cylinder,
        curved cylinder/radius=1cm,
        curved cylinder/shade/.style={left color=blue!30,right
        color=black,middle color=blue!80},looseness=0.7] 
     (6,0) foreach \X in {1,2,3} 
     {to[out=90,in=-90] ++ (-1,4)  to[out=90,in=-90] ++(1,4)};
  \end{tikzpicture}
\end{document}

enter image description here

Even though this is not a full fledged decoration, it still can pick up dimension too large errors easily.

  • Your answer is indeed fantastic!! I think it is not difficult to change the blue pipe orientation, such that it is out of phase to the red one? For instance, one red is like sin(x) and blue is like cos(x). Thanks a lot!!! – Shamina Mar 20 '20 at 15:56
  • 1
    @Shamina I added one pic. This is more like sin(x) and -sin(x), though. –  Mar 20 '20 at 15:59
  • Exactly the stuff I wanted, not cos or sin but actually sin and -sin, thanks for understanding me through telepathy :) One thing which clearly shows my ignorance with the code, is when I am trying to increase the size of the pipes. I was thinking they will come close to each other again at some vertical height. But it doesn't seem to happen. I just wanted to show the pipes long enough so that at least two touchings can be seen (not more). Similar to this link. – Shamina Mar 20 '20 at 16:08
  • 1
    @Shamina You only have to add several of these paths together. –  Mar 20 '20 at 16:14