Curvar el cilindro de forma periódica.

Curvar el cilindro de forma periódica.

Tengo que implementar una matriz formada por elementos cilíndricos. Sin embargo, el siguiente código sólo puede proporcionar un cilindro recto (el crédito del código va aeste enlace), en lugar de eso necesito doblarlo como en la figura que se muestra, puede que no esté en ese ángulo sino vertical. Pero parecía que no podía lograrlo. Ni siquiera parecía poder aumentar el número de cilindros de uno a más.

\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} 

ingrese la descripción de la imagen aquí

Respuesta1

Aquí hay una respuesta que produce algo largo en estas líneas. El ingrediente clave es la perspectivebiblioteca. Utiliza unbuen truco por el símbolo 1(y, como siempre, las cosas realmente interesantes no tienen muchos votos... ;-) lo que nos permite evitar escribir tpp cs:x=...,y=...,z=..., solo podemos coordinar y cambiar switch on perspective. Dado que las decoraciones causan dimension too largeerrores, el gradiente de color y el cambio de ancho de línea se logran mediante bucles, por lo que lleva algo de tiempo compilar (12 segundos en una MacBook Pro de 5 años). A continuación se puede encontrar una respuesta más rápida, basada en decoración, que funciona para caminos que no tienen demasiadas curvas.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{calc,perspective,3d}
\makeatletter
\tikzset{switch on perspective/.code={\def\tikz@parse@splitxyz##1##2##3,##4,{%
    \def\pgfutil@next{\tikz@scan@one@point##1(tpp cs:x={##2},y={##3},z={##4})}% https://tex.stackexchange.com/a/365418/194703
}}}
\makeatother

\begin{document}
\begin{tikzpicture}[3d view={-70}{15}]
 \begin{scope}[perspective={p = {(20,0,0)}, q = {(0,20,0)}},switch on perspective]
  \path let \p1=($(0,2,0)-(0,0,0)$),\p2=($(20,2,0)-(20,0,0)$),
     \n1={atan2(\y1,\x1)/2+atan2(\y2,\x2)/2} in
   [left color=black,right color=gray!80!black,shading angle=\n1]
    (0,-3,0) -- (0,3,0) -- (20,3,0) -- (20,-3,0) -- cycle;
  \begin{scope}
   \clip (1,-3,0) -- (1,3,0) -- (20,3,0) -- (20,-3,0) -- cycle;
   \foreach \X [count=\Y] in {2,1.2,-1.2,-2}
   {\foreach \Z [evaluate=\Z as \CF using {int(90-\Z/3)}] in {1,...,95}
   {\draw let 
    \p1=($(0.8+\Z/5,\X+0.5,0)-(0.8+\Z/5,\X-0.5,0)$),
    \n1={sqrt(\x1*\x1+\y1*\y1)} in [line width=0.1*\n1,gray!\CF!black]
    plot[variable=\t,domain=0.8+\Z/5:0.8+\Z/5+0.4,samples=5,smooth] 
    (\t,{\X+0.2*pow(-1,\Y+1)*isodd(int(\t/2.05))},0) ;}}
  \path foreach \X [count=\Y] in {2,1.2,-1.2,-2}
   {(1,{\X+pow(-1,\Y+1)*0.2*isodd(int(1/2.05))},0) coordinate (aux\Y) };        
  \end{scope}   
 \end{scope}
 \begin{scope}[canvas is xz plane at y=0]
  \fill[rotate=-15] foreach \X in {1,...,4} {(aux\X) circle[x radius=5pt,y radius=1pt]};
 \end{scope}
\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

Para cilindros rectos no hay problema, la decoración se porta bien.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{calc,decorations,perspective,3d}
\makeatletter
\tikzset{switch on perspective/.code={\def\tikz@parse@splitxyz##1##2##3,##4,{%
    \def\pgfutil@next{\tikz@scan@one@point##1(tpp cs:x={##2},y={##3},z={##4})}% https://tex.stackexchange.com/a/365418/194703
}}}
\makeatother
% the following decoration is based on
% https://tex.stackexchange.com/a/14295/128068 and
% https://tex.stackexchange.com/a/471222
\pgfkeys{/pgf/decoration/.cd,
         start color/.store in=\startcolor,
         start color=black,
         end color/.store in=\endcolor,
         end color=black,
         varying line width steps/.initial=100
}
\pgfdeclaredecoration{width and color change}{initial}{
 \state{initial}[width=0pt, next state=line, persistent precomputation={%
   \pgfmathparse{\pgfdecoratedpathlength/\pgfkeysvalueof{/pgf/decoration/varying line width steps}}%
   \let\increment=\pgfmathresult%
   \def\x{0}%
 }]{}
 \state{line}[width=\increment pt,   persistent postcomputation={%
   \pgfmathsetmacro{\x}{\x+\increment}
   },next state=line]{%
   \pgfmathparse{varyinglw(100*(\x/\pgfdecoratedpathlength))}
   \pgfsetlinewidth{\pgfmathresult pt}%
   \pgfpathmoveto{\pgfpointorigin}%
   \pgfmathsetmacro{\steplength}{1.4*\increment}
   \pgfpathlineto{\pgfqpoint{\steplength pt}{0pt}}%
   \pgfmathsetmacro{\y}{100*(\x/\pgfdecoratedpathlength)}
   \pgfsetstrokecolor{\endcolor!\y!\startcolor}%
   \pgfusepath{stroke}%
 }
 \state{final}{%
   \pgfsetlinewidth{\pgflinewidth}%
   \pgfpathmoveto{\pgfpointorigin}%
   \pgfmathsetmacro{\y}{100*(\x/\pgfdecoratedpathlength)}
   \color{\endcolor!\y!\startcolor}%
   \pgfusepath{stroke}% 
 }
}


\begin{document}
\begin{tikzpicture}[3d view={-70}{15}]
 \begin{scope}[perspective={p = {(20,0,0)}, q = {(0,20,0)}},switch on perspective]
  \path let \p1=($(0,2,0)-(0,0,0)$),\p2=($(20,2,0)-(20,0,0)$),
     \n1={atan2(\y1,\x1)/2+atan2(\y2,\x2)/2} in
   [left color=black,right color=gray!80!black,shading angle=\n1]
    (0,-3,0) -- (0,3,0) -- (20,3,0) -- (20,-3,0) -- cycle;
  \begin{scope}
   \clip (1,-3,0) -- (1,3,0) -- (20,3,0) -- (20,-3,0) -- cycle;
   \foreach \X [count=\Y] in {2,1.2,-1.2,-2}
   {\draw[decorate,decoration={width and color change}] let 
    \p1=($(10,\X+0.5,0)-(10,\X-0.5,0)$),\p2=($(1,\X+0.5,0)-(1,\X-0.5,0)$),
    \n1={sqrt(\x1*\x1+\y1*\y1)},\n2={sqrt(\x2*\x2+\y2*\y2)} in
    [declare function={varyinglw(\x)=0.1*\n1+0.1*(\n2-\n1)*\x/100;},
    /pgf/decoration/start color=gray!70!black,/pgf/decoration/end color=gray]
   (20,\X,0) -- (1,\X,0) coordinate (aux\Y);}
  \end{scope}   
 \end{scope}
 \begin{scope}[canvas is xz plane at y=0]
  \fill[rotate=-15] foreach \X in {1,...,4} {(aux\X) circle[x radius=5pt,y radius=1pt]};
 \end{scope}
\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

Probablemente se puedan encontrar regiones de parámetros en las que los caminos curvos también funcionen, pero podría ser una mejor inversión de tiempo intentar enseñar estas decoraciones fpu.

información relacionada