蝸牛的身影消失在長亭外,去尋它的山和海了。我還在城裏的宮廷間徘徊。
許多天後,我的小手指不再那麼木然隱痛了,於是最近又想搞一些事情,長期的,但是每次只需要用一些很小的力氣,例如繼續學習 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
畫布了,這樣可將精力更專注於圖形本身。只有需要將圖形作爲文檔插圖使用時,再考慮使用 uniqueMPgraphic
或 useMPgraphic
。
圓上的點
如果知道一條路徑是基於哪些點構造的,可使用 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 手冊說,可以從一條路徑上「切」出來,用 cutbefore
或 cutafter
。
身爲用戶的幸福就是,不明就裏,但是總能試試看:
\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
同理,可以令 cutbefore
和 cutafter
配合,截取路徑上的任何一段:
\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 宏,用它表示某件事情的工作進度。