MetaFun 09:进度 新画布 圆上的点 圆上的路径 扇形 结语

蜗牛的身影消失在长亭外,去寻它的山和海了。我还在城里的宫廷间徘徊。

许多天后,我的小手指不再那么木然隐痛了,于是最近又想搞一些事情,长期的,但是每次只需要用一些很小的力气,例如继续学习 MetaFun 啊。

新画布

之前用的画布,是为涂鸦和蜗牛准备的。现在可以不用了,更随意且有用的绘画环境可以像下面这样搭建:

\startuseMPgraphic{drawing name}
... ... metapost code ... ...
\stopuseMPgraphic

\starttext
This is my drawing: \useMPgraphic{drawing name}
\stoptext

没错,事实上 MetaFun 绘图环境搭建之简单,连

\envrionment card-env

都是多余的……也许只有我还记得 card-env.tex 是什么。

画一个圆试试。下面是一份完整的 ConTeXt 源文档 foo.tex,

\startuseMPgraphic{foo}
draw fullcircle scaled 2cm
  withpen pencircle scaled 4pt withcolor darkred;
\stopuseMPgraphic

\starttext
This is my drawing: \useMPgraphic{foo}
\stoptext

将其编译为 foo.pdf,结果为

事实上,还有更简单的画布。现在,假设完整的 ConTeXt 源文件 foo.tex 的内容为

\startMPpage
draw fullcircle scaled 2cm
  withpen pencircle scaled 4pt withcolor darkred;
\stopMPpage

编译 foo.tex,得到的 foo.pdf 如下图所示

MPpage 展现的是,吾性自足,不假外求。

从现在开始,我主要用 MPpage 画布了,这样可将精力更专注于图形本身。只有需要将图形作为文档插图使用时,再考虑使用 uniqueMPgraphicuseMPgraphic

圆上的点

如果知道一条路径是基于哪些点构造的,可使用 MetaPost 的 point ... of 语法获得路径上相应的点。例如,之前我曾像下面这样获得任意路径 p 的终点:

point (length p) of p

任意路径 p 的起点,可用以下代码获得:

point 0 of p

以下代码,借助颜色透明效果,展现了圆的起点和终点:

\startMPpage
path p;
p := fullcircle scaled 2cm;
draw p withpen pencircle scaled 4pt 
  withcolor darkred withtransparency (1, .25);
draw (point 0 of p) withpen pencircle scaled 6pt
  withcolor darkgreen withtransparency (1, .5);
draw (point (length p) of p) withpen pencircle scaled 12pt
  withcolor darkblue withtransparency (1, .25);
\stopMPpage

圆的起点和终点重合。这是肯定的,任何封闭路径皆有此性质。

如果我想在圆上画一个点,这个点距离起点有一段距离,而这段距离是圆的周长的 1/10,该如何画呢?

MetaFun 手册说,可以用 point ... along

试试看,

\startMPpage
path p;
p := fullcircle scaled 2cm;
draw p withpen pencircle scaled 4pt 
  withcolor darkred withtransparency (1, .25);

% 起点
draw (point 0 of p) withpen pencircle scaled 6pt
  withcolor darkgreen withtransparency (1, .5);

% 距起点距离为 1/10 圆周的点
draw (point .1 along p) withpen pencircle scaled 6pt
  withcolor darkblue withtransparency (1, .5);
\stopMPpage

的确可以,

圆上的路径

如何在圆上画从起点到距离起点 1/10 圆周的点的弧线?

MetaFun 手册说,可以从一条路径上「切」出来,用 cutbeforecutafter

身为用户的幸福就是,不明就里,但是总能试试看:

\startMPpage
path p;
p := fullcircle scaled 2cm;
pickup pencircle scaled 4pt;
draw p withcolor darkred withtransparency (1, .25);

pickup pencircle scaled 6pt;
% 起点
draw (point 0 of p)
  withcolor darkgreen withtransparency (1, .5);
% 距起点距离为 1/10 圆周的点
draw (point .1 along p)
  withcolor darkblue withtransparency (1, .5);

% 圆上的路径
pickup pencircle scaled 4pt;
draw (p cutafter (point .1 along p))
  withcolor darkgreen withtransparency (1, .5);
\stopMPpage

同理,可以令 cutbeforecutafter 配合,截取路径上的任何一段:

\startMPpage
pickup pencircle scaled 4pt;

path p;
p := fullcircle scaled 2cm;
draw p withcolor darkred withtransparency (1, .25);

% 圆上的路径
draw ((p cutbefore (point .1 along p)) cutafter (point .3 along p))
  withcolor darkgreen withtransparency (1, .5);
\stopMPpage

扇形

现在,可以画一个扇形了……

\startMPpage
path p;
p := fullcircle scaled 2cm;
draw p withpen pencircle scaled 4pt 
  withcolor darkred withtransparency (1, .25);

path q;
q := p cutafter (point .3 along p);
pickup pencircle scaled 2pt;
draw (0, 0) -- (point 0 of q) -- q -- (0, 0) withcolor darkblue;
\stopMPpage

但是,现在还仅仅是看上去像扇形,因为 MetaPost 编译器并不确定最后绘制的这条扇形路径是封闭的。因此,以下代码里的 fill 语句会无法通过编译:

\startMPpage
path p;
p := fullcircle scaled 2cm;
draw p withpen pencircle scaled 4pt 
  withcolor darkred withtransparency (1, .25);

path q;
q := p cutafter (point .3 along p);
pickup pencircle scaled 2pt;

path s;
s := (0, 0) -- (point 0 of q) -- q -- (0, 0) -- cycle;
fill s withcolor darkgray withtransparency (1, .5);
draw s withcolor darkblue withtransparency (1, .5);
\stopMPpage

倘若用 cycle 命令将 s 变为真正的封闭路径,

s := (0, 0) -- (point 0 of q) -- q -- (0, 0) -- cycle;

那么 fill s 便可工作了,结果可得真正的扇形:

结语

能够画出正确的扇形,就意味着,诸如 15%,30%……这些百分比,可以表现为直观的图形,也意味着,我可以将上述绘图命令定义为一个 ConTeXt 宏,用它表示某件事情的工作进度。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章