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

Tarass
  • 16,912

1 Answers1

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