给定一个分段形式的速度函数。目标是绘制位移s(t)
和加速度a(t)
。我不知道
Derive
当函数v(t)
为后缀形式时使用。- 是否有内置的 PostScript 宏可供集成。
\documentclass[pstricks,border=2mm]{standalone}
\usepackage{pst-plot}
\usepackage{amsmath}
\def\v{
u 1 lt { 1 }{
u 3 lt { (2-(u)) I2P }{
u 4 lt { -1 }{
u 6 lt { ((u)-5) I2P }{
1
} ifelse
} ifelse
} ifelse
} ifelse
}
\begin{document}
\pstVerb{/I2P {exec AlgParser cvx exec} def}%
\foreach \f/\l in
{
{x /u ED \v\space Derive}/{a(t)},% it does not work!
{x /u ED \v\space Integrate}/{s(t)} % it does not work!
}
{%
\begin{pspicture}(-1,-2)(8.5,3.5)
\psaxes{->}(0,0)(-1,-2)(8,3)[$t$,-90][$$,0]
\psset{plotpoints=200,linejoin=1,strokeopacity=.5}%
\psplot[linecolor=red,linewidth=1pt]{0}{7}{x /u ED \v}
\rput(4,3.25){\textcolor{red!50}{$v(t)$}}
\psplot[linecolor=blue,linewidth=2pt]{0}{7}{\f}
\rput(2,3.25){\textcolor{blue!50}{$\l$}}
\end{pspicture}}
\end{document}
预期输出(不包括轴和任何其他简单配件)应类似于使用 Mathematica 生成的以下屏幕截图。
答案1
使用 Python可以很容易地完成这一matplotlib
任务。pgf
进行计算的 Python 脚本:
import numpy as np
import matplotlib.pyplot as plt
dt = 0.1 # time resolution
t = np.arange(0, 8 + dt, dt)
v = np.ones(t.size)
v[np.logical_and(t >= 3, t <= 4)] = -1
v[np.logical_and(t >= 1, t <= 3)] = -2 / 2 * (t[np.logical_and(t >= 1, t <= 3)]
- 1) + 1
v[np.logical_and(t >= 4, t <= 6)] = 2 / 2 * (t[np.logical_and(t >= 4, t <= 6)]
- 4) - 1
a = np.gradient(v, dt)
s = np.cumsum(v) * dt
s -= s[0]
plt.plot(t, v, label=r"$v(t)$")
plt.plot(t, a, label=r"$a(t)$")
plt.plot(t, s, label=r"$s(t)$")
plt.legend()
plt.xlabel(r"$t$")
# save the resulting figure as PGF calls, if you use the file extension '.pdf'
# you'll directly get a PDF you could include in your document using
# `\includegraphics` (you would have to set up the RC-parameters to match the
# look of your document).
plt.savefig("velocity_displacement_acceleration.pgf")
将 LaTeX 文件打印成 PDF:
\documentclass[border=3.14]{standalone}
\usepackage{pgf}
\begin{document}
\input{velocity_displacement_acceleration.pgf}
\end{document}
结果:
答案2
可以尝试直接在 tikz/pstricks/metapost 中进行微分和积分。我最熟悉 metapost,所以我用它举了一个例子。对于积分,我只需使用欧拉方法。如果需要,可以使用更复杂的方法。由于我使用 ConTeXt,相关代码被包装到\starttext\startMPpage
和中\stopMPpage\stoptext
。
\starttext
\startMPpage[offset=3bp,instance=doublefun]
n=500;
tmax=8;
myeps=epsilon;
path a,s,v;
v=((0,1)--(1,1)--(3,-1)--(4,-1)--(6,1)--(8,1));
% define v merely as a function of t
def vt(expr t) =
ypart (v intersectionpoint ((t,-infinity)--(t,infinity)))
enddef;
% numerical differentiation
def dvdt(expr t) =
(vt(t+myeps)-vt(t-myeps))/(2*myeps)
enddef;
a = (0,dvdt(myeps)) --
for i=1 upto n-1:
((i/n)*tmax, dvdt((i/n)*tmax)) --
endfor
(tmax,dvdt(tmax-myeps));
% numerical integration
z0 = origin;
for i=1 upto n:
x[i] = x[i-1]+(1/n)*tmax;
y[i] = y[i-1]+(1/n)*tmax*vt(x[i-1]);
endfor;
s = z0 for i=1 upto n: -- z[i] endfor;
pickup pencircle scaled 1bp;
draw v scaled 1cm withcolor darkblue;
draw a scaled 1cm withcolor darkgreen;
draw s scaled 1cm withcolor "orange";
pickup pencircle scaled 0.5bp;
drawarrow ((0,0)--(8.5,0)) scaled 1cm;
drawarrow ((0,-1.5)--(0,2.5)) scaled 1cm;
\stopMPpage
\stoptext
一些问题:
- 该导数包含(几乎)垂直线。
- 积分并不完美。看看 4 和 6 处的值,它们应该为零。