分类
LaTeX

MetaPost作图宏包mpgraphics的一点经验

MetaPost是常见的作图宏包, 对作2维图形是比较方便的. 而且他还能生成各种图片格式. 但是WinEdt自带的Metapost编译功能还不够强大, 稍显麻烦, 我后来都改用作图宏包mpgraphics来将作图代码和latex代码整合到一起.

基本的例子

mpgraphics的安装

首先下载mpgraphics.zip并解压出mpgraphics.sty. 你可以将它放到当前tex文档所在目录(同一目录). 这样就可以直接调用了. 也可以将其放到类似F:\CTEX\UserData\tex\latex\mpgraphics的目录中, 并刷新miktex的database: 在WinEdt中找到MikTex options->在General面板下找到那个Refresh FNDB, 单击即可.

mpgraphics的测试

作为测试, 试着运行如下的latex文件.




Test of MetaPost
Van Abel


  
  \begin{mpdisplay}
    draw fullcircle scaled 100pt withpen pencircle scaled 1pt;
    draw origin withpen pencircle scaled 3pt;
    label.rt(btex $O$ etex, origin);
  \end{mpdisplay}

事实上, 道理很简单, 就是把原来的beginfig(1)endfig;之间的代码放到现在的mpdisplay环境中.

运行时需要设置--shell-escape. 例如你用latex编译上面的文件的话, 那么要在Winedt的Options->Execution Modes面板下->找到LaTeX(位于Accessories列表下), 设置其运行附加开关(Switches)为%0 --shell-escape, 原来默认的是%0. 其他编译方式类似修改即可.

更加高级的用法可以参考mpgraphics的说明文档.

高级用法示例

LaTeX主文件test.tex内容如下



\input figs/mymetafun.mp

Test of MetaPost
Van Abel


  
  
[htbp] \centering \input figs/fig1.mp

而在test.tex同一目录下新建图片文件夹figs, 其中包含两个文件:mymetafun.mpfig1.mp, 他们分别包含了一些自定义函数与作图的源代码.

mymetafun.mp的示例
\begin{ltxpreamble}
 
\end{ltxpreamble}

\begin{mpdefs}
u:=10pt;

def draw_grid =
begingroup
 save p, pat, lenx, leny, N;
 pair p[]; path pat[];
 numeric lenx, leny, N;
 lenx:=25u; leny:=25u; N:=lenx/u;
 for i=0 upto (2N):
   p0:=(-lenx+i*lenx/N,leny);
   p1:=(-lenx+i*lenx/N,-leny);
   p2:=(-lenx,leny-i*leny/N);
   p3:=(lenx,leny-i*leny/N);
   if (i-5*floor(i/5)=0) :
   pickup pencircle scaled 1.5pt;
   else :
   pickup pencircle scaled .7pt;
   fi;
   draw p0--p1 withcolor 0.8*white;
   draw p2--p3 withcolor 0.8*white;
 endfor;
   drawdot(origin);
endgroup;
enddef;

def draw_parallelfour(expr A, drr, drl, lr, ll) =
begingroup
  save p;
  pair p[];
  p0:=A; p1:=A+unitvector(drr)*lr;
  p3:=A+unitvector(drl)*ll;
  p2:=p1+p3-p0;
  pickup pencircle scaled 1pt;
  draw p0--p1--p2--p3--cycle;
endgroup;
enddef;

def draw_manifold(expr A, B, deg) =
begingroup
  save dr, p;
  pair dr[], p[];
  dr0:=unitvector(1,2);
  dr1:=unitvector(5,1);

  p0=A;
  p3=A+dr0*6u;
  p1=A+dr1*10u;
  p2=p3+p1-p0+B;
  pickup pencircle scaled 1pt;
  draw p0{dr1 rotated deg}..p1;
  draw p1{dr0 rotated deg}..p2;
  draw p3{dr1 rotated deg}..p2;
  draw p0{dr0 rotated (1.2deg)}..p3;
endgroup;
enddef;

def draw_prep_angle(expr O, drec, len) =
begingroup
  save p, dr;
  pair p[], dr[];

  dr0:=unitvector(drec);
  dr1:=dr0 rotated 90;
  p1:=dr0*len;
  p3:=dr1*len;
  p2:=p1+p3;
  pickup defaultpen;
  draw (p1--p2--p3) shifted O;
endgroup;
enddef;

def draw_coordtwo(expr O, dr, len, nolab) =
begingroup
 save p, pat;
 pair p[]; path pat[];
 p0:=O-.3*len*dr;
 p1:=O+.7*len*dr;
 p2:=p1 rotatedaround(O,90);
 pat0:=p0--p1;
 drawarrow pat0;
 drawarrow pat0 rotatedaround(O,90);
 if nolab=1:
 else :
 label.bot(btex $x$ etex, p1);
 label.rt(btex $y$ etex, p2);
 fi;
endgroup;
enddef;

def draw_clip(expr pat) =
begingroup
    for i=0 upto 30:
        draw (-30u*dir(40)--30u*dir(40)) shifted (0,i*.3u);
        draw (-30u*dir(40)--30u*dir(40)) shifted (0,-i*.3u);
    endfor;
    clip currentpicture to pat;
endgroup;
enddef;
\end{mpdefs}
fig1.mp的示例
\begin{mpdisplay}
    draw fullcircle scaled 100pt withpen pencircle scaled 1pt;
    draw origin withpen pencircle scaled 3pt;
    label.rt(btex $O$ etex, origin);
\end{mpdisplay}

运行时首先直接运行test.tex, 如果你想得到pdf的图片, 这用pdflatex编译即可, 如果你想得到eps的图片直接用latex编译即可. 把编译后得到的图片复制到figs图片文件夹下. 这时你可以启用后面的插图命令(test.tex的14行), 而注释掉前面的mpgraphics作图命令(test.tex的13行). 这样别人就不需要任何设置就可以直接编译了, 换言之, 我们只是把mpgraphics拿来做生成pdf或者eps图片的中环节.

最终的文件下载.

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据