9

I am making a picture using foreach. MWE is appended below

\documentclass{article}

\usepackage[svgnames]{xcolor}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}

 \foreach \x in {0,...,5}
    \draw [DodgerBlue](\x,-1) circle (0.25);

\foreach \x in {0,...,5}
    \draw [-latex,red](\x,-1) -- (\x,-1.5);

\foreach \x in {0,...,5}
    \draw [-latex,DarkGreen](\x,-1) -- (\x,-0.5);

\draw [ultra thin] (5,-0.5) -- (0,-1);

\end{tikzpicture}

\end{document}

The resulting picture is attached below

enter image description here

Now what I want is that the green arrows on the top should be limited by the black line diagonal line. That is for the first circle there should be no green arrow, and its length should increase until it becomes equal to the red arrow in the last circle. How can this be done using foreach using the variable \y. Is there a way such that the intersection of the black diagonal line with the green arrows can be used to limit the length of the green arrows to the desired values? Or is there any other way to achieve this?

5 Answers 5

11

In case you do not want to do analytic computations (or if you do not have a simple parametrization for the line).

\documentclass{article}

\usepackage[svgnames]{xcolor}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}

\begin{tikzpicture}

 \foreach \x in {0,...,5}
    \draw [DodgerBlue](\x,-1) circle (0.25);

\foreach \x in {0,...,5}
    \draw [-latex,red](\x,-1) -- (\x,-1.5) ;

\draw [ultra thin] (5,-0.5) coordinate(aux0)  -- (0,-1) coordinate(aux1);

\foreach \x in {1,...,5}
    \draw [-latex,DarkGreen] (\x,-1) coordinate(aux2) (\x,-0.5) coordinate(aux3)
    (aux2) -- (intersection cs:first line={(aux2)--(aux3)}, 
    second line={(aux0)--(aux1)});


\end{tikzpicture}

\end{document}

enter image description here

To make @ArtificialStupidity happy (?) one loop...

\documentclass[border=3.14mm]{standalone}
\usepackage[svgnames]{xcolor}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\draw [ultra thin] (5,-0.5) coordinate(aux0)  -- (0,-1) coordinate(aux1);
\foreach \x in {0,...,5}
   { \draw [DodgerBlue](\x,-1) circle (0.25);
    \draw [-latex,red](\x,-1) -- (\x,-1.5) ;
    \unless\ifnum\x=0%    
    \draw [-latex,DarkGreen] (\x,-1) coordinate(aux2) (\x,-0.5) coordinate(aux3)
    (aux2) -- (intersection cs:first line={(aux2)--(aux3)}, 
    second line={(aux0)--(aux1)});
    \fi
    }
\end{tikzpicture}
\end{document}
5
  • Using intersections is an interesting idea :)
    – TeXnician
    Dec 12, 2018 at 11:11
  • @TeXnician These are actually those intersections that come with calc and do not require the intersections library. They are restricted to intersections of straight lines, though. (+1 to your analytic solution ;-)
    – user121799
    Dec 12, 2018 at 11:13
  • I have used these "calc intersections" before, but I would not have thought of them in this case…
    – TeXnician
    Dec 12, 2018 at 11:22
  • 1
    I am almost happy. The code is not so short and cryptic as mentioned before. :-) Dec 12, 2018 at 16:07
  • 2
    @ArtificialStupidity Yes, but of course now it is no longer a valid answer to the question which in its title asks for two loops. (3 loops includes 2, of course ;-)
    – user121799
    Dec 12, 2018 at 16:12
8

You can use a simple linear function. Please note that your arrow heads are quite large in your scale. It might be a good idea to choose a larger scale or use another arrow tip to have a better representation of the second case.

linear function

\documentclass{article}

\usepackage[svgnames]{xcolor}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}

\foreach \x in {0,...,5}{
  \draw [DodgerBlue](\x,0) circle (0.25);
  \draw [-latex,red](\x,0) -- (\x,-.5);
}
\foreach \x in {1,...,5}{
    \draw [-latex,DarkGreen](\x,0) -- (\x,{0.1*\x});
}

\draw [ultra thin] (5,.5) -- (0,0);

\end{tikzpicture}

\end{document}
7

A PSTricks solution with just one loop only for comparison purposes.

\documentclass[pstricks]{standalone}
\usepackage{pst-calculate}
\begin{document}
\begin{pspicture}[arrowsize=.2,arrowinset=0,linewidth=1pt](8.5,\pscalculate{8/3})
        \foreach \i in {0,1,...,5}{%
            \pstVerb{/x {\i\space  1.5 mul .5 add} def}%
            \pscircle[linecolor=blue](!x 1){.5}
            \psline[linecolor=red]{->}(!x 1)(!x 0)
            \ifnum\i=0\relax\else\psline[linecolor=green]{->}(!x 1)(!x \i\space 3 div 1 add)\fi
        }
        \psline[linestyle=dashed](.5,1)(!8 dup 3 div)
\end{pspicture}
\end{document}

enter image description here

1
  • Thanks for upvoting my answer. Now I got a nice hat. Dec 12, 2018 at 15:55
5

one more with use of lines intersections, but defined with help of the package intersections:

\documentclass[tikz, svgnames, margin=3]{standalone}
\usetikzlibrary{intersections}

\begin{document}
    \begin{tikzpicture}
 \foreach \x in {0,...,5}{
  \draw [DodgerBlue](\x,0) circle (0.25);
  \draw [-latex,red](\x,0) -- (\x,-.5);
}
\draw [ultra thin, name path=A] (5,.5) -- (0,0);
\foreach \x in {1,...,5}
{
    \path[name path=B\x]   (\x,0) -- ++ (0,0.5);
    \draw[-latex,DarkGreen,
          name intersections={of=A and B\x,by={B\x}}] (\x,0) -- (B\x);
}
    \end{tikzpicture}
\end{document}

enter image description here

4

Like this (please observe \foreach \x in {1,...,5} instead of \foreach \x in {0,...,5}?

\documentclass{article}

\usepackage[svgnames]{xcolor}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}

 \foreach \x in {0,...,5}
    \draw [DodgerBlue](\x,-1) circle (0.25);

\foreach \x in {0,...,5}
    \draw [-latex,red](\x,-1) -- (\x,-1.5);

%\foreach \x in {0,...,5}
 %   \draw [-latex,DarkGreen](\x,-1) -- (\x,-0.5);
\foreach \x in {1,...,5}
\draw [-latex,DarkGreen](\x,-1) -- (\x,-1+0.1*\x);

\draw [ultra thin] (5,-0.5) -- (0,-1);

\end{tikzpicture}

\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .