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 宏,用它表示某件事情的工作進度。

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