8

I want to learn TikZ using "learn by example" approach because this way helps me to save time by skipping unnecessary concepts. I have made an example, it is a free fall diagram in PSTricks as follows.

enter image description here

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{multido}
\usepackage[nomessages]{fp}
\def\LoadConstants{}
\newcommand\const[3][3]{%
    \edef\temporary{round(#3}%
    \expandafter\FPeval\csname#2\expandafter\endcsname
        \expandafter{\temporary:#1)}%
        \edef\LoadConstants{\LoadConstants
            \noexpand\pstVerb{/#2 \csname#2\endcsname\space def}}%
}


\const[1]{G}{9.8}
\const[1]{Tfinal}{2.0}
\def\y(#1){-G/2*#1^2}
\const[1]{Yfinal}{\y(Tfinal)}

\SpecialCoor
\usepackage{siunitx}
\begin{document}
\begin{pspicture}[showgrid=false](3.5,\Yfinal)
    \LoadConstants
    \psline(1.5,0)(1.5,\Yfinal)
    \multido{\n=0.0+0.5}{5}
    {
        \const[1]{Yt}{\y(\n)}%
        \rput[r](*1.25 {\y(\n)}){$\SI{\Yt}{\meter}$}
        \psline(1.4,\Yt)(1.6,\Yt)
        \rput[l](*1.75 {\y(\n)}){$t=\SI{\n}{\second}$}
        \pscircle*(*3.5 {\y(\n)}){5pt}
    }
\end{pspicture}
\end{document}

I have a problem in evaluating algebraic expression and printing its value in TikZ. This is my attempt.

\documentclass[tikz,border=12pt]{standalone}


\def\G{9.8}
\def\Tfinal{2.0}
\def\y(#1){-\G/2*#1^2}
\def\Yfinal{\y(\Tfinal)}


\usepackage{siunitx}
\begin{document}
\begin{tikzpicture}
    \draw (1.5,0) -- (1.5,\Yfinal);
    \foreach \n in {0.0,0.5,...,2.0}
    {
        \draw ({1.25},{\y(\n)}) node {$\SI{\y(\n)}{\meter}$};
        \draw ({1.4},{\y(\n)}) -- ({1.6},{\y(\n)});
        \draw ({1.75},{\y(\n)}) node {$t=\SI{\n}{\second}$};
        \draw[fill=black] ({3.5},{\y(\n)}) circle (5pt);
    }
\end{tikzpicture}
\end{document}
5
  • If TikZ can work without fp package then it will be interesting. Apr 8 '13 at 9:00
  • You need to evaluate the \y(\n) before printing it in siunitx, do this: \def\Y(#1){\pgfmathparse{\y(#1)}\edef\yn{\pgfmathresult}} and replace: $\SI{\y(\n)}{\meter}$ by \Y(#1)$\SI{\yn}{\meter}$, note that the evaluation cannot be performed inside the SI macro (it does magic beyond belief).
    – nickpapior
    Apr 8 '13 at 9:03
  • @zeroth: OK. Thank you. I will delete my question shortly. Apr 8 '13 at 9:05
  • 2
    Could you please do not delete your question but post a correct solution - I would love to see it!
    – partial81
    Apr 8 '13 at 9:12
  • 1
    @partial81: OK. I will try applying zeroth's suggestion. Apr 8 '13 at 9:14
8

My suggestion. First it's not necessary to place the axe at 1.5. You can use 0 and if you need to add other objects then you can shift with a scope. I used \sisetup to get a light code. As you can see you can remove \Yfinal. The nodes tmp have the same width so it's possible to place the circle relatively to tmp.east. With this way it's possible to scale the picture. Personally I prefer \node at (x,y) instead of \draw (x,y) node.

update

\documentclass[tikz,border=12pt]{standalone}
\usepackage{siunitx}
\sisetup{round-integer-to-decimal,
         round-mode = places,
         round-precision = 1}% possible numprint
\begin{document}

% constants
\def\G{9.8}
\def\Tfinal{2.0}
\def\y(#1){-\G/2*#1^2}

\begin{tikzpicture}% [scale=.5] possible with the next code
    \draw (0,0) -- (0,{\y(\Tfinal)}); % you don't nedd to use \Yfinal
    \foreach \n in {0.0,0.5,...,\Tfinal}
    {       
     \draw (-0.1,{\y(\n)}) -- (0.1,{\y(\n)});
     \node[left] at (-0.25,{\y(\n)}) {\pgfmathparse{\y(\n)}\SI{\pgfmathresult}{\meter}};
     \node[right] (tmp) at (0.25,{\y(\n)}) {$t=\SI{\n}{\second}$};
     \fill ([xshift=.25 cm]tmp.east) circle (5pt);
    }
\end{tikzpicture}
\end{document}

enter image description here

5
  • Comments: No need to remove white spaces in \sisetup, use \Tfinal in foreach, no need to use $$ in the first \SI{}{}. Thank you for answering. Apr 8 '13 at 15:08
  • @Karl'sstudents I agree with all your remarks ! Apr 8 '13 at 15:42
  • @Karl'sstudents I disagree with the latter one. The spacing around = will be incorrect. (and siunitx does use math-mode in the most cases anyway). Apr 8 '13 at 22:07
  • @Qrrbrbirlbel: No problem because I did not say that in my previous comment. I have made the word "first" in bold face actually. And what Alain did is beyond my imagination. :-) Apr 8 '13 at 22:15
  • @Karl'sstudents And I meant the latter \SI. ;) The comment is more directed towards Alain (but he gets notified anyway). Apr 8 '13 at 22:17
6

enter image description here

Just in case if anyone would like to learn Asymptote as well, freefall.asy:

unitsize(5mm);
texpreamble("\usepackage["
  +"rm={oldstyle=true,tabular=true},"
  +"]{cfr-lm}");

real g=9.81;        // g constant
int n=5;            // number of time points
real dt=0.5;        // time interval
real tmax=(n-1)*dt; 

real h(real t){return t^2*g/2;};  // h(t) function

pair top=(0,0);
pair bottom=(0,-h(tmax));

real dx=0.6;                        // half of the tick width
guide tickMark=((-dx,0)--(dx,0));   // tick mark line

pair pos;
Label L;
real ballX=5;                       // x- coordinate of the ball
real ballR=0.5;                     // ball radius
path ball=scale(ballR)*unitcircle;  // the ball outline

pen startColor=darkblue;            
pen finalColor=orange;

pen ballColor(int i, int n){  // interpolates the color at i-th time reading
  return (n-1.0-i)/(n-1.0)*startColor+i/(n-1.0)*finalColor;
};

guide shadeScale=scale(0.6,1)*box((-dx,0),(dx,-h(tmax)));   // shade scale outline
axialshade(shadeScale,          // axial shading of the shade scale outline
  startColor+0.3*white, top,    // start color & position
  finalColor+0.3*white, bottom  // final color & position
);

transform toBallPos;
real t=0.0;

for(int i=0;i<n;++i){
  pos=(0,-h(t));
//  draw(shift(pos)*tickMark,white+1.6pt);
  draw(shift(pos)*tickMark,ballColor(i,n)+1.2pt);
  L=Label("$t=$"+format("%#5.1f",t)+"\,s");
  label(L,pos+(dx,0),E);
  label(((h(t)!=0)?"$-$":"")+format("%#7.2f",h(t))+"\,m",pos-(dx,0),W);
  toBallPos=shift(pos+(ballX,0));
  radialshade(toBallPos*ball,  // transform is applied by "*" on the left
    white,toBallPos*(0,0),0.07*ballR
   ,ballColor(i,n),toBallPos*(0,0),ballR); 
  t+=dt;
}

To get a standalone freefall.pdf, run asy -f pdf freefall.asy.

5
\documentclass[tikz,border=12pt]{standalone}

\def\G{9.8}
\def\Tfinal{2.0}
\def\y(#1){-\G/2*#1^2}
\pgfmathparse{\y(\Tfinal)}
\edef\Yfinal{\pgfmathresult}

\usepackage[nomessages]{fp}
\usepackage{siunitx}
\begin{document}
\begin{tikzpicture}
    \draw (1.5,0) -- (1.5,\Yfinal);
    \foreach \n in {0.0,0.5,...,\Tfinal}
    {       
        \draw ({1.25},{\y(\n)}) node[anchor=east] {\pgfmathparse{\y(\n)}\FPeval\temp{round(\pgfmathresult:1)}$\SI{\temp}{\meter}$};
        \draw ({1.4},{\y(\n)}) -- ({1.6},{\y(\n)});
        \draw ({1.75},{\y(\n)}) node[anchor=west] {\pgfmathparse{\n}\FPeval\temp{round(\pgfmathresult:1)}$t=\SI{\temp}{\second}$};
        \draw[fill=black] ({3.5},{\y(\n)}) circle (5pt);
    }
\end{tikzpicture}
\end{document}

As SI[round-mode=places,round-precision=1]... changes 0.0 to 0 and \pgfmathprintnumberto[precision=1]{\pgfmathresult}{\temp} produces a numerical format that is not compatible with \SI now I use \FPeval as a fallback.

8
  • There is a difference in positioning an object between PTricks and Tikz. \rput[l](x,y){object} stands for placing the left side of object at point (x,y) while \draw (x,y) node[left] {object} stands for placing object to the left side of point (x,y). Confusing to a newbie! Apr 8 '13 at 9:29
  • 3
    Instead of [left] use [anchor=west] which is the rput[l] equivalent. :)
    – nickpapior
    Apr 8 '13 at 9:39
  • @Karl'sstudents $\num[round-mode = places,round-precision = 1]{0.0}$ gives 0.0 and not 0 ?? Possible also \sisetup{round-integer-to-decimal} $\num[round-mode = places]{0}$ Apr 8 '13 at 13:02
  • @zeroth [anchor=west] is equivalent to [left]! The advantage of the last syntax is to authorize left=⟨offset⟩. Apr 8 '13 at 13:16
  • 2
    Thanks @Karl's students for not deleting your question, the answer and the discussion are really interesting and helpful!
    – partial81
    Apr 8 '13 at 14:17

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.