# Projectile Motion Diagram using PGFplots/tikz?

I'm making an equation sheet for my physics class (using LaTeX), and we're doing a section on projectile motion/vectors. Are there any suggestions for drawing diagrams using either plain Tikz or PGFplots like the ones I find in my textbook?

This proposal uses animate in the beamer class, via tikz, to simulate projectile motions and one can see the vectors at any instant by clicking the > arrow at the bottom while triangle is for a continuous trajectory. The simulation uses g=2 instead of g=9.8 so that more points can be obtained.

Update (2014/12/9) The OP needs the graph in article class and the 5 vectors. So this is an update. Basically, simply change the beamer class to artice class and remove the \begin/\end{frame} and navigation. Of course, for the vectors to show up, a foreach loop with conditional check is added in this new update.

Code

\documentclass[11pt]{article}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing}
\usepackage{animate}
\usepackage{ifthen}
\begin{document}
%\begin{frame}
\def\rg{2}
\begin{animateinline}[poster=first,controls]{8}%
\multiframe{37}{rt=0+.1,icount=1+1,rvo=5+0.0,rtheta=45+.0}
{% rt=time, rvo=initial v, g=2, rtheta=inital angle
\begin{tikzpicture}[scale=.75]
\clip (-1,-2) rectangle (15,10); % For body projected upward with angle rtheta=45
%\clip (-1,-8) rectangle (15,1);   % For body projected horizontally, rtheta=0
\draw[red] (0,0)--(13,0);         % ground horizontal line
\coordinate (A\icount) at ({\rvo*cos(\rtheta)*(\rt)},{\rvo*sin(\rtheta)*(\rt)-0.5*\rg*(\rt)*(\rt)}) {};              % (x,y) position,
\path (A\icount) -- + ({0.5*\rvo*cos(\rtheta)},{0.5*(\rvo*sin(\rtheta)-\rg*(\rt))}) coordinate (B\icount){};  % (V_x,V_y) position , scaled by 0.5
\draw[thick,green,->] (A\icount.center) -- (B\icount-|A\icount);
\draw[thick,green,->] (A\icount.center) -- (B\icount|-A\icount);
\draw[thick,green,->] (A\icount.center) -- (B\icount);
\ifthenelse{\icount > 1}
{\draw ({\rvo*cos(\rtheta)*(\rt)},0) node[below]{\tiny S=\rvo*cos(\rtheta)*(\rt)};                               % x displacement
\foreach \x in {.0,.1,...,\rt}
\filldraw [blue]
({\rvo*cos(\rtheta)*(\x)}, {\rvo*sin(\rtheta)*(\x)-0.5*\rg*(\x)*(\x)}) circle (1pt);
\foreach \i in {1,9,19,28,36}{ % adjust this frame number to show the vectors
\ifnum \icount >\i
\draw[thick,blue,->] (A\i.center) -- (B\i-|A\i);
\draw[thick,blue,->] (A\i.center) -- (B\i|-A\i);
\draw[thick,blue,->] (A\i.center) -- (B\i);
\ifnum \icount>19
\node [red,above=0.2cm] at (A19){$v_y=0$};
\fi
\fi
}
}
{}
\filldraw [red]
({\rvo*cos(\rtheta)*(\rt)}, {\rvo*sin(\rtheta)*(\rt)-0.5*\rg*(\rt)*(\rt)}) circle (2pt);
\end{tikzpicture}
}
\end{animateinline}
%\end{frame}
\end{document}


Update: (2014/12/8) --- Thanks for Ellett's insight that improves the coding.

Code

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing}
\usepackage{animate}
\usepackage{ifthen}
\begin{document}
\begin{frame}
\def\rg{2}
\begin{animateinline}[poster=first,controls]{8}%
\multiframe{40}{rt=0+.1,icount=1+1,rvo=5+0.0,rtheta=45+.0}
{% rt=time, rvo=initial v, g=2, rtheta=inital angle
\begin{tikzpicture}[scale=.75]
\clip (-1,-2) rectangle (15,10); % For body projected upward with angle rtheta=45
%\clip (-1,-8) rectangle (15,1);   % For body projected horizontally, rtheta=0
\draw[red] (0,0)--(13,0);         % ground horizontal line
\node (A\icount) at ({\rvo*cos(\rtheta)*(\rt)},{\rvo*sin(\rtheta)*(\rt)-0.5*\rg*(\rt)*(\rt)}) {};     % (x,y) position,
\path (A\icount) -- + ({0.5*\rvo*cos(\rtheta)},{0.5*(\rvo*sin(\rtheta)-\rg*(\rt))}) node (B\icount){};% (V_x,V_y) position,scaled by 0.5
\draw[thick,green,->] (A\icount.center) -- (B\icount-|A\icount);
\draw[thick,green,->] (A\icount.center) -- (B\icount|-A\icount);
\draw[thick,green,->] (A\icount.center) -- (B\icount);
\ifthenelse{\icount > 1}
{\draw ({\rvo*cos(\rtheta)*(\rt)},0) node[below]
{\tiny S=\rvo*cos(\rtheta)*(\rt)};                                % x displacement
\foreach \x in {.0,.1,...,\rt}
\filldraw [blue]
({\rvo*cos(\rtheta)*(\x)}, {\rvo*sin(\rtheta)*(\x)-0.5*\rg*(\x)*(\x)}) circle (1pt);}
{}
\filldraw [red]
({\rvo*cos(\rtheta)*(\rt)}, {\rvo*sin(\rtheta)*(\rt)-0.5*\rg*(\rt)*(\rt)}) circle (2pt);

\end{tikzpicture}
}
\end{animateinline}
\end{frame}
\end{document}

• This code seems overly complicated. I might suggest that you create nodes \node (A\icount) at ({\rvo*cos(\rtheta)*(\rt)},{\rvo*sin(\rtheta)*(\rt)-0.5*\rg*(\rt)*(\rt)}) {}; and \path (A\icount) -- + ({0.5*\rvo*cos(\rtheta)},{0.5*(\rvo*sin(\rtheta)-\rg*(\rt))}) node (B\icount) {};. Then you can draw using \draw[thick,dashed,green,->] (A\icount.center) -- (B\icount-|A\icount); etc which, I believe, makes the code easier to read and understand: it also means that the code for the curve only needs to be changed in one place (if a different curve is desired). Dec 7, 2014 at 17:41
• @A.Ellett -- Thanks for the insights. Apprecited and code improved. Dec 8, 2014 at 1:29
• Is there a way to accomplish a graph like this in an article class, and having all 5 vectors on the graph at the same time? Dec 9, 2014 at 4:20
• Yes, give me some minutes to modify the code and will update my answer. Dec 9, 2014 at 5:10

(OP here) After some work (and help from here!), I've come up with a graph that I hope others will find useful. Packages pgfplots and tikz are used, and tikz libraries positioning,calc, and plotmarks are used.

Everything is calculated from a list of variables under %variable definitions. I wasn't able how to find out to redefine \t before each set of coordinate calculations/drawing so each vector point has a different (lowercase) variable for time.

The angle label at the first vector consists of 2 identical circle nodes; one unclipped so the theta node can be positioned in reference to it, and one clipped to actually draw the circle/arc. You'll have to define/caculate your own circle size and angle where it works best.

Having xmax=11.5 lets the x axis end after the last vector. ymax is not equal to xmax so that the graph will take up more of the space/and be easier to see, for demonstrative purposes.

Tell me if you have any suggestions for optimizing/cleaning up the code or finding a neater way to label the start vector angle!

\begin{tikzpicture}[scale=1, transform shape]  %projectile motion
\begin{axis}[
width=10cm, %set bigger width
height=5cm,
xmin=0,xmax=11.5,
ymin=0,ymax=4,
xlabel=$x$,
ylabel=$y$,
axis x line = bottom,
axis y line = left,
axis line style={->},
%axis on top,
ticks = none,clip=false,
]

\tikzset{every mark/.append style={fill=white}}

%variable definitions
\def\g{-9.8} %gravity
\def\v{10} %velocity
\def\ang{51} %angle
\def\s{0.2}
\pgfmathsetmacro{\t}{0}
%flight path
dashed,
domain=0:10,
samples=100,]
{{\g*(x^2)/(2*\v^2*cos(\ang)^2)+x*tan(\ang)}}
node[midway,above]{$V_y=0$};

%vector at start
\coordinate (A) at (axis cs: {\v*cos(\ang)*\t}, {\v*\t*sin(\ang)+0.5*\g*(\t^2)});
\coordinate (B) at (axis cs: {\v*cos(\ang)*\t+\s*\v*cos(\ang)}, {\v*\t*sin(\ang)+0.5*\g*\t^2+\s*(\v*sin(\ang)+\g*\t)});
\draw[very thick,->](A)--(B)
node[midway,sloped,above]{$V$};
\draw[densely dashed,very thick,->](A)--(B|-A)
node[midway,below]{$V_x$};
\draw[densely dashed,very thick,->](A)--(B-|A)
node[midway,left]{$V_y$};

\path plot[mark=*] coordinates {(A)};

%dashed box around start vector
\draw[dashed](B-|A)--(B);
\draw[dashed](B|-A)--(B);

%vector at end
\pgfmathsetmacro{\a}{{-1*(2/\g)*\v*sin(\ang)}}
\coordinate (E) at (axis cs:{\v*cos(\ang)*\a},{\v*\a*sin(\ang)+0.5*\g*(\a^2)}){};
\coordinate (F) at (axis cs:{\v*cos(\ang)*\a+\s*\v*cos(\ang))}, {\v*\a*sin(\ang)+0.5*\g*\a^2+\s*(\v*sin(\ang)+\g*\a)});
\draw[very thick,->](E)--(F)
node[midway,sloped,above]{$V$};
\draw[densely dashed,very thick,->](E)--(F |- E)
node[midway,above]{$V_x$};
\draw[densely dashed,very thick,->](E)--(F-| E)
node[midway,left]{$V_y$};

\path plot[mark=*] coordinates {(E)};

%vector 1/2 up
\pgfmathsetmacro{\b}{{(-1*(2/\g)*\v*sin(\ang))/4}}
\coordinate (H) at (axis cs:{\v*cos(\ang)*\b},{\v*\b*sin(\ang)+0.5*\g*(\b^2)});
\coordinate (I) at (axis cs: {\v*cos(\ang)*\b+\s*\v*cos(\ang)},{\v*\b*sin(\ang)+0.5*\g*\b^2+\s*(\v*sin(\ang)+\g*\b)});
\draw[very thick,->](H)--(I)
node[midway,sloped,above]{$V$};
\draw[densely dashed,very thick,->](H)--(I-|H)
node[midway,left]{$V_x$};
\draw[densely dashed,very thick,->](H)--(I|-H)
node[midway,below]{$V_y$};

\path plot[mark=*] coordinates {(H)};

%vector halfway
\pgfmathsetmacro{\c}{{(-1*(2/\g)*\v*sin(\ang))/2}}
\coordinate (L) at (axis cs:{\v*cos(\ang)*\c},{\v*\c*sin(\ang)+0.5*\g*(\c^2)});
\coordinate (M) at (axis cs:{\v*cos(\ang)*\c+\s*\v*cos(\ang))},{\v*\c*sin(\ang)+0.5*\g*\c^2+\s*(\v*sin(\ang)+\g*\c)});
\draw[very thick,->](L)--(M)
node[midway,sloped,below]{$V$};

%T2 line; halfway up flight path
\draw[loosely dashed] (L) -- (axis cs:{\v*cos(\ang)*\c},0)
node[midway,right] {$\frac{t_\text{total}}{2}$};

\path plot[mark=*] coordinates {(L)};

%vector 1/2 down
\pgfmathsetmacro{\d}{{(-1*(2/\g)*\v*sin(\ang))*0.75}}
\coordinate (P) at (axis cs:{\v*cos(\ang)*\d},{\v*\d*sin(\ang)+0.5*\g*(\d^2)});
\coordinate (Q) at (axis cs:{(\v*cos(\ang)*\d+\s*\v*cos(\ang))},{\v*\d*sin(\ang)+0.5*\g*\d^2+\s*(\v*sin(\ang)+\g*\d)});
\draw[very thick,->](P)--(Q)
node[midway,sloped,below]{$V$};
\draw[densely dashed,very thick,->](P)--(Q|-P)
node[midway,above]{$V_x$};
\draw[densely dashed,very thick,->](P)--(Q-|P)
node[midway,left]{$V_y$};

\path plot[mark=*] coordinates {(P)};

%start vector angle label
\node[circle,minimum size=25pt] at (A) (circ) {};
\node[right] at (circ.30) {$\theta$};
\path[clip] (A) -- (B) -- (B|-A) -- cycle;
\node[circle,draw,minimum size=25pt] at (A) (circ) {};
\end{axis}
\end{tikzpicture}


And for the horizontal projection:

\begin{tikzpicture}[scale=2, transform shape]  %horizontal projection
%variable definitions
\def\g{-9.8} %gravity
\def\v{10} %velocity
\def\ang{51} %angle
\def\s{0.1}
\pgfmathsetmacro{\c}{{(-1*(2/\g)*\v*sin(\ang))/2}}

\begin{axis}[
width=.45\linewidth, %set bigger width
height=2.2in,
xmin={{\v*cos(\ang)*\c}},xmax=11.5,
ymin=0,ymax={\v*\c*sin(\ang)+0.5*\g*(\c^2)},,
xlabel=$x$,
ylabel=$y$,
axis x line = bottom,
axis y line = left,
y axis line style={-},
ticks = none,clip=false,
]

\tikzset{every mark/.append style={fill=white}}

%flight path
dashed,
domain={\v*cos(\ang)*\c}:10,
samples=100,]
{{\g*(x^2)/(2*\v^2*cos(\ang)^2)+x*tan(\ang)}};

%vector at end
\pgfmathsetmacro{\a}{{-1*(2/\g)*\v*sin(\ang)}}
\coordinate (E) at (axis cs:{\v*cos(\ang)*\a},{\v*\a*sin(\ang)+0.5*\g*(\a^2)}){};
\coordinate (F) at (axis cs:{\v*cos(\ang)*\a+\s*\v*cos(\ang))}, {\v*\a*sin(\ang)+0.5*\g*\a^2+\s*(\v*sin(\ang)+\g*\a)});
\draw[very thick,->](E)--(F)
node[right, at end,font=\tiny]{$\vec{V}$};
\draw[densely dashed,very thick,->](E)--(F |- E)
node[midway,above,font=\tiny]{$\vec{V}_x$};
\draw[densely dashed,very thick,->](E)--(F-| E)
node[midway,left,font=\tiny]{$\vec{V}_y$};

\path plot[mark=*] coordinates {(E)};

%vector at start
\pgfmathsetmacro{\c}{{(-1*(2/\g)*\v*sin(\ang))/2}}
\coordinate (L) at (axis cs:{\v*cos(\ang)*\c},{\v*\c*sin(\ang)+0.5*\g*(\c^2)});
\coordinate (M) at (axis cs:{\v*cos(\ang)*\c+\s*\v*cos(\ang))},{\v*\c*sin(\ang)+0.5*\g*\c^2+\s*(\v*sin(\ang)+\g*\c)});
\draw[very thick,->](L)--(M)
node[midway,sloped,above,font=\tiny]{$\vec{V}$};

\path plot[mark=*] coordinates {(L)};

%vector 1/2 down
\pgfmathsetmacro{\d}{{(-1*(2/\g)*\v*sin(\ang))*0.75}}
\coordinate (P) at (axis cs:{\v*cos(\ang)*\d},{\v*\d*sin(\ang)+0.5*\g*(\d^2)});
\coordinate (Q) at (axis cs:{(\v*cos(\ang)*\d+\s*\v*cos(\ang))},{\v*\d*sin(\ang)+0.5*\g*\d^2+\s*(\v*sin(\ang)+\g*\d)});
\draw[very thick,->](P)--(Q)
node[right, at end,font=\tiny]{$\vec{V}$};
\draw[densely dashed,very thick,->](P)--(Q|-P)
node[midway,above,font=\tiny]{$\vec{V}_x$};
\draw[densely dashed,very thick,->](P)--(Q-|P)
node[midway,left,font=\tiny]{$\vec{V}_y$};

\path plot[mark=*] coordinates {(P)};

%vector 3/4 down
\pgfmathsetmacro{\f}{{(-1*(2/\g)*\v*sin(\ang))*0.6}}
\coordinate (R) at (axis cs:{\v*cos(\ang)*\f},{\v*\f*sin(\ang)+0.5*\g*(\f^2)});
\coordinate (S) at (axis cs:{(\v*cos(\ang)*\f+\s*\v*cos(\ang))},{\v*\f*sin(\ang)+0.5*\g*\f^2+\s*(\v*sin(\ang)+\g*\f)});
\draw[very thick,->](R)--(S)
node[right, at end,font=\tiny]{$\vec{V}$};
\draw[densely dashed,very thick,->](R)--(S|-R)
node[midway,above,font=\tiny]{$\vec{V}_x$};
\draw[densely dashed,very thick,->](R)--(S-|R)
node[at end,below,font=\tiny]{$\vec{V}_y$};

\path plot[mark=*] coordinates {(R)};

%vector 1/4 down
\pgfmathsetmacro{\e}{{(-1*(2/\g)*\v*sin(\ang))*0.875}}
\coordinate (T) at (axis cs:{\v*cos(\ang)*\e},{\v*\e*sin(\ang)+0.5*\g*(\e^2)});
\coordinate (U) at (axis cs:{(\v*cos(\ang)*\e+\s*\v*cos(\ang))},{\v*\e*sin(\ang)+0.5*\g*\e^2+\s*(\v*sin(\ang)+\g*\e)});
\draw[very thick,->](T)--(U)
node[right, at end,font=\tiny]{$\vec{V}$};
\draw[densely dashed,very thick,->](T)--(U|-T)
node[midway,above,font=\tiny]{$\vec{V}_x$};
\draw[densely dashed,very thick,->](T)--(U-|T)
node[midway,left,font=\tiny]{$\vec{V}_y$};

\path plot[mark=*] coordinates {(T)};

\end{axis}
\end{tikzpicture}


Basically the same code, except you define the maximum y value as the equation of the height of the halfway point. y axis line style={-} is added so that no y-axis arrow exists; otherwise it would clash with the circular mark. Arrows are changed with \tikzset{>=stealth}.

• First of all, thank you all so much for so much effort. Please help. How would I give raise the initial node in the first picture on y-axis. Basically, giving it some y_0 as if the projectile was launched from some elevation and then landed at the ground?? Jun 25, 2020 at 2:52