使用 MetaPost 绘制抛物线

使用 MetaPost 绘制抛物线

我一直收到这个错误:“!三级表达式不能以 `[' 开头。”

beginfig(1);
numeric u,a,x;
vardef yb(expr x)=
    x*x-6*x+8;
enddef;
pair igreka[],igrekb[];
path paraboola,paraboolb;
u := 1cm;
drawarrow (-4u,0u)--(6u,0u);
drawarrow (0u,-4u)--(0u,9u);
for i=0 upto 16:
    igreka[i]:=((i/2)*u,((i/2)**2-6*(i/2)+8)*u);
endfor;
paraboola:=igreka[0]..igreka[1]..igreka[2]..igreka[3]..[igreka[4]..igreka[9]..igreka[10]..igreka[11]..igreka[13]..igreka[14]..igreka[15]..igreka[16];
draw paraboola;
endfig;

我正在尝试绘制一条抛物线,但无法使用我的代码中显示的列表(igreka[] 列表)绘制路径。

我还想知道是否有办法通过某些 for 循环以更简单的方式定义抛物线的路径,例如:

beginfig(1);
numeric u,a,x;
vardef yb(expr x)=
    x*x-6*x+8;
enddef;
pair igreka[],igrekb[];
path paraboola,paraboolb;
u := 1cm;
drawarrow (-4u,0u)--(6u,0u);
drawarrow (0u,-4u)--(0u,9u);
for i=0 upto 16:
    igreka[i]:=((i/2)*u,((i/2)**2-6*(i/2)+8)*u);
endfor;
EXAMPLE HERE: for i=1 upto 16:
    paraboola:=igrek[1]..igrek[2].. ..igrek[16];
endfor;
draw paraboola;
endfig;

答案1

第一个问题只是一个拼写错误:你写的[igreka[4]应该是igreka[4]。所以 MetaPost 抱怨你不应该以 开头你的表达式[

MetaPost 与 TeX 类似,是一种基于宏的语言。因此,像 这样的控制结构for不仅限于其主体中包含完整语句,其主体还可以包含部分语句,例如.. igreka[i]

beginfig(1);
numeric u,a,x;
vardef yb(expr x)=
    x*x-6*x+8;
enddef;
pair igreka[],igrekb[];
path paraboola,paraboolb;
u := 1cm;
drawarrow (-4u,0u)--(6u,0u);
drawarrow (0u,-4u)--(0u,9u);
for i=0 upto 16:
    igreka[i]:=((i/2)*u,((i/2)**2-6*(i/2)+8)*u);
endfor;
paraboola := igreka[0]
    for i=1 upto 16: .. igreka[i] endfor;
draw paraboola;
endfig;
bye;

答案2

我知道这已经很老了,而且我看到原始答案解决了 OP 中的问题,但如果有人来这里希望找到一种“用 Metapost 绘制抛物线”的好方法,我认为可能值得添加另一种解决方案,也许更通用一些。

在此处输入图片描述

这被包裹在魔法中luamplib并利用了mplibtextextlabel魔法,所以你需要用 来编译它lualatex

\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
beginfig(1);

    path ff;  % first the function and its curve
    vardef f(expr x) = x * x - 6 * x + 8 enddef;
    ff = (0, f(0)) for x = 1 upto 12: .. (x, f(x)) endfor;
   
    % scale the curve nicely in each dimension
    numeric u, v; u = 20; v = 2;
    ff := ff xscaled u yscaled v;

    % this is just one way to make nice axes
    path xx, yy;
    bboxmargin := 20pt;
    xx = subpath (0, 1) of bbox ff;
    xx := xx shifted (0, -ypart point 0 of xx);
    yy = subpath (4, 3) of bbox ff;
    yy := yy shifted (-xpart point 0 of yy, 0);

    % draw and label the function curve
    draw ff withcolor 2/3 red;
    label.top("$y=x^2 - 6x + 8$", point infinity of ff) 
        withcolor 2/3 red;

    % draw and label the axes
    drawarrow xx; label.rt("$x$", point 1 of xx);
    drawarrow yy; label.top("$y$", point 1 of yy);

    % add some scales along the axes
    for x = 2 step 2 until 12:
        draw (x * u, 0) -- (x * u, -3);
        label.bot("$" & decimal x & "$", (x * u, -3));
    endfor
    for y = 20 step 20 until 80:
        draw (0, y * v) -- (-3, y * v);
        label.lft("$" & decimal y & "$", (-3, y * v));
    endfor

endfig;
\end{mplibcode}
\end{document}

相关内容