如果我编译这个文件:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[domain=-1:1,scale=5,samples=1000]
\draw plot (\x,{sqrt(-1/2-\x*\x+sqrt(1/4+2*\x*\x))});
\draw plot (\x,{-sqrt(-1/2-\x*\x+sqrt(1/4+2*\x*\x))});
\end{tikzpicture}
\end{document}
我明白了:
是否有可能避免右侧的间隙?我知道这与该曲线在该点处有垂直切线有关。另一方面,我知道如何毫无问题地绘制它;我所需要的只是使用参数化方式描述曲线。但迟早我会想要绘制一条我不知道这种描述的曲线,那时我想知道如何处理这个问题。
答案1
我认为这是由于 TeX/PGFMath 的不精确造成的,如果我们这样做的话
\documentclass[tikz]{standalone}
\tikzset{declare function={infty(\x)=sqrt(-1/2-\x*\x+sqrt(1/4+2*\x*\x));}}
\begin{document}
\tikz[domain=-1:1, scale=5, samples=100]
\draw plot ([/utils/exec=\pgfmathparse{infty(\x)}\typeout{\x => \pgfmathresult}]
\x,{ infty(\x)});
\end{document}
日志文件将包含
-1.0 => 0.00000
-0.998 => 0.03646
-0.996 => 0.05157
-0.994 => 0.06300
-0.992 => 0.07252
-0.99 => 0.08099
⋮ ⋮
-0.00655 => 0.00447
-0.00455 => 0.00000
-0.00255 => 0.00000
-0.00055 => 0.00000
0.00145 => 0.00000
0.00345 => 0.00447
⋮ ⋮
0.9909 => 0.07733
0.9929 => 0.06841
0.9949 => 0.05805
0.9969 => 0.04538
0.9989 => 0.02701
将范围分成-1:1
1001 个部分对于 PGFMath/TeX 来说并不是一个好的练习。
最快的解决方法是使用samples at
如下方法:
\tikz[domain=-1:1, scale=5, samples at={-500,...,500}]
\draw plot (\x/500,{ infty(\x/500)});
TeX/\foreach
非常擅长增加整数:
-1.0 => 0.00000
-0.99799 => 0.03660
-0.99599 => 0.05157
-0.99399 => 0.06300
⋮ ⋮
-0.006 => 0.00447
-0.004 => 0.00000
-0.002 => 0.00000
0.0 => 0.00000 ← symmetry!
0.002 => 0.00000
0.004 => 0.00000
0.006 => 0.00447
⋮ ⋮
0.99199 => 0.07266
0.99399 => 0.06300
0.99599 => 0.05157
0.99799 => 0.03660
1.0 => 0.00000
和所有计算机事物一样,TeX 也以 2 的幂运行,因此 1025 这样的数字也可以。(样本数为n该领域将被划分为n− 1 部分。)
您还可以通过将另一个图与域连接起来来回避该问题,1:-1
以便X= 1 将明确计算并以 结束路径以-- cycle
返回(-1, 0)
。
当然,还有fpu
库gnuplot
和其他外部工具。
但我还添加了一个稍微复杂的解决方案,在我看来,它可以让你的符号更清晰,并且用更少的点数!
代码
\documentclass[tikz]{standalone}
\tikzset{declare function={infty(\x)=sqrt(-1/2-\x*\x+sqrt(1/4+2*\x*\x));}}
\begin{document}
\tikz[domain=-1:1, scale=5]
\draw plot[domain=-1:1, samples at={-500,...,500}] (\x/500,{ infty(\x/500)})
-- plot[domain=1:-1, samples at={500,...,-500}] (\x/500,{-infty(\x/500)}) -- cycle;
\tikz[domain=-1:1, scale=5, samples=1025]{
\draw plot (\x, { infty(\x)});
\draw plot (\x, {-infty(\x)});
}
\tikz[scale=5, samples=1000]
\draw plot[domain=-1:1] (\x, { infty(\x)})
-- plot[domain=1:-1] (\x, {-infty(\x)})
-- cycle;
\tikz[scale=5]
\draw plot[domain=-1:0, samples at={-500,...,-300,-295,-290,...,0}] (\x/500, { infty(\x/500)})
-- plot[domain= 0:1, samples at={0, 5,..., 300, 301, 302,..., 500}] (\x/500, {-infty(\x/500)})
-- plot[domain= 1:0, samples at={ 500,..., 300, 295, 290,...,0}] (\x/500, { infty(\x/500)})
-- plot[domain=0:-1, samples at={0,-5,...,-300,-301,-302,...,-500}] (\x/500, {-infty(\x/500)})
-- cycle;
\end{document}
输出
(详细信息在交叉处。)
答案2
无论如何,以下是您可以如何解决这个问题元帖子,使用 OP 函数代替参数方程,并利用双纽线曲线。
\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
beginfig(1);
vardef f(expr x) = sqrt(-1/2 - x * x + sqrt(1/4 + 2 * x * x)) enddef;
numeric s; s = 1/8;
path limb;
limb = origin for x = s step s until 1: .. (x, f(x)) endfor {down};
limb := limb scaled 128;
path lemniscate;
lemniscate = limb
& reverse limb reflectedabout(left, right)
& limb reflectedabout(up, down)
& reverse limb rotated 180
& cycle;
draw limb withpen pencircle scaled 2 withcolor 7/8[red, white];
drawarrow lemniscate withcolor 2/3 blue;
endfig;
\end{mplibcode}
\end{document}
编译此可得到lualatex
:
这里的想法是使用函数在第一象限创建曲线的肢体(以粉红色显示),然后将该肢体的三个变换副本拼接在一起以形成完整的曲线(以蓝色箭头显示)。