metafun学习笔记
主要是学习官方文档METAPOST manual、metafun(metafun-p.pdf)和metafun xl(luametafun.pdf),以及官网。
惯例#
在ConTeXt中使用:
\starttext
% 就地插入图片
\startMPcode
fill unitsquare scaled 5cm withcolor red ;
\stopMPcode
% 插入mp页
\startMPpage
fill fullcircle scaled 5cm withcolor red ;
\stopMPpage
% 生成指定名字的图片,再使用
\startuseMPgraphic{name}
fill unitsquare scaled 5cm withcolor red ;
\stopuseMPgraphic
\useMPgraphic{name}
\stoptext
欢迎来到MetaPost#
坐标点,数值对(pair),矢量,路径,控制点。
pair somepoint;
somepoint := (1cm,1.5cm) ;
路径#
(1cm,1cm)..(1.5cm,1.5cm)..(2cm,0cm) % 开放路径,平滑曲线
(1cm,1cm)--(1.5cm,1.5cm)--(2cm,0cm) % 开放路径,直线
(1cm,1cm)..(1.5cm,1.5cm)..(2cm,0cm)..cycle % 闭合路径
(1cm,1cm)..(1.5cm,1.5cm)..controls (3cm,2cm)..(2cm,0cm) % 控制点,左右两个点共用
(1cm,1cm)..controls (.5cm,2cm) and (2.5cm,2cm)..(2cm,.5cm) % 控制点,左右分别定义
变形#
变量和赋值:
path p ; % 定义路径变量
p := (1cm,1cm)..(1.5cm,2cm)..(2cm,0cm) ; % 赋值
p shifted (4cm,2cm) % 位移
p rotated 15 % 旋转,等于:
p rotatedaround (origin, 15)
p rotatedaround(center p, 15) shifted (4cm,0cm) % 联合操作
p slanted 1.5 shifted (4cm,0cm) % 倾斜
p reflectedabout((2.4cm,-.5),(2.4cm,3cm)) % 镜像反射
transform t ; % 变形变量
t := identity scaled 2cm shifted (4cm,1cm) ; % 变形矩阵
p transformed t
METAPOST | code | mathematical equivalent |
---|---|---|
(x,y) | shifted (a,b) | (𝑥 + 𝑎, 𝑦 + 𝑏) |
(x,y) | scaled s | (𝑠𝑥, 𝑠𝑦) |
(x,y) | xscaled s | (𝑠𝑥, 𝑦) |
(x,y) | yscaled s | (𝑥, 𝑠𝑦) |
(x,y) | zscaled (u,v) | (𝑥𝑢 − 𝑦𝑣, 𝑥𝑣 + 𝑦𝑢) |
(x,y) | slanted s | (𝑥 + 𝑠𝑦, 𝑦) |
(x,y) | rotated r | (𝑥 cos(𝑟) − 𝑦 sin(𝑟), 𝑥 sin(𝑟) + 𝑦 cos(𝑟)) |
构造路径#
z0 = (0.5cm,1.5cm) ;
z1 = (2.5cm,2.5cm) ;
z2 = (6.5cm,0.5cm) ;
z3 = (3.0cm,1.5cm) ;
z0--z1--z2--z3--cycle
z0..z1..z2..z3..cycle
z0...z1...z2...z3...cycle % 紧闭合
z0---z1---z2---z3---cycle % 紧闭合,看不见控制点
z0..z1..z2--z3..cycle % 折线过度
z0..z1..z2---z3..cycle % 曲线过度
z0..z1..z2 & z2..z3..z0 & cycle % 连接子路径
z0..z1..z2..z3..z0 % 看似闭合的开放路径
z0..z1..z2..z3..z0..cycle % 如此闭合
buildcycle(z0..z1..z2 , z0..z3..z1..cycle) % 用点和多个路径构造闭合路径
z0--z1 softjoin z2--z3 % 松开一个结点
subpath(2,4) of (z0..z1..z2..z3..cycle) % 提取子路径,可以是小数
(z0..z1..z2..z3) cutafter z2 % 剪除路径
(z0..z1..z2..z3) cutbefore z1
(z0..z1..z2..z3) cutbefore point 2 of (z0..z1..z2..z3) % 剪除路径,可以是小数
预定义的directionpoint
- right ( 1, 0)
- up ( 0, 1)
- left (-1, 0)
- down ( 0,-1)
(z0..z1..cycle) cutafter directionpoint up of (z0..z1..cycle)
(z0..z1..cycle) cutafter directionpoint (1,1) of (z0..z1..cycle)
角度#
方向函数dir
pickup pencircle scaled 2mm ;
draw (origin -- dir(45) -- dir(0) -- cycle)
scaled 3cm
withcolor .625red ;
draw (origin -- dir(angle(1,1)) -- dir(angle(1,0)) -- cycle)
scaled 3cm shifted (3.5cm,0) withcolor .625yellow ;
draw (origin -- (1,1) -- (1,0) -- cycle)
scaled 3cm shifted (7cm,0)
withcolor .625white ;
画图#
根据路径画线和填充
draw (0cm,1cm)..(2cm,2cm)..(4cm,0cm)..cycle ;
fill (0cm,1cm)..(2cm,2cm)..(4cm,0cm)..cycle ;
颜色,笔型,线型
path p ;
p := (0cm,1cm)..(2cm,2cm)..(4cm,0cm)..(2.5cm,1cm)..cycle ;
drawarrow p withcolor .625red ;
draw p shifted (7cm,0) dashed withdots withcolor .625yellow ;
图形变量,赋值,清空,操纵
picture pic ;
pic := currentpicture ;
currentpicture := nullpicture ;
draw pic rotated 45 withcolor red ;
unfill其实是使用背景色填充
添加
addto currentpicture doublepath pat
addto currentpicture contour pat
addto currentpicture also pic
变量#
METAPOST是一种简单的宏语言,用PASCAL编写而成。
数据类型:
numeric | real number in the range −4096… + 4096 |
boolean | a variable that takes one of two states: true or false |
string | sequence of characters, like "metapost" |
pair | point or vector in 2--dimensional space |
path | a piecewise collection of curves and line segments |
picture | collection of stroked or filled paths |
color | vector of three (rgb) or four (cmyk) numbers |
pen | pen specification |
transform | transformation vector with six elements |
十种基础数据类型:
- numeric, 1/65536(epsilon)的整数倍
- pair, 数对,可进行四则运算,可用于区间定位表达式(mediation expressions)
- path,路径
- transform,变换组合,包括旋转、缩放、倾斜、位移的组合,可用于数对、路径、图像、笔和变换自身。
- color/rgbcolor,三元数组,运算同数对(结果会修剪到0与1之间)。也指预定义的常量:
- black,(0,0,0)
- white,(1,1,1)
- red
- green
- blue
- cmykcolor,四元数组,运算同color,小心纯黑色(0,0,0,1)与混色黑(1,1,1,𝑘)(𝑐,𝑚,𝑦,1)的在印刷实际中的区别
- string,"...",不能包括双引号和换行,但可以通过
n := scantokens(str);
输入 - boolean
- true, false
- and, or, not
- =, <>, <, >, <=, >=
- picture, 任何可绘制对象,draw把绘制结果存在currentpicture,图像可叠加和变换
- pen, 主要确定笔画粗细,表达式如pencircle scaled ⟨numeric primary⟩,非圆形笔可以取得书法效果,pickup ⟨pen expression⟩ 影响会面的draw和drawdot
未定义的变量默认为数字。以下行相同:
n := 10 ;
numeric n ; n := 10 ;
在宏集中最好先定义,以免冲突。
数组是同类变量的集合:
numeric n[][] ; n[2][3] := 10 ;
超界索引不会出错,而返回unknown
实际上并没有数组,而是生成了一些哈希条目。以下是定价的:
i_111_222 := 1cm ;
i_[111]_[222] := 1cm ;
i_[111][222] := 1cm ;
变量后缀#
如lable后缀:<空> | lft | rt | top | bot | ulft | urt | llft | lrt
z后缀,如:
dotlabels.rt(0, 1, a); % 等价于dotlabel.rt("0",z0); dotlabel.rt("1",z1); dotlabel.rt("a",z.a);
token#
运算符#
条件表达式#
if n=10 : draw p ;
else : draw q ;
fi ;
一行式:
draw if n=10 : p else : q fi withcolor red ;
draw p withcolor if n<10 : red elseif n=10 : green else : blue fi ;
变量的布尔检测:
if picture p :
if known n :
if odd i :
if cycle q :
支持用and, or, not, 和 ( )构造表达式。
循环#
for i=0 step 2 until 20 :
draw (0,i) ;
endfor ;
draw for i=0 upto n-1 : p[i] .. endfor p[n] ;
迭代一列对象:
for i=p,q,r :
fill i withcolor .8white ;
draw i withcolor red ;
endfor ;
改变循环变量自身:
forsuffixes i = p, q, r :
i := i shifted (3cm,2cm) ;
endfor ;
查找特定值后跳出/终止循环:
numeric done[][], i, j, n ; n := 0 ;
forever :
i := round(uniformdeviate(10)) ; j := round(uniformdeviate(2)) ;
if unknown done[i][j] :
drawdot (i*cm,j*cm) ; n := n + 1 ; done[i][j] := n ;
fi ;
exitif n = 10 ;
endfor ;
宏#
定义宏:
def upto = step 1 until enddef ;
primarydef p doublescaled s =
p xscaled (s/2) yscaled (s*2)
enddef ;
draw somepath doublescaled 2cm withcolor red ;
% 实际展开为:
% draw somepath xscaled 1cm yscaled 4cm withcolor red ;
def drawrandomscaledpath (expr p, s) =
draw p xscaled (s/2) yscaled (s*2) ;
enddef ;
% 返回变量的定义,返回最后一句的结果,而不是展开(因此不要使用分号结尾)
vardef randomscaledpath(expr p, s) =
numeric r ; r := round(1 + uniformdeviate(4)) ;
p xscaled (s/r) yscaled (s*r)
enddef ;
可接受的参数:
- expr: something that can be assigned to a variable
- text: arbitrary METAPOST code ending with a ;
- suffix: a variable bound to another variable
- primary
expr是传值的,suffix则是传引用。
默认所有变量都是全局的,局部变量需要通过分组来管理。
% 实际上,vardef会自动分组
vardef randomscaledpath(expr p, s) =
begingroup ; save r ; numeric r ; % save r 定义局部变量
r := round(1 + uniformdeviate(4)) ;
p xscaled (s/r) yscaled (s*r)
endgroup
enddef ;
其他定义:
- primarydef x mod y = ... enddef ;
- secondarydef p intersectionpoint q = ... enddef ;
- tertiarydef p softjoin q = ... enddef ;
参数#
馈送参数相当灵活:
def test expr a = enddef ; test (a) ; test a ;
def test (expr a) = enddef ; test (a) ; test a ;
def test (expr a,b) (expr c,d) = enddef ;
test (a) (b) (c) (d) ;
test (a,b) (c,d) ;
test (a,b,c) (d) ;
test (a,b,c,d) ;
text参数,如果没有括号限制,会一直匹配到分号。
限定参数,用于定义z1或z234:
vardef z@# = (x@#,y@#) enddef ;
笔型#
绘图时可以使用三种属性:a dashpattern, a pen and/or a color
withpen pencircle
% 改变当前笔型
pickup pencircle xscaled 2mm yscaled 4mm rotated 30 ;
% 自定笔型,使用makepen和makepath转换路径和笔型
path p ; p := fullcircle xscaled 2cm yscaled 3cm ;
pen doublepen ; doublepen := makepen ((0,0)--(.3cm,.3cm)) ;
pickup doublepen ; draw p ;
% 就地使用
draw p withpen makepen ((0,0)--(.3cm,.3cm)) ;
% 显示笔型框架
path p ; p := (-1,0) {down} .. {up} (1,0) ;
draw pensilled(p, pensquare scaled (1/3) rotated 30)
scaled 2cm ;
draw boundingbox image(draw p)
scaled 2cm ;
连接线段#
interim linejoin := mitered ;
for i :=1 step 1 until 5 :
interim miterlimit := i*pt ;
draw ((0,0)--(.5,1)--(1,0)) shifted (1.5i,0) scaled 50pt
withpen pencircle scaled 10pt withcolor .625red ;
endfor ;
参见:Figure 1.3 The nine ways to end and join lines.
颜色#
withcolor (.4,.5.,6)
color darkred ; darkred := (.625,0.0) ;
withcolor darkred
withcolor .625red
withcolor .5[red,green]
虚线#
picture p ; p := nullpicture ;
addto p doublepath ((0,0)--(3mm,3mm)) shifted (6mm,6mm) ;
draw (0,0)--(10cm,0) dashed p withpen pencircle scaled 1mm ;
% 更方便
picture p ; p := dashpattern(on 3mm off 3mm) ;
draw (0,0)--(10cm,0) dashed p withpen pencircle scaled 1mm ;
% 直接使用开关式图像evenly
draw (0,0)--(10cm,0) dashed (evenly scaled 1mm)
withpen pencircle scaled 1mm ;
% 设置默认值
drawoptions(dashed evenly withcolor red) ;
文本#
- label⟨标签后缀⟩(⟨字符串或图片表达式⟩, ⟨数对表达式⟩);
- thelabel⟨标签后缀⟩(⟨字符串或图片表达式⟩, ⟨数对表达式⟩); % 返回图像原语
- dotlabel⟨标签后缀⟩(⟨字符串或图片表达式⟩, ⟨数对表达式⟩);
- dotlabels.rt(0, 1, a); % z后缀,等价于dotlabel.rt("0",z0); dotlabel.rt("1",z1); dotlabel.rt("a",z.a);
- ⟨标签后缀⟩ -> <空> | lft | rt | top | bot | ulft | urt | llft | lrt
pair a ; a := (3cm,3cm) ;
label.top("top",a) ; label.bot("bot",a) ;
label.lft("lft",a) ; label.rt ("rt" ,a) ;
pair a ; a := (3cm,3cm) ;
dotlabel.top("top",a) ; dotlabel.bot("bot",a) ;
dotlabel.lft("lft",a) ; dotlabel.rt ("rt" ,a) ;
pair a ; a := (3cm,3cm) ; pickup pencircle scaled 1mm ;
drawdot a withcolor .625yellow ;
draw thelabel.rt("the right way",a) withcolor .625red ;
% 标签排版btex..etex和textext()会生成图像原语
% 使用字体(infont不支持居中、字间等,但是在ConTeXt中与btex无异,因为infont已经重载为,二者都是用textext,即重定向到tex)
draw "this string will become a sequence of glyphs (MP)" infont defaultfont scaled defaultscale ;
draw btex this string will become a sequence of glyphs (\TeX) etex ;
改变默认字体、字号:
- defaultfont:="ptmr8r";
- defaultscale:= 1.2; % 1是默认值
- defaultscale:= 12pt/fontsize defaultfont;
绑定盒bbox与文本测量
线性方程#
解析线性方程(符号计算)
a + b = 3;
2a = b +3;
c = 1/2[a,b]; % 两点之间的比例位置
show a, b, c; % 跟踪变量
剪裁#
取得外框数据:
- llcorner p: lower left corner
- lrcorner p: lower right corner
- urcorner p: upper right corner
- ulcorner p: upper left corner
- center p: the center point
fill fullcircle scaled 2cm withcolor .625yellow ;
setbounds currentpicture to unitsquare scaled 1cm ; % 重置外框
draw unitsquare scaled 1cm withcolor .625red ;
fill fullcircle scaled 2cm withcolor .625yellow ;
clip currentpicture to unitsquare scaled 1cm ; % 剪裁
METAFUN扩展#
% 缩放:enlarged,bottomenlarged, rightenlarged, topenlarged and leftenlarged
path p ; p := fullsquare scaled 2cm ;
drawpath p ; drawpoints p ;
p := (p shifted (3cm,0)) enlarged (.5cm,.25cm) ;
drawpath p ; drawpoints p ;
% 圆角
path p ; p := ((1,0)--(2,0)--(2,2)--(1,2)--(0,1)--cycle)
xysized (4cm,2cm) ;
drawpath p ; drawpoints p ;
p := (p shifted (5cm,0)) cornered .5cm ;
drawpath p ; drawpoints p ;
% 平滑,会改变大形状
path p ; p := ((1,0)--(2,0)--(2,2)--cycle) xysized (4cm,2cm) ;
drawpath p ; drawpoints p ;
p := (p shifted (5cm,0)) smoothed .5cm ;
drawpath p ; drawpoints p ;
% 简化路径(重复的点)
path p ; p := ((0,0)--(1,0)--(2,0)--(2,1)--(2,2)--(1,2)--(0,2)--(0,1)--cycle) xysized (4cm,2cm) ;
drawpath p ; drawpoints p ;
p := simplified (p shifted (5cm,0)) ;
drawpath p ; drawpoints p ;
% 去除路径毛刺(重叠路径)
path p ; p := ((0,0)--(2,0)--(3,1)--(2,0)--(2,2)--(1,2)--(1,3)--(1,2)--(0,1)--cycle) xysized (4cm,2cm) ;
drawpath p ; drawpoints p ;
p := unspiked (p shifted (5cm,0)) ;
drawpath p ; drawpoints p ;
% 随机扭曲
path p ; p := fullsquare scaled 2cm ;
drawpath p ; drawpoints p ;
p := (p shifted (5cm,0)) randomized .5cm ;
drawpath p ; drawpoints p ;
% 挤压
path p ; p := fullsquare scaled 2cm randomized .5cm ;
drawpath p ; drawpoints p ;
p := (p shifted (5cm,0)) squeezed .5cm ;
drawpath p ; drawpoints p ;
% 朋克(减少平滑,缩小)
path p ; p := fullcircle scaled 2cm randomized .5cm ;
drawpath p ; drawpoints p ;
p := punked (p shifted (5cm,0)) ;
drawpath p ; drawpoints p ;
% 平滑(变大)
path p ; p := fullsquare scaled 2cm randomized .5cm ;
drawpath p ; drawpoints p ;
p := curved (p shifted (5cm,0)) ;
drawpath p ; drawpoints p ;
% 阶梯化
path p ; p := fullcircle scaled 3cm ;
drawpath p ; drawpoints p ;
p := laddered (p shifted (5cm,0)) ;
drawpath p ; drawpoints p ;
% 并列,比如画化学分子式
path p ; p := fullcircle scaled 3cm ;
drawpath p ; drawpoints p ;
p := p paralleled 1cm ;
drawpath p ; drawpoints p ;
% 膨胀
path p ; p := fullsquare xyscaled (4cm,1cm) randomized .5cm ;
drawpath p ; drawpoints p ;
p := p blownup .5cm ;
drawpath p ; drawpoints p ;
% 伸缩,仅应用与直线路径
path p ; p := (0,0) -- (2cm,3cm) ;
drawpath p ; drawpoints p ;
p := p shortened 1cm ;
drawpath p ; drawpoints p ;
p := p shortened -1cm ;
drawpath p ; drawpoints p ;
% 圆角矩形
path p ; p := roundedsquare(2cm,4cm,.25cm) ;
drawpath p ; drawpoints p ;
% 圆方/方圆,张力圆
path p ; p := tensecircle(2cm,4cm,.25cm) ;
drawpath p ; drawpoints p ;
% 取得路径上的某个位置的点
path p, q, r ;
p := fullsquare xyscaled (2cm,2cm) randomized .5cm ;
q := p shifted (3cm,0) ; r := q shifted (3cm,0) ;
drawpath p ; drawpoints p ; drawpointlabels p ;
drawpath q ; drawpoints q ; drawpointlabels q ;
drawpath r ; drawpoints r ; drawpointlabels r ;
pickup pencircle scaled 5mm ;
draw point 2.25 of p withcolor .625red ;
draw point 2.50cm on q withcolor .625yellow ;
draw point .45 along r withcolor .625white ;
% 剪切路径
path p ; p := (0cm,0cm)
-- (4cm,1cm) ;
path q ; q := (5cm,0cm){right} .. (9cm,1cm) ;
drawpath p ; drawpoints p ; drawpath q ; drawpoints q ;
p := p cutends .5cm ; q := q cutends .5cm ;
drawpathoptions (withpen pencircle scaled 5pt withcolor .625yellow) ;
drawpointoptions(withpen pencircle scaled 4pt withcolor .625red) ;
drawpath p ; drawpoints p ; drawpath q ; drawpoints q ;
resetdrawoptions ;
path p ; p := (0cm,0) .. (4cm,0) .. (8cm,0) .. (4cm,0) .. cycle ;
drawpath p ; drawpoints p ; p := p cutends (2cm,1cm) ;
drawpathoptions (withpen pencircle scaled 5pt withcolor .625yellow) ;
drawpointoptions(withpen pencircle scaled 4pt withcolor .625red) ;
drawpath p ; drawpoints p ;
resetdrawoptions ;
% 拉伸路径,零点不变
path p ; p := (0cm,0) .. (3cm,1cm) .. (4cm,0) .. (5cm,1cm) ;
drawpath p ; drawpoints p ; p := p stretched 1.1 ;
drawpathoptions (withpen pencircle scaled 2.5pt withcolor .625yellow) ;
drawpointoptions(withpen pencircle scaled 4.0pt withcolor .625red) ;
drawpath p ; drawpoints p ; resetdrawoptions ;
% 指定零点后拉伸
path p ; p := (0cm,0) .. (3cm,1cm) .. (4cm,0) .. (5cm,1cm) ;
drawpath p ; drawpoints p ; p := p stretched (.75,1.25) ;
drawpathoptions (withpen pencircle scaled 2.5pt withcolor .625yellow) ;
drawpointoptions(withpen pencircle scaled 4.0pt withcolor .625red) ;
drawpath p ; drawpoints p ; p := p stretched (0,1.5) ;
drawpathoptions (withpen pencircle scaled 4.0pt withcolor .625red) ;
drawpointoptions(withpen pencircle scaled 2.5pt withcolor .625yellow) ;
drawpath p ; drawpoints p ; resetdrawoptions ;
% randomized随机化可以应用于numeric, pair, path and color
draw fullsquare xyscaled (4cm,2cm)
randomized .25cm
shifted origin randomized (1cm, 2cm)
withcolor red randomized (.625, .850)
withpen pencircle scaled (5pt randomized 1pt) ;
% xy缩放, METAPOST本身只有scaled, xscaled and yscaled
picture p ; p := image
( draw fullsquare
xyscaled (300,800)
withpen pencircle scaled 50
withcolor .625 yellow ; ) ;
draw p xysized (3cm,2cm) shifted (bbwidth(currentpicture)+.5cm,0) ;
draw p xysized 2cm shifted (bbwidth(currentpicture)+.5cm,0) ;
draw p xsized 1cm shifted (bbwidth(currentpicture)+.5cm,0) ;
draw p ysized 2cm shifted (bbwidth(currentpicture)+.5cm,0) ;
% 画出外框
draw fullcircle scaled 1cm
withcolor .625red
withpen pencircle scaled 1mm ;
draw currentpicture
withcolor .625yellow withpen pencircle scaled 3mm ;
draw boundingbox currentpicture
withpen pencircle scaled .5mm ;
% 画出背景
fill fullcircle scaled 1cm withcolor .625red ;
addbackground withcolor .625 yellow ;
剪切和粘贴#
vardef somearrow (expr pat, loc, len) =
save p ; path p ; p := pat cutbefore loc ; % 剪掉指定位置前
(p cutafter point (arctime len of p) of p) % 剪掉指定点(弧长)后
enddef ;
path p ; p := fullcircle scaled 3cm ;
pair q ; q := point .4 along p ;
pickup pencircle scaled 2mm ;
draw p withcolor .625white ;
drawarrow somearrow(p,q,2cm) withcolor .625red ;
draw q withcolor .625yellow ;
当前图像(currentpicture)#
我们绘画时是在当前图像上操作。还可以把当前图像当做一个整体来处理。
draw fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625red ;
currentpicture := currentpicture slanted .5 ;
draw fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625red ;
currentpicture := currentpicture slanted .5 ;
pushcurrentpicture ; % 压栈暂存
draw fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625yellow ;
currentpicture := currentpicture slanted -.5 ;
popcurrentpicture ; % 弹出
% 或使用METAFUN的变体image
draw fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625red ;
currentpicture := currentpicture slanted .5 ;
draw image (
draw fullcircle scaled 1cm
withpen pencircle scaled 1mm withcolor .625yellow ;
currentpicture := currentpicture slanted -.5 ;
) ;
更多细节#
生成图形(graphic)#
独立文件,比如yourfile.mp:
% Let's draw a circle.
% input mp-tool ;
% or input metafun ;
beginfig (7) ;
% 生成svg格式,否则是POSTSCRIPT格式
% outputformat := "svg" ;
draw fullcircle scaled 3cm withpen pencircle scaled 1cm ;
endfig ;
end .
在CONTEXT文档中不需要beginfig (7) ; endfig ;和end .
生成图像文件:
mpost yourfile.mp
使用图像:
\externalfigure[yourfile.7]
单位:
- cm
- pt, point
- bp, big point, METAPOST的缺省单位,对应pt的POSTSCRIPT的近似值
围盒#
bbox宏生成的围盒是有偏置量的。偏置量控制:
% 绘制(在路径上/两侧)
pickup pencircle scaled .5cm ;
draw unitsquare xscaled 8cm yscaled 1cm withcolor .625white ;
path bb ; bboxmargin := 0pt ; bb := bbox currentpicture ;
draw bb withpen pencircle scaled 1pt withcolor .625red ;
draw origin withpen pencircle scaled 5pt withcolor .625yellow ;
% 填充(在路径内)
pickup pencircle scaled .5cm ;
fill unitsquare xscaled 8cm yscaled 1cm withcolor .625white ;
path bb ; bboxmargin := 0pt ; bb := bbox currentpicture ;
draw bb withpen pencircle scaled 1pt withcolor .625red ;
draw origin withpen pencircle scaled 5pt withcolor .625yellow ;
% 填绘
pickup pencircle scaled .5cm ;
filldraw unitsquare xscaled 8cm yscaled 1cm withcolor .625white ;
path bb ; bboxmargin := 0pt ; bb := bbox currentpicture ;
draw bb withpen pencircle scaled 1pt withcolor .625red ;
draw origin withpen pencircle scaled 5pt withcolor .625yellow ;
解散字模#
调试#
读写文件#
导出通用文件#
prologues := 2 ;
#
嵌入图形#
开始#
外部图形#
- \externalfigure[graphic.123][width=4cm]
- useexternalfigure
- \useexternalfigure[pentastar][star.803][height=4cm]
- \useexternalfigure[octostar] [star.804][pentastar]
- \placefigure{A five||point star drawn by \METAPOST.}{\externalfigure[pentastar]}
整合图形#
% 直接使用
\startMPcode
fill fullcircle scaled 200pt withcolor .625white ;
\stopMPcode
% 先定义图形,再使用
\startuseMPgraphic{name}
fill fullcircle scaled 200pt withcolor .625yellow ;
\stopuseMPgraphic
% 每次使用都会重新计算一遍,因此可以改变属性
\useMPgraphic{name}
% 可重用图形,不会每次使用都计算一遍,节省计算资源
\startreusableMPgraphic{name}
fill fullcircle scaled 200pt withcolor .625yellow;
\stopreusableMPgraphic
\reuseMPgraphic{name}
% unique图形,每次使用都会重新计算
\startuniqueMPgraphic{name}
path p ; p := unitsquare
xscaled OverlayWidth yscaled OverlayHeight ;
fill p withcolor .625yellow ;
draw p withcolor .625red ;
\stopuniqueMPgraphic
\defineoverlay[my graphic][\uniqueMPgraphic{name}]
\button[background=my graphic,frame=off]{Go Home}[firstpage]
% 运行时图形,比如mylogos.mp,每次生成图形,再插入
\startMPrun
input mylogos ;
\stopMPrun
% 或指定解释命令和文件路径
\startMPrun{extrafun::mydemo}
input mfun-mrun-demo.mp ;
\stopMPrun
不用CONTEXT,只用METAFUN#
\startMPpage
% Your mp code goes here. You can use the textext
% macro as discussed later to deal with typeset text.
\stopMPpage
Lua#
导语#
基础#
metafun向tex输入流馈入字符串:
%
numeric n ; n := scantokens("123.456") ;
%
numeric n ; n := runscript("return '123.456'") ;
%
local function scriptrunner(code)
local f = loadstring(code)
if f then
return tostring(f())
else
return ""
end
end
local m = mplib.new {
...
run_script = scriptrunner,
...
}
辅助函数#
CONTEXT的方式:
numeric n ; n := lua("mp.print(12.34567)") ;
draw textext(n) xsized 4cm withcolor darkred ;
字符串#
draw
textext("This will print \quotation{Hi} in the console!")
xsized TextWidth
withcolor "darkblue" ;
% 运行lua脚本
runscript("print('Hi')");
% 给mp返回字符串
string s ;
s := runscript("mp.quoted('This will return a string!')") ;
draw textext(s)
xsized TextWidth
withcolor "darkgreen" ;
数字#
runscript 10000;
CONTEXT/METAFUN辅助函数#
draw lua.mp.foo(0,2,(3,4)) ; % mp是给CONTEXT用的
fill lua.MP.foo(0,2,(3,4)) ; % MP是给用户使用的
在lua段,被映射到相应的函数:
function mp.foo(n,m,p)
-- do something
end
function MP.foo(n,m,p)
-- do something
end
numeric n ; n := lua("mp.print(12.34567)") ;
draw textext(n) xsized 4cm withcolor darkred ;
numeric n ; n := lua("mp.print(1) mp.print('+') mp.print(2)") ;
draw textext(n) xsized 1cm withcolor darkred ;
% 等价于
numeric n ; n := lua("mp.print(1,'+',2)") ;
draw textext(n) xsized 1cm withcolor darkred ;
从lua打印到mp(传递数据)#
所打印的字符串即为合法的mp代码
fill fullcircle scaled runscript("mp.print('3cm')") withcolor "darkred" ;
fill fullcircle scaled runscript("mp.print.print('2cm')") withcolor "darkgreen" ;
fill fullcircle scaled runscript("mp.aux.print('1cm')") withcolor "darkblue" ;
% 打印路径
local t1 = { {0,0}, {1,0}, {1,1}, {0,1} }
local t2 = { {0,0}, {1,0}, {1,1}, {0,1}, cycle = true }
mp.print.path(t1)
mp.print.path(t1,nil,true)
mp.print.path(t1,true,true)
mp.print.path(t1,false)
mp.print.path(t1,false,true)
mp.print.path(ts,false)
mp.print.path(t1,"...",true)
mp.print.path(t1,"..",true)
mp.print.path(t2,"..")
Direct值#
与打印机近似的注入器:
function MP.MyFunction()
mp.inject.string("This is just a string.")
end
包括: boolean, cmykcolor, color, integer, number, numeric, pair, path, quadruplet, string, transform, triplet and whatever (kind of automatic)
寄存器#
特殊辅助函数#
哈希
模式
\enablemode[weird]
\startMPcode
fill fullsquare xyscaled (TextWidth,5mm)
withcolor if texmode("weird") : "darkblue" else : "darkgreen" fi ;
\stopMPcode
\disablemode[weird]
定位
TeX数量
UTF8
string s ; s := "ÀÁÂÃÄÅàáâãäå" ;
draw textext(s) shifted ( 0cm,0) withcolor "darkyellow" ;
draw textext(utfnum("Â")) shifted ( 3cm,0) withcolor "darkmagenta" ;
draw textext(utflen(s)) shifted ( 6cm,0) withcolor "darkcyan" ;
draw textext(utfsub(s,3,4)) shifted ( 9cm,0) withcolor "darkblue" ;
draw textext(utfsub(s,6)) shifted (12cm,0) withcolor "darkred" ;
使用变量#
库#
CONTEXT辅助函数#
- mp.string string passed as it is but with percent, double quote and newline escaped
- mp.boolean boolean the true or false primitives
- mp.integer number an integer
- mp.number number a float
- mp.numeric number a float (same as previous)
- mp.points number a scaled numeric with pt unit
- mp.pair numbers or table a pair (x,y) or (x,x)
- mp.pairpoints numbers or table idem but with scaled numbers and a pt unit
- mp.triplet numbers or table a rgb triplet (r,g,b)
- mp.tripletpoints numbers or table idem but with scaled numbers and a pt unit
- mp.quadruple numbers or table a cmyk quadruple (c,m,y,k)
- mp.quadruplepoints numbers or table idem but with scaled numbers and a pt unit
- mp.color numbers or table a numeric, triplet or quadruple
- mp.transform numbers or table a six element transform
- mp.print whatever the normal semi-intelligent printer
- mp.print.path
- mp.inject
- mp.inject.path
- mp.fprint format, whatever the normal semi-intelligent printer using a format
- mp.vprint variable the normal semi-intelligent printer with escaped percents, quotes and newlines
- mp.quoted string a valid string surrounded by quotes with an optional first format specifier
- mp.print(...) returns one or more values
- mp.pair(x,y) pair(t) returns a proper pair
- mp.triplet(x,y,z) triplet(t) returns an RGB color
- mp.quadruple(w,x,y,z) quadruple(t) returns an CMYK color
- mp.format(fmt,...) returns a formatted string
- mp.quoted(fmt,...) quoted(s) returns a (formatted) quoted string
- mp.path(t[,connect][,close]) returns a connected (closed) path
- mp.get.numeric(name) gets a numeric from METAPOST
- mp.get.boolean(name) gets a boolean from METAPOST
- mp.get.string(name) gets a string from METAPOST
METAPOST向CONTEXT/lua传递参数#
\startMPcalculation
passvariable("version","1.0") ;
passvariable("number",123) ;
passvariable("string","whatever") ;
passvariable("point",(1.5,2.8)) ;
passvariable("triplet",(1/1,1/2,1/3)) ;
passvariable("quad",(1.1,2.2,3.3,4.4)) ;
passvariable("boolean",false) ;
passvariable("path",fullcircle scaled 1cm) ;
path p[] ; p[1] := fullcircle ; p[2] := fullsquare ;
passarrayvariable("list",p,1,2,1) ; % first last step
\stopMPcalculation
% 或在MP代码中
\startMPcode
path p ; p := fullcircle xyscaled (10cm,2cm) ;
path b ; b := boundingbox p ;
startpassingvariable("mypath")
passvariable("points",p) ;
startpassingvariable("metadata")
passvariable("boundingbox",boundingbox p) ;
stoppassingvariable ;
stoppassingvariable ;
fill p withcolor .625red ;
draw b withcolor .625yellow ;
\stopMPcode
lua端通过表metapost.variables使用
\startluacode
context.tocontext(metapost.variables)
\stopluacode
tex用法:
\MPruntab{quad}{3}
跟踪参数:
\enabletrackers[metapost.variables]