Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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}
share|improve this question
    
If TikZ can work without fp package then it will be interesting. –  Please don't touch 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). –  zeroth Apr 8 '13 at 9:03
    
@zeroth: OK. Thank you. I will delete my question shortly. –  Please don't touch 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. –  Please don't touch Apr 8 '13 at 9:14

3 Answers 3

up vote 7 down vote accepted

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

share|improve this answer
    
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. –  Please don't touch Apr 8 '13 at 15:08
    
@Karl'sstudents I agree with all your remarks ! –  Alain Matthes 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). –  Qrrbrbirlbel 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. :-) –  Please don't touch 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). –  Qrrbrbirlbel Apr 8 '13 at 22:17
\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.

share|improve this answer
    
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! –  Please don't touch Apr 8 '13 at 9:29
3  
Instead of [left] use [anchor=west] which is the rput[l] equivalent. :) –  zeroth 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}$ –  Alain Matthes Apr 8 '13 at 13:02
    
@zeroth [anchor=west] is equivalent to [left]! The advantage of the last syntax is to authorize left=⟨offset⟩. –  Alain Matthes 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

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.