这是我的tikz
图片代码,我的目标是让黎曼和图片的所有必要条件成为可以自动为我制作图片的命令。到目前为止,我已经实现了这一点,但我很难使子区间自动化,因为当我尝试将模式制作为或\ra+0.5
(\ra+\rstep
其中\rstep
每个矩形的宽度是多少)时,我总是出错。我也不想每次使用函数时都定义它。
最后,我想在开始时一次性定义端点a
和 b、子区间和函数。这样,我就可以制作不同子区间、不同和以及不同函数的多幅图片。n
#
a
b
\documentclass[11pt]{article}
\usepackage{tikz}
\newcommand\ra{-1} % ra = Riemann, a
\newcommand\ratwo{-0.5} % ra = Riemann, a
\newcommand\rb{4} % rb = Riemann, b
\newcommand\rbtwo{3.5} % rb = Riemann, b
\begin{document}
\textcolor{blue}{Left-hand Riemann Sum} and \textcolor{red}{Right-hand Riemann Sum}
\begin{tikzpicture}
\draw[<->] (\ra-0.5,0) -- (\rb+0.5,0);
\draw[<->] (0,\ra-0.5) -- (0,\rb+0.5);
\draw[dashed] (\ra,0) -- (\ra,1) node[above] {$a$};
\draw[dashed] (\rb,0) -- (\rb,-1) node[below] {$b$};
%Right-Hand
\foreach \x in {\ratwo,0,...,\rb} % <--- my issues
\draw[thick, fill=red!25] (\x-.5,0) -- (\x-.5,{sin(deg(\x))}) -- (\x,{sin(deg(\x))}) -- (\x,0) -- cycle;
%Left-Hand
\foreach \x in {\ra,-0.5,...,\rbtwo} % <--- my issues
\draw[thick, fill=blue!25] (\x,0) -- (\x,{sin(deg(\x))}) -- (\x+.5,{sin(deg(\x))}) -- (\x+.5,0) -- cycle;
\draw[ultra thick, <->, domain=\ra:\rb, smooth, samples=100, variable=\x] plot ({\x},{sin(deg(\x))});
\end{tikzpicture}
\end{document}
答案1
如果您的工作涉及数学和/或编程,您应该调查sagetex
位于这里在 CTAN 上。这可以让你访问一个计算机代数系统,称为智者以及 Python 编程语言。SAGE 不是 LaTeX 安装的一部分。您可以在 5 分钟内通过创建免费在线 Cocalc 帐户。另一种方法是将 SAGE 安装到您的计算机上。这可能会更麻烦,具体取决于您的计算机背景。考虑到这一点,这里有一个sagetex
解决方案:
\documentclass{article}
\usepackage{sagetex}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{tikz,pgfplots}
\usetikzlibrary{patterns}
\pgfplotsset{compat=1.15}
\begin{document}
\begin{sagesilent}
def RiemannRec(a,b,n,f):
t = var('t')
delta = (b-a)/n
LowerY = find_local_minimum(f,a,b)[0]-.5
UpperY = find_local_maximum(f,a,b)[0]+.5
step = .01
x_coords = [t for t in srange(a,b,step)]
y_coords = [f(t).n(digits=4) for t in srange(a,b,step)]
####################### Picture
output = r"\begin{tikzpicture}[scale=0.75]"
output += r"\begin{axis}["
output += r"xtick=\empty, ytick=\empty,"
output += r"grid = none,"
output += r"thick,black,"
output += r"scale=1,"
output += r"axis lines=center,"
output += r"line join=bevel,"
output += r"xmin=%f,xmax=%f,ymin= %f,ymax=%f]"%(a-.5,b+.5,LowerY, UpperY)
#### Left hand rectangles
for i in range(0,n):
output += r"\draw[color=Red,pattern=north west lines, pattern color=Red!90,opacity=.4] (%s,0) rectangle (%s,%s);"%(a+i*delta,a+(i+1)*delta,f(a+i*delta))
#### Right hand rectangles
for i in range(0,n):
output += r"\draw[color=NavyBlue,pattern=north east lines, pattern color=NavyBlue!90!white,opacity=.4] (%s,0) rectangle (%s,%s);"%(a+i*delta,a+(i+1)*delta,f(a+(i+1)*delta))
####### the function
output += r"\addplot[smooth] coordinates {"
for i in range(0,len(x_coords)-1):
output += r"(%s,%s)"%(x_coords[i],y_coords[i])
output += r"};"
#### a and b
output += r"\draw[dashed] (%s,0)--(%s,1) node[above] {$a$};"%(a,a)
output += r"\draw[dashed] (%s,0)--(%s,-1) node[below] {$b$};"%(b,b)
output += r""
output += r"\end{axis}"
output += r"\end{tikzpicture}"
return output
f(x) = (sin(x)).function(x)
fig1 = RiemannRec(-1.0,4.0,10,f) #a,b,n,function
\end{sagesilent}
This is the first diagram:
\begin{center}
\sagestr{fig1}
\end{center}
\begin{sagesilent}
f(x) = (sin(x)+cos(x^2)).function(x)
fig2 = RiemannRec(-1.0,4.0,6,f)
\end{sagesilent}
This is the second diagram:
\begin{center}
\sagestr{fig2}
\end{center}
\end{document}
创建一个 LaTeX 文档,将代码复制/粘贴到其中,您将获得如下输出:
针对该代码有一些观察结果。代码假设您有一个在从 a 到 b 的封闭有界区间上的连续函数。这保证了您的函数在该区间内达到其最大值和最小值。现在,SAGE 可以找到这些值并设置绘图屏幕的最小值和最大值,以便整个图形显示为:LowerY = find_local_minimum(f,a,b)[0]-.5 UpperY = find_local_maximum(f,a,b)[0]+.5
这意味着您无需花时间确定屏幕的绘图参数。屏幕的绘图参数设置如下:output += r"xmin=%f,xmax=%f,ymin= %f,ymax=%f]"%(a-.5,b+.5,LowerY, UpperY)
。RiemannRec(a,b,n,f)
使用 Python 代码创建一个函数来完成工作。您需要告诉它 a 和 b(左端点和右端点),以及 n(矩形数量)和 f(函数)。我对您的输出不满意,因为左黎曼积分和右黎曼积分的输出有时会覆盖另一个,所以我更改了不透明度,以便您可以同时看到两个输出。还要注意,您仍然需要进行一些调整,以便您对 a 和 b 位置的指示不会干扰图形。最后,请注意函数的调用有些笨拙f(x) = (sin(x)).function(x) fig1 = RiemannRec(-1.0,4.0,10,f)
。以这种方式编码不会产生错误。但是,您只需一行就可以获得输出。假设我尝试fig1 = RiemannRec(-1.0,4.0,10,cos(2*x))
运行它。您会在下图中看到我得到了一个弃用警告这事从 2009 年就开始了 (!)。
因此,您可以更自然地编写代码,但它会给出一个十多年来毫无意义的警告。最终,这个问题可能会得到解决,因此,当那一天到来时,您已经准备好了解决方案。
答案2
\documentclass[tikz, border=1cm]{standalone}
\pgfdeclarelayer{left}
\pgfdeclarelayer{right}
\pgfdeclarelayer{plot}
\pgfsetlayers{main, right, left, plot}
\tikzset{
pics/riemann sum/.style args={#1:#2:#3}{
code={
\pgfmathsetmacro{\leftpoint}{#1}
\pgfmathsetmacro{\rightpoint}{#2}
\pgfmathsetmacro{\movecount}{#3}
\pgfmathsetmacro{\step}{(\rightpoint-\leftpoint)/\movecount}
\begin{scope}[local bounding box=riemann]
\foreach \i [count=\c from 0] in {1,...,\movecount} {
\pgfonlayer{left}
\path[riemann sum/left sum] (\leftpoint+\c*\step, {temp(\leftpoint+\c*\step)}) rectangle (\leftpoint+\i*\step, 0);
\endpgfonlayer
\pgfonlayer{right}
\path[riemann sum/right sum] (\rightpoint-\c*\step, {temp(\rightpoint-\c*\step)}) rectangle (\rightpoint-\i*\step, 0);
\endpgfonlayer
}
\pgfonlayer{plot}
\draw [domain=#1:#2, riemann sum/riemann line] plot (\x, {temp(\x)});
\endpgfonlayer
\end{scope}
\draw[->, riemann sum/riemann axis] ([xshift=-5mm]riemann.west) -- ([xshift=5mm]riemann.east);
\draw[->, riemann sum/riemann axis] ([yshift=-5mm]riemann.south) -- ([yshift=5mm]riemann.north);
}
},
riemann sum/.search also=/tikz,
riemann sum/.cd,
function/.style 2 args={declare function={temp(#1)=#2;}},
left sum/.style={draw},
right sum/.style={draw},
riemann line/.style={},
riemann axis/.style={},
left/.style={left sum/.append style={#1}},
right/.style={right sum/.append style={#1}},
line/.style={riemann line/.append style={#1}},
axis/.style={riemann axis/.append style={#1}}
}
\newcommand{\riemannsum}[2][-1:1:2]{\pic[riemann sum/.cd,#2] {riemann sum=#1};}
\begin{document}
\begin{tikzpicture}
\riemannsum[-2:2:8]{
function={\x}{sin(\x r)},
left={thick, fill=blue!50},
right={thick, fill=yellow!50},
line={thick},
axis={thick}
}
\riemannsum[-2:2:12]{
function={\x}{sin(\x r) + cos(\x^2 r)},
left={thick, fill=blue!50},
right={thick, fill=yellow!50},
line={thick, red, samples=300, domain=-3:3},
axis={thick},
yshift=5cm,
}
\end{tikzpicture}
\end{document}