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 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

share|improve this question

2 Answers 2

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?

share|improve this answer
    
I found the problem with xtick, æpgfmath is not expandable: tex.stackexchange.com/questions/20265/… the solution is to use a macro and call it before setting the xtick with the result. –  Reza Feb 2 at 8:53

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

share|improve this answer
    
I plot it y versus x rather than t. Sorry for misunderstanding! –  In PSTricks we trust Feb 1 at 16:49
    
No problem, a very swift solution with pstricks! –  Reza Feb 2 at 7:56

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.