画示意图,还是metapost好
March 10th, 2008想画一个Linux内核五大组成部分的示意图(如下),试了一堆开源工具:GraphViz, Dia, Kivio,居然没有一个可以画出想要的样子。

本来感觉对付这种图GraphViz应该比较拿手,但是搞了半天发现默认的dot工具没法指定顶点元素的位置,自动生成的布局极其诡异,neato倒是允许强制设定位置,但是不知道怎么搞的自动布局的箭头之间竟然互相交叉,凭着感觉调整了一下语句顺序,箭头不交叉了,但弧度又变得很奇特。。。
Dia和Kivio似乎都不怎么支持这种弧线箭头,虽然用折线箭头对付一下也凑合了,但总归不爽,至于界面的丑陋程度不提也罢。
其实OpenOffice.org Draw还不错,按以往的经验,画出的图还比较符合我的想法,只是OpenOffice.org家族里的其它成员太令人失望,实在不情愿为了它浪费EeePC宝贵的硬盘空间。
最后想起来还有个metapost,以前倒是玩过两下子,但没用它干过什么正经事,语法都快忘光了。杀到王垠前辈的网站找资料,居然惊奇地发现其中一个示例(下图)包含我要的所有元素:圆角矩形框起来的文字、弧线箭头,唯一一点疑虑就是不知道中文支持怎么样。。

Google了一把,发现只要装好了cjk-latex,要让metapost支持中文非常简单,在Ubuntu 7.10中,只要装上
context
latex-cjk-chinese
latex-cjk-chinese-arphic-gbsn00lp
latex-cjk-chinese-arphic-gkai00mp
这几个包(后两个是字体,可以选装),然后在metapost文件前后分别添加
verbatimtex
%&latex
\documentclass{article}
\usepackage{CJK}
\begin{CJK}{UTF8}{gkai}
\begin{document}
etex
和
verbatimtex
\end{CJK}
\end{document}
etex
设定好CJK环境、字体(gkai是文鼎楷体,还有一个宋体的名字是gbsn)即可。
下面是最上面那幅图的完整代码:
verbatimtex
%&latex
\documentclass{article}
\usepackage{CJK}
\begin{CJK}{UTF8}{gkai}
\begin{document}
etex
input boxes;
input rboxes;
beginfig(1);
rboxit.PM(btex 进程管理 etex);
rboxit.MM(btex 内存管理 etex);
rboxit.FS(btex 文件系统 etex);
rboxit.NET(btex 网络接口 etex);
rboxit.IPC(btex 进程间通信 etex);
PM.c = (3cm, 2cm);
MM.c = PM.c + (0, 2cm);
FS.c = PM.c - (3cm, 0);
IPC.c = PM.c + (3cm, 0);
NET.c = PM.c - (0, 2cm);
drawboxed(PM,MM,FS,IPC,NET);
drawdblarrow MM.c{left}..{down}FS.c cutbefore bpath.MM cutafter bpath.FS;
drawdblarrow MM.c{right}..{down}IPC.c cutbefore bpath.MM cutafter bpath.IPC;
drawarrow MM.c{down}..{down}PM.c cutbefore bpath.MM cutafter bpath.PM;
drawarrow FS.c{right}..{right}PM.c cutbefore bpath.FS cutafter bpath.PM;
drawarrow IPC.c{left}..{left}PM.c cutbefore bpath.IPC cutafter bpath.PM;
drawarrow NET.c{up}..{up}PM.c cutbefore bpath.NET cutafter bpath.PM;
drawarrow FS.c{down}..{right}NET.c cutbefore bpath.FS cutafter bpath.NET;
endfig;
verbatimtex
\end{CJK}
\end{document}
etex
end
mptopdf之,就可以直接生成PDF文件,如果需要其它图片格式,可以先用pdftoppm转成ppm,再用ImageMaigck中的convert。