$H(x,y)=y^2+u(x)$
我正在尝试通过对 进行多次绘图来绘制形式为 的函数的高度线$\pm\sqrt{c-u(x)}$
。问题是,对于某些值,$c$
域很棘手且不易计算。我尝试通过绘图来绕过这个问题$\pm\max{\sqrt{c-f(x)},0}$
(被 x 轴“吸收”),但这会导致那些可见的、令人讨厌的“峰值”。我需要一个聪明的想法来摆脱它们。
我的代码:
\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}[
declare function = {u(\x) = 0.5*pow(\x-2,3)-\x+4;}
]
\draw[->] (-0.5,0)--(4.5,0);
\draw[->] (0,-2.2)--(0,2.2);
\clip (-0.5,-2.2) rectangle (4,2.2);
\def\samp{200}
\foreach \c in {0,0.8,...,3.6}
{
\draw plot[domain=-0.5:4, samples=\samp] (\x, {sqrt(max(\c-u(\x),0)))});
\draw plot[domain=-0.5:4, samples=\samp] (\x, {-sqrt(max(\c-u(\x),0)))});
}
\end{tikzpicture}
\end{document}
结果:
答案1
看起来你需要做的就是增加样本量。因为这需要更长的时间,也许你只能在 y==0 附近进行,即有一个过程(200 个样本)和一个有限的精细区域(2000 个样本)。或者你只是花时间等待。
\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}[
declare function = {u(\x) = 0.5*pow(\x-2,3)-\x+4;}
]
\draw[->] (-0.5,0)--(4.5,0);
\draw[->] (0,-2.2)--(0,2.2);
\clip (-0.5,-2.2) rectangle (4,2.2);
\def\samp{2000}% <<--
\foreach \c in {0,0.8,...,3.6}
{
\draw plot[domain=-0.5:4, samples=\samp] (\x, {sqrt(max(\c-u(\x),0)))});
\draw plot[domain=-0.5:4, samples=\samp] (\x, {-sqrt(max(\c-u(\x),0)))});
}
\end{tikzpicture}
\end{document}
附言:如果您有更多这样的图纸,并且担心将它们合并到更大的 Latex 文档中,可以采用以下方法:
- 通过至少一个单独的 Latex 文档创建图纸
- 另存为 .eps
- 将 .eps 图像加载到您的关键文档中
参见章节“7.1 导出为 pdf/eps“在大型 tikz 手册(pgfplots.pdf)中。
答案2
为了比较,编译时使用渐近线。
size(7cm);
import contour;
// H(x,y)=y^2+u(x) with u(x)=0.5*(x-2)^3-x+4;
real f(real x, real y){ return y^2+0.5*(x-2)^3-x+4;}
// Array c={0,0.8,...,3.6}
real[] c;
for (int i=0; i<=36; i=i+8) { c.push(i/10); }
draw((-0.5,0)--(4.5,0),Arrow);
draw((0,-2.2)--(0,2.2),Arrow);
// one-dimensional pen array
pen[] pp={red, green, blue, gray};
pp.cyclic=true; // See 6.12 Arrays
// two-dimensional guide array
guide[][] g=contour(f,(-0.5,-2.2),(4,2.2),c,400); // 400 is ngraph!
guide[] G=concat(... g); // See 6.12 Arrays
for (int i=0; i<G.length; ++i)
draw(G[i],pp[i]);
可以增加默认分辨率ngraph x ngraph
(此处 ngraph 默认为),以获得更高的准确性。100
另请参阅8.35 contour
(主要文档)以了解更多信息。
您可以像这样手动处理每个指南:
size(7cm);
import contour;
// H(x,y)=y^2+u(x) with u(x)=0.5*(x-2)^3-x+4;
real f(real x, real y){ return y^2+0.5*(x-2)^3-x+4;}
// Array c={0,0.8,...,3.6}
real[] c;
for (int i=0; i<=36; i=i+8) { c.push(i/10); }
draw((-0.5,0)--(4.5,0),Arrow);
draw((0,-2.2)--(0,2.2),Arrow);
// two-dimensional guide array
guide[][] g=contour(f,(-0.5,-2.2),(4,2.2),c,400); // 400 is ngraph!
guide[] G=concat(... g); // See 6.12 Arrays
write(G.length); // Outputs: 7
draw(Label("$0$",EndPoint),G[0],red,Arrow);
draw(Label("$1$",BeginPoint),G[1],green,Arrow);
draw(Label("$2$",BeginPoint),G[2],blue+dashdotted,Arrow);
draw(Label("$3$",BeginPoint),G[3],red+dashed,Arrow);
draw(Label("$4$",EndPoint),G[4],gray,Arrow);
draw(Label("$5$",BeginPoint),G[5],magenta,Arrow);
draw(Label("$6$",EndPoint),G[6],cyan,Arrow);
答案3
我们可以用 Ti 来做到这一点钾Z,但使用的样本也较少。但在这种情况下,我们需要帮助 Ti钾Z做任务。
只需选择一种数值微积分软件,然后找出多项式何时具有多个根(三次方程),然后求出它的根。接下来,只绘制正值部分。
我认为在这种情况下钾Z 可能可以处理数学(卡尔达诺和朋友或牛顿-拉夫森?)但我们在样本中节省的时间将用于数学,因此不值得付出努力。
我的示例每个图最多有 100+100 个样本。如果我们将曲线分成更多部分并在根部附近放置更多样本,这个数字可以减少。
这是我的代码(我使用 Python 来查找根):
\documentclass[tikz,border=2mm]{standalone}
\tikzset
{% abs is to prevent rounding errors causing a 'false negative' number
declare function={f(\x,\y)=sqrt(abs(-0.5*\x*\x*\x+3*\x*\x-5*\x+\y));},
my color/.style={blue, opacity={-0.4*abs(2-#1)+1.2}}
}
\begin{document}
\begin{tikzpicture}
\draw[-latex] (-0.5,0)-- (4.5,0);
\draw[-latex] (0,-3) -- (0,3);
\def\samp{100}
% one piece
\foreach\d/\r in {0/0,0.4/0.0842,0.8/0.1786,1.2/0.2871,2.8/3.7129,3.2/3.8214,3.6/3.9158,4/4} \foreach\j in {-1,1}
\draw[my color=\d] plot[domain=-0.5:\r, samples=\samp] (\x, {\j*f(\x,\d)}) -- (\r,0);
% two pieces
\foreach\d/\r/\s/\t in {1.6/0.4171/2.4437/3.1392,2/0.5858/2/3.4142,2.4/0.8608/1.5563/3.5829,2.5443/1.1835/1.1835/3.633} \foreach\j in {-1,1}
\draw[my color=\d] plot[domain=-0.5:\r, samples=\samp] (\x, {\j*f(\x,\d)}) -- (\r,0)
(\s,0) -- plot[domain=\s:\t, samples=\samp] (\x, {\j*f(\x,\d)}) -- (\t,0);
\fill[blue] (2.8165,0) circle (1pt);
\end{tikzpicture}
\end{document}
输出结果如下: