随着时间的推移弹跳球

随着时间的推移弹跳球

我有一段笨拙的代码来绘制弹跳球随时间变化的高度。是否有可能进行优化?也许直接使用 tikz 数学库编写函数?此外,目前无法处理负时间输入。具有多个输入参数的宏如何调用 lua 代码?

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

它看起来像这样:

在此处输入图片描述

答案1

经过一番数学运算(关键词是几何级数),我找到了一个计算时间的解析解。现在有一个简洁的解决方案,但它比第一个慢得多。

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

它看起来像这样:

在此处输入图片描述

为什么我不能调用其中声明的函数xtick

答案2

使用 PSTricks 只是为了好玩。其余琐碎部分是为了简单起见而故意留下的。

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

在此处输入图片描述

相关内容