6

I have this clumsy code to plot the height of a bouncing ball over time. Is there a possibility for optimization? Perhaps writing the functions directly with the tikz math library? Also at the moment negative time input can't be handled. And how can macros with more then one input argument call lua code?

\documentclass[tikz]{standalone}
\usepackage{fontspec}
\usepackage{pgfplots}
\usepackage{luatextra}

\begin{luacode}
  function height(h0, idx)
    return h0*(3/4)^(math.abs(idx))
  end
  function time(h0, idx)
    t = math.sqrt(2*height(h0, 0)/9.81)
    for i=1,idx,1 do
      t = t+2*math.sqrt(2*height(h0, i)/9.81)
    end
    return t
  end 
  function offset(h0, idx)
    o = 0
    if idx > 0 then
      o = time(h0, idx-1)+(time(h0, idx)-time(h0, idx-1))/2
    end
    return o
  end
\end{luacode}

\makeatletter
\pgfmathdeclarefunction{luaheight}{1}{%
  \begingroup
    \pgfkeys{/pgf/fpu,/pgf/fpu/output format=sci}%
    \pgfmathparse{#1}%
    \edef\pgfmathresult{\directlua{tex.print("" .. height(10,\pgfmathresult))}}%
    \pgfmathsmuggle\pgfmathresult%
  \endgroup
}%
\pgfmathdeclarefunction{luatime}{1}{%
  \begingroup
    \pgfkeys{/pgf/fpu,/pgf/fpu/output format=sci}%
    \pgfmathparse{#1}%
    \edef\pgfmathresult{\directlua{tex.print("" .. time(10,\pgfmathresult))}}%
    \pgfmathsmuggle\pgfmathresult%
  \endgroup
}%
\pgfmathdeclarefunction{luaoffset}{1}{%
  \begingroup
    \pgfkeys{/pgf/fpu,/pgf/fpu/output format=sci}%
    \pgfmathparse{#1}%
    \edef\pgfmathresult{\directlua{tex.print("" .. offset(10,\pgfmathresult))}}%
    \pgfmathsmuggle\pgfmathresult%
  \endgroup
}%
\makeatother

\begin{document}
\begin{tikzpicture}
\begin{axis}
  \addplot[domain=0:luatime(0)] {luaheight(0)-9.81/2*x^2};
  \foreach \p in {1,...,5} {
    \addplot[domain=luatime(\p-1):luatime(\p)] {luaheight(\p)-9.81/2*(x-luaoffset(\p))^2}; 
  }    
\end{axis}
\end{tikzpicture}
\end{document}

And it looks like this:

enter image description here

8

After some math (keyword is geometric series) I found an analytical solution to calculate the time passed. Now there is a neat solution, but it's way slower then the first one.

\documentclass[tikz]{standalone}
\usepackage{fontspec}
\usepackage{pgfplots}
\usepackage{luatextra}
\begin{document}
\begin{tikzpicture}[
  declare function={
    bounce(\hz,\idx) = \hz*(3/4)^\idx;
    duration(\hz,\idx) = sqrt(2*\hz/9.81)*(1+sqrt(3)*(1-sqrt(3/4)^\idx)/(1-sqrt(3/4)));
    offset(\hz,\idx) = duration(\hz,\idx-1)+(duration(\hz,\idx)-duration(\hz,\idx-1))/2;
    flight(\hz,\idx,\t) = bounce(\hz,\idx)-9.81/2*(\t-offset(\hz,\idx))^2;
  }
]
  \begin{axis}[
      xmin=0, xmax=20,
      ymin=0, ymax=12,
      thick,
      axis lines=left,
      xtick={14.047},
      %xtick={{duration(10,8)}},
      xticklabels={$t_c$},
      yticklabels={},
      xlabel={Zeit},
      ylabel={Höhe},
      tick style=transparent,
  ]
    \addplot[red,domain=0:{duration(10,0)}] {bounce(10,0)-9.81/2*\x^2};
    \addplot[dashed,gray]coordinates {({duration(10,8)},0) ({duration(10,8)},12)};
    \foreach \p in {9,...,20} {
      \addplot[domain={duration(10,\p-1)}:{duration(10,\p)}] {flight(10,\p,\x)}; 
    }
    \foreach \p in {1,...,8} {
      \addplot[red,domain={duration(10,\p-1)}:{duration(10,\p)}] {flight(10,\p,\x)}; 
    }
    \addplot[red]coordinates{({duration(10,8)},0) (20,0)};
  \end{axis}
\end{tikzpicture}
\end{document}

It looks like this:

enter image description here

Why can't I call a declared function in the xtick?

4

With PSTricks just for fun. The remaining trivial parts are intentionally left for the sake of simplicity.

\documentclass[pstricks,border=12pt]{standalone}
\SpecialCoor
\psset{linecolor=red}
\begin{document}
    \begin{pspicture}(11,10)
        \foreach \i in {0,...,10}{\parabola(\i,0)(!\i\space .5 add  10 .65 \i\space exp mul)}
    \end{pspicture}
\end{document}

enter image description here

  • I plot it y versus x rather than t. Sorry for misunderstanding! – kiss my armpit Feb 1 '14 at 16:49
  • No problem, a very swift solution with pstricks! – Reza Feb 2 '14 at 7:56

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.