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文件.
\documentclass{amsart}
\usepackage{mpgraphics}
\title{Test of MetaPost}
\author{Van Abel}
\date{}
\begin{document}
\maketitle
\begin{mpdisplay}
draw fullcircle scaled 100pt withpen pencircle scaled 1pt;
draw origin withpen pencircle scaled 3pt;
label.rt(btex $O$ etex, origin);
\end{mpdisplay}
\end{document}
事实上, 道理很简单, 就是把原来的beginfig(1)与endfig;之间的代码放到现在的mpdisplay环境中.
运行时需要设置--shell-escape. 例如你用latex编译上面的文件的话, 那么要在Winedt的Options->Execution Modes面板下->找到LaTeX(位于Accessories列表下), 设置其运行附加开关(Switches)为%0 --shell-escape, 原来默认的是%0. 其他编译方式类似修改即可.
更加高级的用法可以参考mpgraphics的说明文档.
高级用法示例
LaTeX主文件test.tex内容如下
\documentclass{amsart}
\usepackage{mpgraphics}
%\NoProcess[2]
\input figs/mymetafun.mp
\title{Test of MetaPost}
\author{Van Abel}
\date{}
\begin{document}
\maketitle
\begin{figure}[htbp]
\centering
\input figs/fig1.mp
%\includegraphics{figs/test-fig1}
\end{figure}
\end{document}
而在test.tex同一目录下新建图片文件夹figs, 其中包含两个文件:mymetafun.mp与fig1.mp, 他们分别包含了一些自定义函数与作图的源代码.
mymetafun.mp的示例
\begin{ltxpreamble}
\usepackage{bm}
\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图片的中环节.
最终的文件下载.

发表回复