This my first attempt ever in making an animated image using latex.
I searched a lot here on stackexchange and learned about:
- defining an array
\def\array{{}} ...notation for arrays{1,...,5}= {1,2,3,4,5}- draw multiple images with the same code
\foreach \i in {...} { \begin{tikzpicture} ...code... \end{tikzpicture} - make a computation using
\foreach [evaluate = {...computation...}] - using conditionals if/else with
result = cond?v0:v1(cond true -> result = v0, cond false -> result = v1).
My aim is to draw two points moving on two lines with different "speeds" (say a and b), to show that if they start at the same time from the same point on the line, then they will meet again at the same point at the moment given by the least common multiple lcm(a, b).
In the example the "speeds", or better the times required for the points to go back to their initial positions, are 4 and 6, so the points will meet again at moment 12.
To make the animation smooth enough, I divided the first line in 24 (= 4*6) equal parts and the second line in 36 (= 6*6) equal parts. So in the initial arrays 0,...,24 mean that the first point moves from left to right, and 23,...,0 that it moves from right to left, and it does this 3 times (3*4 = 12). Analogously the second point move from left to right 0,...,36, and from right to left 35,...,0, and it does this 2 times (2*6 = 12).
I think these part of the code can be improved:
- the definitions of the initial arrays, is it possible to define them in a compact way? for example by concatenating arrays
{0,...,24}+{23,...,0}+{1,...,24}+... - to be able to compute the numbers on the left of the lines and above the points I wrote the
fillinside a dummyforeach, dummy because the loop is done only 1 time. Is it possibile to compute the numbers directly inside thefillcommand? - the computations of the numbers needed are too clumsy
Is the general structure of the code good or bad? How to improve it?
\documentclass[tikz, 12pt]{standalone}
\usepackage{tikz}
\begin{document}
% define the arrays containing the x axis coords to draw the moving points
\def\four{{0,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}}
\def\six{{0,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,
35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,
35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}}
% generate an image for each point (each array contain 145 points)
\foreach \i in {0,...,144}
{
\begin{tikzpicture}
% draw a frame so that size of all images is the same
\draw (-1,-2) rectangle (7,1);
% first line
\draw[gray, thick] (0,0) -- (6,0);
% compute the number on the left
% it is a multiple of 4 obtained by multiplying by 4 the integer part of the quotient of the current cycle index divided by the double of 24
\foreach [evaluate = {\multiple = int(4*floor(\i/48))}] \dummy in {1}
\fill (0,0) node [left]{\multiple};
% draw the point and compute the number above the point
% the number is computed as the integer part of the remainder of the division of the current cycle index divided by the double of 24, divided by 12, and when the remainder is 0 it is added 1
\foreach [evaluate = {\counter = int(int(floor(mod(\i,48)/12))+int(int(\i==0?0:1)*int(4*int(mod(\i,48)==0?1:0))))}] \dummy in {1}
\fill (\four[\i]/4,0) circle (2pt) node [above]{\counter};
% draw a bar on the line where the number above the point changes
\foreach \x in {0,3,6}
\draw (\x,0.1) -- (\x,-0.1);
% second line
\draw[gray, thick] (0,-1) -- (6,-1);
% compute the number on the left
\foreach [evaluate = {\multiple = int(6*floor(\i/72))}] \dummy in {1}
\fill (0,-1) node [left]{\multiple};
% draw the point and compute the number above the point
\foreach [evaluate = {\counter = int(int(floor(mod(\i,72)/12))+int(int(\i==0?0:1)*int(6*int(mod(\i,72)==0?1:0))))}] \dummy in {1}
\fill (\six[\i]/6,-1) circle (2pt) node [above]{\counter};
% draw a bar on the line where the number above the point changes
\foreach \x in {0,2,4,6}
\draw (\x,-1.1) -- (\x,-0.9);
\end{tikzpicture}
}
\end{document}
