Art_of_MetaPost.pdf《metapost的艺术》(中文metapost简明教程)插图3蒙索引48插图个简单的 METAPOST小意..2单位其实就是一种全局变量3变量做单位用元正态分布的例子形的重心6使用色了。直线和曲线8控制点的作用9通过的角度计第山0便用dir控制曲线形状与。的不同不同 tension的影响13不同curl的曲线形状14自定义pen14列度15一把直尺的刻丿16 infont创建的字困17不共线三点确定 transfor18 Cantor渠合1719if小意20三叶玫瑰线groupin卫g示例21saveinterin··223 primary vS expr2424 METAPOST中的词因25算符优先顺闬2626不同线型作图2827线型研究....2928 dashed怎么利用线型2929端点样式30接头样式31 miterlimit的影响3232箭头示意33自定义头.表格adto的等价用困4第一部分理论篇本部分讲述一些使用 ME TAPOST作图的理论知识,从 ME TAPOST的历史开始,然后讲述MEτP○sτ使用的变量类型,以及其中使用的控制结构,最后讲述作图的一些基本概念和方法。要点:熟悉使用MET∩POsT作图以及插入到所需位置的基本流程。理解METP¤ST是一个宏语言的特征。熟练的使用 METAPOST的几种基本数据类型。能够使用MET∩POsT的控制结构写出简单的程序。能够运用所学会的编程知识看懂系统写的宏。逐步积累一点点常用的宏。●能够玶解并运用客种作图的基本手段实现自己的作图目的。难怎么正确的理解 METAPOST是一个宏语言。·如何利用已有的方式构造合适的path如何利用线性方程纽简单的计算出所需要的未知数如何正确理解de「和 varden的不同。如何实现宏的后缀。如何定义算符,以及不同级别算符的区别。怎么理解线型以及定义自己的线型。1 METAPO57的历史1 METAPOST的历史METAPOST作为一门语言,其发生,发展,到今天有着自己的历史。人牛 Donald e. Knuth为其巨著〖皿的排版头痛丛而创作了①X这个排版言,同时为了为该排版系统定制字体,发了METAFON中 METAPOST就是由 John D.Ioby基于 METAFON创造,学习 METAPOST应该参考他所作的 METAPOST手册Hobc,本文不希望写成如此的于册,而是希望通过一些某本概念方法的介绍,激发读者使用 ME TAPOST的欲望ME TAFONT输出的是点阵字型,而 METAPOST所输出却是 POSTSCRIPT2L METAPOST从MET∩FoNT中借用了一些基本操纵图形的工具,也从 POST SCRII中获得了更多的新特性,如clipping(剪辑), shading(渐变色), dashed lines(虚线)等等。在网上可以找到很多与 ME TAPO5T相关的资料,下面列出少许供参考:http://cm.bell-labs.com/who/hobby/metapost.htmlixeJohnD.Hobby]mEtapoSt官方主页了,上面有关于 METAPOST的历史资料,如何安装 METAPOST,怎么利用METAPO5T的例子,手册, mail listhttp://www.tug.org/metapost.html这是TUG的METAPOST介绍网页,有很多教程(在本文的参考手册中可以找到部分相同的),相关的应用,相关的作图语言(如 Asymptote)、程http://tex.loria.fr/prod-graph/zoonekynd/metapost/metapost.htm1,全是例子,如果你有耐心把这些程序全部写完,你马上就能成为一个 METAPOST高手,这里面的例子从简单到困难,本文有些例子可能也会从中选择出来。ht:/b.cte.org/ forums/ index.php? showforum=35,这是国内人气最旺的(x论坛的 METAPOST分,由 love老兄主持,有问题可以去问问,有好东西可以去分享,有经验可以去交流。http://melusine.eu.org/syracuse/metapost/这是一个法文站点,上面除了一些文档以外(如obc的 prosper版本)还含有大量的动画,漂亮的 galleries,使用 METAPOST做成的课件,感谢 changrong提供。另外该网站还有 POST SCRIPT, PSTricks,SWF的相关示例。这里顺带着讲述一些作图的方法。在 Windows大行其道的今天,很多人都被漂亮的GUI所迷惑,熟悉了怎么使用鼠标拖拖拉拉,反倒生疏了键盘。为了获得-些文档中的图片,想来一般人都尝试过 Windows的画笔,甚至是 MS Office中的作图工具,另外徼软还提供了 MS Visio。这些作图工具的特点在于用户不必关心准确的位置,只需要到一些面板上寻找按钮到画布上拖拉,就能获得些图形,Ⅴisio稍微好点带有标尺,可以较为精桷的定位,同吋Ⅴisio的输岀可以选择矢量图形格式,加上大量的图形元件,可以很方便的实现多种图形的绘制。另外,徼软在 MS Office2003叶捣鼓出来了自己的mdi格式,大家可以猜测微软的日的。在 Windows平台下,有不少类似的作图工具,如 Adobe的平面设计“专家” Photoshop,矢量图形绘制 illustrator,还有 Corel的点阵矢量包打的( orel draw,另外和 visio有的一拼的还有 Smart draw等等。如果算上开源作品中精良的GIMP和 Inkscape,那真是百家齐放。Linx下面还有很多类似的软件,也有移植到 Windows下的,如xfig、dia等等, Open Office里面的 oodraw和 KDE Ofce套装中的 kivio,也算是不错的Ⅴisio替代品。可是有人能做到像 AutoDesk的 AutoCaD那样精准的图形么?“哦,”你也许会抱怨道,“我不需要这种图形。”那么这里不妨劝你放弁 METAPOST,因为 METAPOST要处理获得的往往是精桷的图形,而随意画出来的图形却很难用MET∩PoST画出来。另外,你不能指望可以仅仅用鼠标就让METAFONT是 Addison Wesley Publishing公司的注册标2 POSTSCRIPT1M是 Adobe System Inc,的注册商标1 METAPO57的历史6METAPOST服服贴贴的为你画出各种图形,正如 AutoCAD一样,真正的高手很少完仝用鼠标,并且结合VⅤ Visual lisp有时才能高效的绘制出所需要的图形。“哦, METAPOST这么繁啊!我不想用了……”好吧,这算是我对你打的预防针,因为的确学习 ME TAPOST你需要更大的热情和精力,看看上面那个全部是例子的网页吧,难道精美的图片不值得我们的热情和精力么?当你下定决心的时候,就让我们廾始 ME TAPOST之旅吧!1.1我的 METAPOST在哪里?如果你在 Windows下面,安装了套装,或者你是独立的安装了 MikTEX发行版,那么你可以用 MikTEX的 Package Manager查看自己的 METAPOST是合已经搞定,没有的话可以在其中完成安装。(区x套装的fl版用户,如果你没有删除过 METAPOST,你就可以直接使用METAPOST了。如果你在 Linux下面,安装的是 tetex,一般说来 METAPOST凵经装好了,你可以用s whereis mpost或者p whereis mp看看该程序是否在你的PATH中。如果没有安装,可以依照各自发行版安装对应的 tetex,如 FedoraCore用户可以考虑使用yum install tetex tetex-fonts tetex-latex tetex-xdvi Vtetex-afm tetex-doc tetex-dvips安装好整个 tetex,想单另装可以去CTAN下载源代码自己编译, Debian用户可以使用 aptitude这个TUI或者apt-get install tetex-base tetex-bin tetex-doctetex-ext从网上安装。现在我使用的MiTx版本和 tetex的版本分别为241和30,里面所带的 ME TAPOST的版本为0.641。12使用 METAPOST的基本流程般说来,最好先对需婓做的图形有个基本的轮廓,然后开始绲与源代码,写好后使用 mpost程序将源程序转换成为 POSTSCRIPT,可以使用一般的査看软件如 GSView或者 Imagemagick/-raphicmagick自带的 display/ gm display查看。如果不符合自己的要求,就修改源代码,重新转换,直到生成自己需要的图形为止。该图片可以使用 graphics/ graphicx宏包直接插入到ITx源文件中,然后编译ⅣX源文件获得.dvi文件,使用Dv阅读软件,如MkTX的yap和 Linux下的xdvi(k)。TX用户可以通过put epf%somethingsepsfboxisimmple-exanple0 SS插入图片。另外可以使用 mptopdf将,m直接转化为PDF,如上面的例子就会被转化为 simple- example-0,pdf1 METAPO57的历史13一个简单的例子那么首先让我们建立一个小小的测试文件(参考图①。存为 imple- example.mp,并使用图1:一个简单的 METAPOST示意beginfig( 0raw(0,0)—(lcm,0)—-(1cm,1cm)(O, lcm)- cycleendfigS mpost simple-example m获得编译结果,是个名为 simple- example.0的文件,你可以检查是不是和在本文档中所见致,是一个边长为1cm的正方形你能猜出来上面的程序大致什么意思么?14 METAPOST的预览问题从上面的例子看出,如果希望能够在写出代码后较快的看到转化的结果,需要用一道程序实现预览,这在 Winedt里面口绎实现过了,注意工具栏靠右侧的两个按钮,有一个是用来配置预览,还有一个就是用于预览,其基本原理就是将生成的图形建立在一个临时的.tex文件中并且编译后使用 dvips转换为 POST SCRIPT并使用 GSView査看在Iinx里面,可以配合一些脚本实现类似的功能,如下面的一段BASH脚本利用find实现类似的预览功能:/bin/sht t-gt 1fn=S]shiftoptions=selsefn=S1optionecho ""mpost. Options."\prologput. fn).mpost Options prologues: =l; inputs fn). mp'finds{fn}.[0-9)]play 0\你能否想出更好的预览脚本?或者编制一个自己的预览程序?2变量类型2变量类型值得注意的几点是 ME TAPOST稈序的风格,这里提出几点:1.使用;分割不同句子。2.使用作为行注释号。3.使用:=作为赋值号2.1 numeric类型由于 METAPOS5T不需要像C/C++一样使用很大范围的整数或者浮点数,因此MET∩POST选择使用的 numeric类型是不分整数浮点,其表达精度是 epsilon:=a3,表达的范围在(-4096,4096)之间。之所以出现4096是因为这是对应到 POSTSCRIPT中的距离已经超过1.4m了,般不需要更大的数了,由此可见 ME TAPO5T使用的固定精度(小数点后16位),另有12位表达整数部分,还有一位符号位。可以在计算数值超过限定范围后,把一个内置变量 warningcheck:=0即可。另外, numeric变量不需要声明即可使用。一般说来, numeric类型被用于表征长度,默认的单位是bp=in。但是 METAPOST也支持其他很多常见单位,如cm,mm,pt=n2yin,c=12.97213bp,d=1.06601bp,pC=1.957bp另外,这些单位和我们使用的 numeric变量没有太大的区别,换言之,你完全可能会通过对某些单位的赋值,使得该单位失去原先的意义,但这往往是我们不希望看到的:当我们在某处改变某个单位后,在该文件其他任何后继部分除非再次吏改该值,否则都不会变化。下面的简单实验说明了这·点。图2单位其实就是一种全局变量beginfig(0)draw(0,0)—(1cm,0)draw( lcm, 0)-(lcm, Icmendfigbeginfig(1draw(0,0)—(lcrn,0)MIndraw 10lcn. lcmndfi可能你注意到了1cm的写法,既然变量和单位基木雷同,你当然可以通过自凵定义一个长度如u=lcm;然后通过5u这种类似的方法作图,最终调节u获得不同大小的图片,如图3但是值得注总的是不同的 beging… endfig;环境中的u是不互相影响的。°请自己设计实验验证。Numeric可以执行的运算类型有+,-,*,/,另外还可以做x*,++,+-+,abs.mod,div,mexp,mlog这些运算,分别++y+-+y2变量类型图3:变量做单位用beginfig(0u: 1cmfor idraw(-2u,-2u)-(2u,-2u)(2u:2u)-(2=1/1.2;ndforendfig: y=r mod y=x-y×( r div ymexp=esfmlog y= 256 log y22pair类型所谓的pair类型也就是我们通常所指的平面直角坐标系中点的坐标了,在 METAPOST里面和般的数学表达完全相同,即(x,y),其中的x,y都是 numeric类型的变量。pair型变量使用前必须声明。下面的例子说明如何产生一个二元正态分布,其数学期望在(0,0),协方差矩阵为10图4:一个二元正态分布的例子beginfig(0)lLmdrawarrow(-3.5u,0)—(3.51,0)小,∵drawarrow(0,-35u0,3.5u)pickup pencircle scaled 2ptfor i1 upto 1000draw( u *k normaldeviate, u normaldeviateendoendfigpair与pair相加可认为向量相加,其内积使用 x dotprod y表小,是一个 numeric的结果。pair与 numerIc相乘就相当于线性代数中的数乘运算。如a(x,y)或者a*(x,y),衣示的就是这个pair可以进行求定比分点的运算,其基本语法是ax,y],其中a是一个 numerIc类型变量,而,y皆为pair型变量,该表达式返回的是x+a(y-x)这点,因此a=k,k=1,,n-1,就获得了n-1个n等分点图的程序说明了怎么利用定比分点求证三角形的三条中线交于一点,并且这个点三等分中线。2变量类型图5:三角形的重心ginfig( 0pair a, b, c, ab, bc, ca5cma: = uniformdeviate( u), uniformdeviate(u))b: - uniformdeviate(u), uniformdeviate( u))C:二uniformdeviate(u ), uniformdeviate( u))ab5 a, b i biC.:二];ca:=5[draw a- bCcycledraw a- bc withcolor( 1,0,0draw bca withcolor(0, 1,0)draw cb withcolor(0, 0, 1)draw fullcircle scaled 2In shifted 2/3 a, bc Ipickup pencircle scaled 3ptdraw 1/3[a, bc]: draw 1/3[b, ca]; draw 1/ 3[c, abendfigent我们知道三角形除了重心以外,还有垂心,内心,外心,旁心,如何设计类似的程序验证?垂心是三条高的交点,内心是三条角平分线的交点,外心是三条中位线的交点,旁心是一条内角平分线和两条外角平分线的交点我们可以使用 part, part从一个pair中取出其某方向坐标。比如有一个pair为a,那么和其止交的方向可以用(- part a, part a)表示。可以使用下面的方法求两条直线的交点:因为交点在两条直线上,都可以看作其上两点的定比分点,只是对应的定比未知,所以可以列出一个二元一次方程组(未知数为两个定比)求解。但是METAPOST提供了更好的方法airbd. e2 initial for a, b, c, dwhatever「a,bwhatever「c,d这里的a,b、c,d都是u知,e是过a,b的直线与过c,d的直线的交点。注意到这里使用的=,并非,表示的正是一个线性方程组。而 whatever是一个匿名 numerIc变量(每次调用代表的不同的变量),表示的正是方程组中代求的定比(虽然不是我们最终要求的交点)。请设计一个实例,使用自定义的 numeric变量计算交点,看看结果是不是和 hat计算出来的交点相同其实利用=构造多元线性方程组同样适用于 numeric类型,不妨写一个,结果可以用show varable list显小,其中的变量表用,分割。当需要更加翔实的结果显小该命令的结果时,可以 tracingonline23 color类型每种颜色都是用红绿蓝三色依照不同比例组合而成,因此通常用三种颜色的比例来表示一种颜色,故(r,g,b)中r,g,b的值都是在[0,1中选择的,其中像 black:=(0,0,0), white:=(1,1,1),red:=(1,0,0), green:=(0.1,0),blue:=(0,0.1)