6

I have the following problem

I want to avoid a \foreach loop in a macro if not necessary, but I don't know how to do a test in a tikz picture, I undersand why \ifthenelse can not work. In my example I don't want the foreach loops if graduation are set to 0.

\documentclass[tikz]{standalone}

\pgfkeys{/tikz/.cd,
  CylCol/.store in=\CylCol,
  CylCol=gray,
  CylFillCol/.store in=\CylFillCol,
  CylFillCol=blue,
  CylFill/.store in=\CylFill,
  CylFill=0,
  CylRatio/.store in=\CylRatio,
  CylRatio=.08,  
  CylGrad/.store in=\CylGrad,
  CylGrad=5,
  CylSecondGrad/.store in=\CylSecondGrad,
  CylSecondGrad=0,
   }

\newcommand{\TikzCylindre}[1][]{%
    \begin{scope}[#1]
    % Grisé des surfaces du cylindre.
    \shade[left color=\CylCol!30, right color=\CylCol!5]%
         (-1,1)--(-1,0) arc (180:360:1 and \CylRatio) --(1,0) -- (1,1);
    \shade[left color=\CylCol!5, right color=\CylCol!30]%
        (0,1) ellipse (1 and \CylRatio);
    \draw[\CylCol!50] (1,0) arc (0:180:1 and \CylRatio)--(-1,0) ;

    % Remplissage du cylindre
    \shade[left color=\CylFillCol!40, right color=\CylFillCol!10]%
         (-1,\CylFill)--(-1,0) arc (180:360:1 and \CylRatio) --(1,0) -- (1,\CylFill);
    \fill[color=\CylFillCol!25] (0,\CylFill) ellipse (1 and \CylRatio);
    \draw[\CylFillCol!50!black!50] (1,0) arc (0:180:1 and \CylRatio)--(-1,0) ;
    \draw[\CylFillCol!50!black!50] (0,\CylFill) ellipse (1 and \CylRatio) ;

    % dessin des bords du cylindre
    \draw[semithick] (-1,1)--(-1,0) arc (180:360:1 and \CylRatio)--(1,0)--(1,1);
    \draw[semithick] (0,1) ellipse (1 and \CylRatio);   

        \begin{scope}[shift={(0,-\CylRatio)}]
    \pgfmathtruncatemacro\CylMaxGrad{\CylGrad-1}
    \foreach \y in {1,2,...,\CylMaxGrad}
            {\draw[semithick] (0,\y/\CylGrad)
                arc (270:260:1 and \CylRatio) ;
            \draw[semithick] (0,\y/\CylGrad)
                arc (270:280:1 and \CylRatio) (0.2,\y/\CylGrad)
                node[right,yslant=\CylRatio](\y){\footnotesize\y};
            };

    \pgfmathtruncatemacro\CylMaxGrad{\CylSecondGrad-1}
    \foreach \y in {1,2,...,\CylMaxGrad}
        {\draw(0,\y/\CylSecondGrad) arc (270:265:1 and \CylRatio) ;
        \draw (0,\y/\CylSecondGrad) arc (270:275:1 and \CylRatio) ;
        };
        \end{scope} ;

    \end{scope}
    }

\begin{document}

\begin{tikzpicture}

    \TikzCylindre[x=1.5cm,y=4cm,CylFill=.8,CylSecondGrad=10] ;

\end{tikzpicture}

\end{document}

Any other inprovments are welcome.

enter image description here

  • 1
    \the\numexpr\max-1 is useful if you want to use \max-1 in a foreach – Alain Matthes Feb 22 '14 at 21:47
4

Your original questions were:

First : I need to do some thing like :\foreach \y in {1,2,...,\max-1} but \max-1 doesn't work

Second : I want to avoid a \foreach loop in a macro if not necessary, but I don't know how to do a test in a tikz picture, I undersand why \ifthenelse can not work. In my example I don't want the foreach loops if graduation are set to 0.

As to the first of your two questions. one way is to introduce a new counter mytemp and use it as such:

\setcounter{mytemp}{\CylGrad}
\addtocounter{mytemp}{-1}
\foreach \y in {1,2,...,\themytemp}

or alternately, as Alain suggests, avoid the counter and use

\foreach \y in {1,2,...,\the\numexpr\CylGrad-1}

For the second question, use an \ifnum

\ifnum\CylGrad>0
\foreach \y in {1,2,...,\the\numexpr\CylGrad-1}
    {\draw[semithick] (0,\y/\CylGrad)
        arc (270:260:1 and \CylRatio) ;
    \draw[semithick] (0,\y/\CylGrad)
        arc (270:280:1 and \CylRatio) (0.2,\y/\CylGrad)
        node[right,yslant=\CylRatio](\y){\footnotesize\y};
    };
\fi

Here is your MWE demonstrating these:

\documentclass[tikz]{standalone}

\pgfkeys{/tikz/.cd,
  CylCol/.store in=\CylCol,
  CylCol=gray,
  CylFillCol/.store in=\CylFillCol,
  CylFillCol=blue,
  CylFill/.store in=\CylFill,
  CylFill=0,
  CylRatio/.store in=\CylRatio,
  CylRatio=.08,  
  CylGrad/.store in=\CylGrad,
  CylGrad=5,
  CylSecondGrad/.store in=\CylSecondGrad,
  CylSecondGrad=0,
   }

\newcommand{\TikzCylindre}[1][]{%
    \begin{scope}[#1]
    % Grisé des surfaces du cylindre.
    \shade[left color=\CylCol!30, right color=\CylCol!5]%
         (-1,1)--(-1,0) arc (180:360:1 and \CylRatio) --(1,0) -- (1,1);
    \shade[left color=\CylCol!5, right color=\CylCol!30]%
        (0,1) ellipse (1 and \CylRatio);
    \draw[\CylCol!50] (1,0) arc (0:180:1 and \CylRatio)--(-1,0) ;

    % Remplissage du cylindre
    \shade[left color=\CylFillCol!40, right color=\CylFillCol!10]%
         (-1,\CylFill)--(-1,0) arc (180:360:1 and \CylRatio) --(1,0) -- (1,\CylFill);
    \fill[color=\CylFillCol!25] (0,\CylFill) ellipse (1 and \CylRatio);
    \draw[\CylFillCol!50!black!50] (1,0) arc (0:180:1 and \CylRatio)--(-1,0) ;
    \draw[\CylFillCol!50!black!50] (0,\CylFill) ellipse (1 and \CylRatio) ;

    % dessin des bords du cylindre
    \draw[semithick] (-1,1)--(-1,0) arc (180:360:1 and \CylRatio)--(1,0)--(1,1);
    \draw[semithick] (0,1) ellipse (1 and \CylRatio);   

        \begin{scope}[shift={(0,-\CylRatio)}]
        \ifnum\CylGrad>0
        \foreach \y in {1,2,...,\the\numexpr\CylGrad-1}
            {\draw[semithick] (0,\y/\CylGrad)
                arc (270:260:1 and \CylRatio) ;
            \draw[semithick] (0,\y/\CylGrad)
                arc (270:280:1 and \CylRatio) (0.2,\y/\CylGrad)
                node[right,yslant=\CylRatio](\y){\footnotesize\y};
            };
        \fi

        \ifnum\CylSecondGrad>0
        \foreach \y in {1,2,...,\the\numexpr\CylSecondGrad}
        {\draw(0,\y/\CylSecondGrad) arc (270:265:1 and \CylRatio) ;
        \draw (0,\y/\CylSecondGrad) arc (270:275:1 and \CylRatio) ;
        };
        \fi
        \end{scope} ;

    \end{scope}
    }

\begin{document}

\begin{tikzpicture}

    \TikzCylindre[x=1.5cm,y=4cm,CylFill=.8,CylSecondGrad=10] ;

\end{tikzpicture}

\end{document}

enter image description here

  • I try to avoid the 5 on the top of the cylinder, it was for the first loop not for the second ;-) thank you. during this time I found a tikz solution for that : ` \pgfmathtruncatemacro\CylMaxGrad{\CylGrad-1} \foreach \y in {1,2,...,\CylMaxGrad} `. – Tarass Feb 22 '14 at 21:33
  • @Tarass see revision for second question – Steven B. Segletes Feb 22 '14 at 21:40
  • 1
    I prefer no newcounter solution : \ifnum\CylSecondGrad>0 works as well. Thank you for the \ifnum help. – Tarass Feb 22 '14 at 21:46
  • 2
    You can avoid a new counter with \foreach \y in {1,2,...,\the\numexpr\CylSecondGrad-2} – Alain Matthes Feb 22 '14 at 21:51

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.