summaryrefslogtreecommitdiff
path: root/Master/texmf-doc/doc/chinese/lnotes/src/graphics.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-doc/doc/chinese/lnotes/src/graphics.tex')
-rw-r--r--Master/texmf-doc/doc/chinese/lnotes/src/graphics.tex1256
1 files changed, 1256 insertions, 0 deletions
diff --git a/Master/texmf-doc/doc/chinese/lnotes/src/graphics.tex b/Master/texmf-doc/doc/chinese/lnotes/src/graphics.tex
new file mode 100644
index 00000000000..03256a1fb42
--- /dev/null
+++ b/Master/texmf-doc/doc/chinese/lnotes/src/graphics.tex
@@ -0,0 +1,1256 @@
+\chapter{插图}
+\label{sec:graphics}
+
+\begin{quotation}
+A picture says more than a thousand words.
+\begin{flushright}
+--- Shakespeare
+\end{flushright}
+\end{quotation}
+
+当年~Knuth~开发~\TeX~时,GIF、JPEG、PNG、EPS~等图形格式还没有问世,所以~DVI~不能直接支持这些格式。但是高手就是高手,Knuth~在~\TeX~上留了一个后门:\verb|\special|~命令,让后面的~Driver~决定怎样处理图形。
+
+这和当年老毛把港澳台,老邓把钓鱼岛都“留给后人解决”有异曲同工之妙。曾经有位出版社的编辑看上了包老师写的一个程序,要包老师改改当作教学辅助软件出版,但是包老师手头没有~DOS~中断的资料没办法加鼠标操作。该编辑说:你把鼠标驱动打包在软件里,让用户自己琢磨是怎么回事。
+
+下面我们会在~\ref{sec:graphics_format}~节介绍一下~\LaTeX~所用图形格式,\ref{sec:includegraphics}~节介绍怎样插入已有的图形,\ref{sec:mp}--\ref{sec:pgf}~节讨论怎样制作矢量图形。
+
+\section{图形格式}
+\label{sec:graphics_format}
+
+\LaTeX~支持点阵图形格式~JPEG~和~PNG,也支持矢量格式~EPS~和~PDF。对于示意图,我们应该首选矢量格式;包含大量自然色彩的图像(比如照片)应该选~JPEG,人工点阵图像应该选~PNG。
+
+\subsection{EPS}
+80~年代中后期,PS~风头之劲一时无两,人们自然会考虑把它作为文档中嵌入图形的标准格式。然而~PS~实在太强大,人们担心嵌入文档的~PS~会搞破坏,于是就产生了戴着手铐的~Encapsulated PostScript(EPS)。出于同样的原因,人们也担心嵌入~HTML~的~ActiveX、Java Applet、JavaScript~中混入恶意代码,所以才会对它们也有所限制。
+
+早年间~DVI~经常被转换为~PS,所以~EPS~就成了~\LaTeX~的标准图形格式。
+
+\subsection{Driver~们的口味}
+
+\subsubsection{dvips}
+\verb|dvips|~喜欢~PS,所以就爱屋及乌只支持嵌入~EPS。MiKTeX~看不惯这种垄断行为,就把~\verb|dvips|~破解,添加了对~JPEG~和~PNG~的支持。如果你反对这种黑客破解行径,只好找软件把其它图形格式转换为~EPS。
+
+\subsubsection{pdf\LaTeX}
+pdf\LaTeX~支持~JPEG、PNG和PDF,不支持~EPS。传说pdf\LaTeX~不支持~EPS~的原因是~PS~解释器的版权问题。包老师认为这种说法不可信,因为~1997~年~Hàn The Thành~发布~pdf\TeX~时~PS~已经被~PDF~赶超,Adobe~与其保护~PS~还不如保护~PDF。
+
+\LaTeX~有两个宏包~\verb|epstopdf|~和~\verb|pst-pdf|~可以实时地(on the fly)把~EPS~转换为~PDF\footnote{在这里on the fly是指在后台处理,用户不用操心。包老师不确定把它翻译为“实时”是否合适,因为~real time~通常被翻译为实时。对于用户无须干涉、知情的情况,有人说~user transparent,也有人说~black box,语言还真奇妙。}。然而前者有安全漏洞,后者用法繁琐,用户最好还是用其它软件事先把~EPS~转为~PDF。
+
+\subsubsection{dvipdfm}
+\verb|dvipdfm|~支持~JPEG、PNG、PDF,不支持~EPS,但是它可以实时地调用~Ghostscript~把~EPS~转为~PDF。所以从图形格式支持的角度来讲,\verb|dvipdfm|~比~\verb|dvips|~和~pdf\LaTeX~都好。
+
+那位同学说了,你这么多废话作甚,直接告诉我们用~\verb|dvipdfm|~不就完了。然而你别忘了~\verb|dvipdfm|~需要~DVI~作为输入,不幸的是用来生成~DVI~的~\verb|latex|~对~JPEG~和~PNG~有意见。
+
+综上所述,这些~driver~都不能把图形格式痛快地通吃,所以同学们别着急,且听包老师慢慢忽悠怎样转换和处理图形格式。
+
+\subsection{图形格式转换}
+
+注意把点阵图形转换为矢量图形并不能提高图形本身的质量,正所谓“garbage in, garbage out”。
+
+\subsubsection{JPEG~和~PNG~的范围框}
+
+作为中间格式的~DVI~不包含图形本身,它只记录图形的尺寸和文件名,因为具体的图形处理由后面的~driver~负责。DVI~中图形的尺寸来自它的范围框(bounding box),而~\verb|latex|~无法从点阵图形文件中提取这一信息,所以我们需要以某种方式把范围框信息告诉它。
+
+一种方法是打开图形文件,记下尺寸,插入图形时加上相应的参数。
+
+另一种方法用~\verb|ebb|~程序生成一个含范围框信息的文件。比如下例会生成~\verb|graph.bb|~文件,有了它插入图形时就不需要范围框参数。注意有时此程序算出的范围框不准,不知道是它的~bug~还是包老师的人品问题。
+\begin{code}
+ebb graph.jpg
+\end{code}
+
+\subsubsection{其它格式转为EPS}
+有很多程序都可以把点阵图形转换为~EPS,比如~\href{http://www.imagemagick.org/}{ImageMagick},以及~\href{http://www.tex.ac.uk/cgi-bin/texfaq2html?label=dvipsgraphics}{~a2ping/sam2p、bmeps、jpeg2ps、sam2p}~等。
+
+PS~从~Level 2~开始才支持点阵图形压缩,所以在把其它格式转为~EPS~时应尽量使用~Level 2~或~3,否则输出的~EPS~会很大。
+
+下面是一个~ImageMagick~中~\verb|convert|~程序的例子。
+\begin{code}
+convert photo.jpg eps2:photo.eps
+\end{code}
+
+另外还有一种~PS~虚拟打印机的方法,优点是可以把几乎所有文件“打印”成~EPS,缺点是输出的是~PS Level 1,即使驱动程序提供了其它~Level~的选项。
+
+\begin{enumerate}
+\item 找一个~PS~打印机驱动程序。Windows~安装盘附带很多打印机驱动,其中带~PS~字样的就是~PS~驱动。包老师选的是“HP Color LaserJet 8550-PS”,Adobe~提供的~PS~驱动效果不太好。其它驱动安装过程可能稍有不同。
+\item 安装时端口选“FILE”,或者后面打印时选择“Print to File”。高级选项里的~PS~选项选“Encapsulated PostScript (EPS)”。
+\item 打开点阵图形文件,打印到上面的虚拟打印机,输出的文件就是~EPS,但是它没有范围框。
+\item 用~GSview~打开上面生成的~EPS,不用理会没范围框的警告,Options~菜单里选上“EPS Clip”,用~File~菜单的“PS to EPS”生成含范围框的~EPS。
+\end{enumerate}
+
+\subsubsection{其它格式转为~PDF}
+
+\LaTeX~附带的~\verb|epstopdf|~程序\footnote{这个命令行程序和上面提到的~epstopdf~宏包是两样东西。}可以把~EPS~转为~PDF。类似地我们也可以安装一个~PDF~虚拟打印机,用它来把其它图形文件转为~PDF。
+
+\section{插入图形}
+\label{sec:includegraphics}
+
+\subsection{插入命令}
+如今万事俱备,只欠插入。上回讲到哪儿来着?Yeah,~Knuth~的后门~\verb|\special|。
+
+用低级命令~\verb|\special|~来插入图形很不爽,于是~\LaTeX~v2.09~增加了~\verb|epsf|~和~\verb|psfig|~宏包。之后~\LaTeXe~推出了更好的~\verb|graphics|~和~\verb|graphicx|~宏包,这两个宏包有个共同的命令:\verb|\includegraphics|。\verb|graphicx|~版本的语法更简单,功能更强大,所以一般推荐用它。
+
+插入图形的具体命令如下,如果是点阵图形需要加范围框参数(左上角和右下角坐标)。
+
+\begin{code}
+\includegraphics[bb=0 0 410 307]{photo.jpg}
+\end{code}
+
+若想省略文件后缀,可在插入图形前使用两个命令。前者指定一个后缀列表,让~\LaTeX~自行查找;后者告诉~\LaTeX~未知后缀的都是~EPS。
+\begin{code}
+\DeclareGraphicsExtensions{.eps,.mps,.pdf,.jpg,.png}
+\DeclareGraphicsRule{*}{eps}{*}{}
+\end{code}
+
+\subsection{缩放、旋转}
+\Fref{tab:scale_angle}~和\Fref{tab:clip}~的选项可以用来缩放、旋转和裁剪插图。
+
+\begin{table}[htbp]
+\caption{includegraphics~命令的缩放和旋转选项}
+\label{tab:scale_angle}
+\centering
+\begin{tabularx}{350pt}{lX}
+ \toprule
+ scale & 缩放比例 \\
+ width & 宽度 \\
+ height & 高度 \\
+ totalheight & 范围框高度,旋转时它不等于高度 \\
+ keepaspectratio & 如果不使用它而同时指定插图的宽度、高度,长宽比可能会失调;使用它时长宽比不变,宽度、高度都不超过指定参数 \\
+ angle & 旋转角度 \\
+ origin & 旋转原点 \\
+ \bottomrule
+\end{tabularx}
+\end{table}
+
+\begin{table}[htbp]
+\caption{includegraphics~命令的裁剪选项}
+\label{tab:clip}
+\centering
+\begin{tabularx}{350pt}{lX}
+ \toprule
+ viewport & 可视区域的左上角和右下角坐标。\\
+ trim & 左、下、右、上四边裁剪的数值。\\
+ clip & 是否真正裁剪。缺省为false,不执行裁剪,多出的部分就那样放着;设置为true时执行裁剪。似乎是多此一举。\\
+ \bottomrule
+\end{tabularx}
+\end{table}
+
+若想深入了解~\LaTeX~插入图形的功能,请参考~Keith Reckdahl~的《Using Imported Graphics in \LaTeX~ and pdf\LaTeX》\citep{Reckdahl_2006}(简称epslatex)。
+
+\subsection{figure环境}
+插图通常需要占据大块空白,所以在文字处理软件中用户经常需要调整插图的位置。\LaTeX~有一个~\verb|figure|~环境可以自动完成这样的任务,这种自动调整位置的环境称作浮动环境。
+
+\begin{code}
+\begin{figure}[htbp]%位置选项
+\centering
+\includegraphics[bb=0 0 410 307,scale=.8]{photo}
+\caption{10个月大的Anna}
+\label{fig:anna}
+\end{figure}
+\end{code}
+
+\begin{figure}[htbp]
+\centering
+\includegraphics[bb=0 0 410 307,scale=.8]{dscf4684}
+\caption{10个月大的Anna}
+\label{fig:anna}
+\end{figure}
+
+上述代码中,\verb|[htbp]|~选项用来指定插图排版的理想位置,这几个字母分别代表~here、top、bottom、float page,也就是固定位置、页顶、页尾、单独的浮动页。我们可以使用这几个字母的任意组合,一般不推荐单独使用~\verb|[h]|,因为那个位置也许很不合适,\LaTeX~会很生气。
+
+\verb|\centering|~用来使插图居中,\verb|\caption|~命令设置插图标题,\LaTeX~会自动给浮动环境的标题加上编号。注意~\verb|label|~应放在\verb|caption|~之后,否则引用时指向的是前一个插图。
+
+\subsection{插入多幅图形}
+\subsubsection{并排摆放,共享标题}
+当我们需要两幅图片并排摆放,并共享标题时,可以在~\verb|figure|~环境中使用两个~\verb|\includegraphics|~命令。
+
+\begin{fdemo}{
+\centering
+\includegraphics[scale=2]{examples/subfig_left.mps}
+\includegraphics[scale=2]{examples/subfig_right.mps}
+\captionof{figure}{反清复明}
+}
+\begin{figure}[htbp]
+\centering
+\includegraphics{left}
+\includegraphics{right}
+\caption{反清复明}
+\end{figure}
+\end{fdemo}
+
+\subsubsection{并排摆放,各有标题}
+如果想要两幅并排的图片各有自己的标题,可以在~\verb|figure|~环境中使用两个~\verb|minipage|~环境,每个环境里插入一个图。
+\begin{code}
+\begin{figure}[htbp]
+\centering
+\begin{minipage}[t]{0.3\textwidth}
+ \centering
+ \includegraphics{left}
+ \caption{清明}
+\end{minipage}
+\end{code}
+\begin{code}
+\begin{minipage}[t]{0.3\textwidth}
+ \centering
+ \includegraphics{right}
+ \caption{反复}
+\end{minipage}
+\end{figure}
+\end{code}
+
+\begin{figure}[htbp]
+\centering
+\begin{minipage}[t]{0.3\textwidth}
+ \centering
+ \includegraphics[scale=2]{examples/subfig_left.mps}
+ \caption{清明}
+\end{minipage}
+\begin{minipage}[t]{0.3\textwidth}
+ \centering
+ \includegraphics[scale=2]{examples/subfig_right.mps}
+ \caption{反复}
+\end{minipage}
+\end{figure}
+
+\subsubsection{并排摆放,共享标题,各有子标题}
+如果想要两幅并排的图片共享一个标题,并各有自己的子标题,可以使用~\verb|subfig|~宏包提供的~\verb|\subfloat|~命令。
+
+\verb|subfloat|~命令缺少宽度参数。虽然我们可以用~\verb|\hspace|~命令调整子图的距离,子标题却只能和子图本身一样宽,就会出现折行。
+\begin{code}
+\usepackage{subfig}
+\begin{figure}[htbp]
+\centering
+\subfloat[清明]{
+ \label{fig:subfig_a}
+ \includegraphics{left}
+}
+\hspace{80pt}
+\subfloat[反复]{
+ \label{fig:subfig_b}
+ \includegraphics{right}
+}
+\caption{反清复明}
+\end{figure}
+\end{code}
+
+每个子图可以有各自的引用,就象这个样子:\Fref{fig:subfig_a}、\Fref{fig:subfig_b}。
+\begin{figure}[htbp]
+\centering
+\subfloat[清明]{
+ \label{fig:subfig_a}
+ \includegraphics[scale=2]{examples/subfig_left.mps}
+}
+\hspace{80pt}
+\subfloat[反复]{
+ \label{fig:subfig_b}
+ \includegraphics[scale=2]{examples/subfig_right.mps}
+}
+\caption{反清复明}
+\end{figure}
+
+\subsubsection{改进的子图方法}
+为了避免子标题折行,我们可以在~\verb|\subfloat|~里再嵌套个~\verb|minipage|,因为后者是有宽度的。
+\begin{code}
+\begin{figure}[htbp]
+\centering
+\subfloat[清明]{
+\label{fig:improved_subfig_a}
+\begin{minipage}[t]{0.3\textwidth}
+ \centering
+ \includegraphics{left}
+\end{minipage}
+}
+\subfloat[反复]{
+\label{fig:improved_subfig_b}
+\begin{minipage}[t]{0.3\textwidth}
+ \centering
+ \includegraphics{right}
+\end{minipage}
+}
+\caption{反清复明}
+\end{figure}
+\end{code}
+
+\begin{figure}[htbp]
+\centering
+\subfloat[清明]{
+\begin{minipage}[t]{0.3\textwidth}
+ \centering
+ \includegraphics[scale=2]{examples/subfig_left.mps}
+\end{minipage}
+}
+\subfloat[反复]{
+\begin{minipage}[t]{0.3\textwidth}
+ \centering
+ \includegraphics[scale=2]{examples/subfig_right.mps}
+\end{minipage}
+}
+\caption{反清复明}
+\end{figure}
+
+\section{图形绘制工具比较}
+与~\LaTeX~配套使用的绘图工具主要有三种:\MP、PSTricks~和~PGF,它们的特点如下。
+
+\begin{itemize}
+\item 工作方式。\MP~离线绘图,生成的~EPS~可以插入~\LaTeX~文档;PSTricks~和~PGF~都采用在线绘图的方式,也就是~\LaTeX~文档内直接使用绘图命令。
+\item 兼容性。\MP~生成的~MPS~需要先转为~PDF~才能被~pdf\LaTeX~使用;PSTricks~生成的~EPS和~pdf\LaTeX~不兼容;PGF~提供针对各种~driver~的接口,兼容性最好。
+\item 功能。PSTricks~有~PS~作后盾,功能最强;\MP~擅长处理数学内容;PGF~的流程图有独到之处。
+\end{itemize}
+
+限于篇幅,本文只对这三种工具进行简介。除了它们,用户也可以考虑一些面向~\LaTeX~的绘图前端,比如~Unix/Linux~下的~xfig~和~Windows~下的~TpX;或可以输出~EPS~的专用软件,比如~gnuplot~和~Matlab。
+
+\section{\MP}
+\label{sec:mp}
+
+1989~年~John D. Hobby\footnote{Hobby 1985年从斯坦福获博士学位,导师就是Knuth,现供职于贝尔实验室。}开始设计一种绘图语言及其编译器,也就是~\MP。\MP~从~\MF~那里获得了大量灵感和源代码,学生从导师那里顺点东西自然是手到擒来。\MP~和~\MF~语法类似,\MP~的主要优点在于是它输出的是~EPS,而且支持彩色;\MF~输出的是点阵格式,不支持彩色。Knuth~声称自己画图时只用~\MP。
+
+从~Hobby~主页上~\MP~的更新记录看,它的最后版本是~0.63,年份是~1994。目前~Taco Hoekwater\footnote{他也是LuaTeX开发者之一。}继续~\MP~的开发工作,最新版本是~1.005。
+
+本文只对~\MP~作简单介绍,若想深入了解请参阅~Hobby~的《A User's Manual for MetaPost》\citep{Hobby_2007}。
+
+\subsection{准备工作}
+用户一般需要把~\MP~源文件(.mp)用一个命令行程序~\verb|mpost|~编译为一种特殊的~EPS,也称作~MPS,然后再把~MPS~插入~\LaTeX~源文件中使用。
+\begin{figure}[htbp]
+\centering
+\begin{tikzpicture}
+ \node[box] (mp) {.mp};
+ \node[box, right=5 of mp] (mps) {.mps};
+ \path (mp) edge [arrow] node[auto] {mpost} (mps);
+\end{tikzpicture}
+\caption{MetaPost~的编译}
+\label{fig:mp}
+\end{figure}
+
+一个~\MP~源文件可以包含多个图形,一般形式如下。代码中每行语句以~\verb|;|~结尾,注释行以~\verb|%|~起始。每个图形的绘图命令包含在一对起始和结尾声明之间。文件结尾也要有一个结尾声明。
+\begin{code}
+beginfig(1); %图形起始
+... %绘图命令
+endfig; %图形结尾
+
+beginfig(2);
+...
+endfig;
+...
+end; %文件结尾
+\end{code}
+
+假如上面的源文件名字是~\verb|fig.mp|,我们可以执行以下编译命令。
+\begin{code}
+mpost fig(.mp)
+\end{code}
+
+编译后就会生成“fig.1、fig.2、$\cdots$”~等文件,每个文件的后缀就是相应的图形起始声明的编号。所以此编号在一个源文件中应保持唯一,否则后生成的文件就会覆盖前面的。
+
+这样的文件名管理起来很麻烦,插入它们时也不能省略后缀,因为~\LaTeX~不能识别它们。用~\verb|\DeclareGraphicsExtensions|~来逐一声明后缀看起来很傻,自己改文件名更傻,\verb|\DeclareGraphicsRule|~也显得不够严谨。
+
+然而~\MP~已经考虑到这个问题,为此提供了一个文件名模板命令。把下面的代码加到源文件头部,编译输出的文件名就会是“fig-01.mps、fig-02.mps、$\cdots$”。
+\begin{code}
+filenametemplate "%j-%2c.mps"; %加在源文件头部
+\end{code}
+
+我们也可以把这个命令加在每个图形的起始声明之前,指定个性化的输出文件名,这样可能更便于记忆。
+\begin{code}
+filenametemplate "flowchart.mps" %加在每个图形前面
+\end{code}
+
+MPS~可以用~GSview~查看,我们也可以用以下命令把它转为~PDF~再用~Adobe Reader~查看。
+
+\begin{code}
+epstopdf flowchart.mps
+\end{code}
+
+\subsection{基本图形对象}
+为了节省空间,本节后面的示例会略去图形起始声明和结尾声明等不重要的细节。
+
+\subsubsection{直线}
+
+绘图命令~\verb|draw|~把几个点以直线段连接起来。\MP~中的缺省长度单位是~bp,用户也可以使用\Fref{tab:unit}~中的其它单位。我们还可以定义一个缩放系数,把坐标都转换成此系数的倍数,这样以后想缩放图形时只要改这个系数即可。
+
+注意~\MP~中的变量赋值符号是~\verb|:=|,而~\verb|=|~用于方程式。变量在同一源文件中只须定义一次,其后的图形中都可以使用。
+
+\begin{fdemo}{\includegraphics{examples/line.mps}}
+draw (0,0)--(40,0)--(20,20)--(0,0);
+u:=10pt; %缩放系数
+draw (5u,0)--(9u,0)--(7u,2u)--cycle;
+\end{fdemo}
+
+几段直线或曲线可以构成一条路径(path),在路径末尾加个~\verb|cycle|~就能构成封闭路径(closed path)。上例中的两个三角形看起来都是封闭的,但是前面这个其实不是真正的封闭路径。
+
+\subsection{点和线宽}
+\verb|drawdot|~命令可以在指定坐标画一个点,为了使它醒目些我们可以换支粗一点的画笔。\MP~中的画笔缺省是直径~0.5pt~的圆形,拿它画出来的线宽就是~0.5pt。
+
+\begin{fdemo}{\includegraphics{examples/dot.mps}}
+draw (0,0)--(10u,4u);
+pickup pencircle scaled 2pt;
+drawdot (0,0);
+drawdot (10u,4u);
+\end{fdemo}
+
+上面的~\verb|pickup|~是一种全局操作,也就是说它会影响到之后所有的绘图命令,我们也可以用~\verb|withpen|~为单个绘图命令设置画笔。
+
+\begin{code}
+draw (0,0)--(10u,4u) withpen pencircle scaled 2pt;
+\end{code}
+
+\subsubsection{曲线}
+曲线和直线的命令相近,只是把连接两个点的~\verb|--|~换成了~\verb|..|。如果共用一些坐标,直线和曲线也可以混在一条语句里画。
+
+\begin{fdemo}{\includegraphics{examples/curve.mps}}
+draw (0,.5u)..(5u,3u)..(10u,1.5u)..
+ (7u,0)..(5u,1.5u)..(7u,1.5u);
+\end{fdemo}
+
+\MP~的曲线用三次贝塞尔(Cubic B\'ezier)算法实现。用户可以在命令中增加~direction(方向)、Tension(张力)和~Curl(曲率)等控制,限于篇幅本文不赘述。
+
+\subsubsection{预定义图形}
+~\verb|fullcircle|~命令以原点为圆心画一个单位圆,类似的预定义图形还有~\verb|halfcircle、quartercircle、unitsquare|~等。注意单位正方形的参考点在左下而不在其中心。
+
+通过不同的横向和纵向缩放系数,我们可以把圆形和正方形变成椭圆和长方形。
+
+\begin{code}
+draw fullcircle scaled 2u;
+draw halfcircle scaled 2u shifted (3u,0);
+draw quartercircle scaled 2u shifted (5u,0);
+draw fullcircle xscaled 4u yscaled 2u shifted (9u,0);
+draw unitsquare scaled 2u shifted (12u,-u);
+draw unitsquare xscaled 4u yscaled 2u shifted (15u,-u);
+\end{code}
+
+\begin{out}
+\includegraphics{examples/predefined.mps}
+\end{out}
+
+\subsection{图形控制}
+
+\subsubsection{线型和箭头}
+在绘制图形时,我们不仅可以变换线宽,也可以使用多种线型。
+\begin{code}
+draw (0,0)--(10u,0) dashed withdots;
+draw (0,1u)--(10u,1u) dashed withdots scaled 2;
+draw (0,2u)--(10u,2u) dashed evenly;
+draw (0,3u)--(10u,3u) dashed evenly scaled 2;
+\end{code}
+
+\begin{out}
+\includegraphics{examples/dashed.mps}
+\end{out}
+
+箭头和直线、曲线的语法相近,注意画反向箭头时需要把两个坐标用一对~\verb|()|~括起来。
+
+\begin{fdemo}{\includegraphics{examples/arrow.mps}}
+drawarrow (0,4u)--(9u,4u);
+drawarrow reverse ((0,2u)--(9u,2u));
+drawdblarrow (0,0)--(9u,0);
+\end{fdemo}
+
+\subsubsection{颜色和填充}
+\MP~预定义的颜色有黑、白、红、绿、蓝,它们的~RGB~值分别为(0,0,0)、(1,1,1)、(1,0,0)、(0,1,0)、(0,0,1),缺省色就是黑色。
+
+绘图命令一般都可以通过~\verb|withcolor|~参数来使用各种颜色。封闭路径可以用~\verb|fill|~命令填充。
+
+\begin{fdemo}{\includegraphics{examples/color.mps}}
+draw (0,4u)--(9u,4u) withcolor red;
+draw (0,2u)--(9u,2u) withcolor green;
+draw (0,0)--(9u,0) withcolor blue;
+\end{fdemo}
+
+\begin{code}
+fill p scaled u;
+fill p scaled u shifted (3u,0) withcolor red;
+fill p scaled u shifted (6u,0) withcolor green;
+fill p scaled u shifted (9u,0) withcolor blue;
+\end{code}
+
+\begin{out}
+\includegraphics{examples/fill.mps}
+\end{out}
+
+另一个命令~\verb|filldraw|~可以看作是~\verb|fill+draw|,它除了填充外还会把路径用指定的画笔画一遍。然而不幸的是画边缘和填充内部只能用同一种颜色,所以它的用处不大。
+
+除了为每个绘图命令单独指定颜色,我们也可以使用一个全局命令,使得其后的绘图命令都使用某种颜色。
+\begin{code}
+drawoption(withcolor blue);
+\end{code}
+
+下面的方法可以用来定义基本色以外的颜色,用基本色混色或直接用RGB值效果是一样的。
+
+\begin{code}
+color c[];
+c1 := .9red + .6green + .3blue;
+c2 := (.9,.6,.3);
+\end{code}
+
+\subsubsection{图形变换}
+我们可以对路径进行缩放、平移、旋转等变换操作,横向和纵向缩放可以分开进行。由于旋转是围绕原点进行的,所以要注意平移和旋转的顺序。下例中定义了一个~\verb|path|~变量,以便后面重用。
+
+\begin{code}
+path p;
+p := (0,0)--(2,0)--(1,1.732)--cycle;
+draw p scaled u;
+draw p xscaled 2u yscaled u shifted (3u,0);
+draw p scaled u rotated 60 shifted (8u,0);
+\end{code}
+
+\begin{out}
+\includegraphics{examples/transform.mps}
+\end{out}
+
+\subsubsection{标注}
+\verb|\label|~命令可以在指定的点附近加文字标注。\MP~也可以用一对~\verb|btex|~和~\verb|etex|~来嵌入一些~\TeX~内容,比如数学标注。
+
+\begin{code}
+draw unitsquare xscaled 10u yscaled 4u;
+label.top("top", (5u,4u));
+label.bot("bottom", (5u,0));
+label.lft("left", (0,2u));
+label.rt("right", (10u,2u));
+\end{code}
+\begin{code}
+label.ulft("upper left", (0,4u));
+label.urt("upper right", (10u,4u));
+label.llft("lower left", (0,0));
+label.lrt("lower right", (10u,0));
+label.rt(btex $E=mc^2$ etex, (3u,2u));
+\end{code}
+
+\begin{out}
+\includegraphics{examples/label.mps}
+\end{out}
+
+因为用缺省方法编译生成的~MPS~不嵌入字体,当~\MP~包含文字时,GSview~就不能正常查看。这时我们可以给编译命令加个参数,生成的~MPS~就会包含字体信息。注意这种方法生成的~MPS~虽然~GSview~能查看,\verb|dvipdfmx|~却不能正常处理。
+
+\begin{code}
+mpost \prologues:=2; input fig.mp
+\end{code}
+
+\subsection{编程功能}
+
+\subsubsection{数据类型和变量}
+\MP~中有10~种基本数据类型:numeric、pair、path、pen、~color~、cmykcolor、transform、string、boolean、picture。我们已经接触过其中几种,比如缩放系数~u~就是一个~numeric,一个点的坐标是一个~pair,几个点用直线或曲线连起来是一个~path,pencircle~是一种~pen,black~是一种~color,scaled、rotated、shifted~都是~transform。
+
+numeric~类型变量的精度是~1/65536,它的绝对值不能超过~4096,在计算过程中数值可以达到~32768。这样的规定也应归功于当年的电脑硬件,不过对于科技文档插图而言,4096~一般还是够用的。
+
+除了缺省的~numeric,其它变量在使用之前都需要用数据类型来显式声明。相同类型的变量可以在一行语句中声明,但是带下标的变量不能放在同一行(这个规定很蹊跷)。
+\begin{code}
+numeric x,y,z; %正确
+numeric x1,x2,x3; %错误
+numeric x[]; %正确
+\end{code}
+
+\subsubsection{数学运算}
+\MP~中可以使用普通的运算符,比如~\verb|+ - * /|;也提供一些特殊的运算符,比如~\verb|a++b|~表示$\sqrt{a^2+b^2}$,\verb|a+-+b|~表示$\sqrt{a^2-b^2}$;另外\Fref{tab:math_function}~列出一些常用数学函数。
+
+\begin{table}[htbp]
+\caption{数学函数}
+\label{tab:math_function}
+\centering
+\begin{tabular}{llll}
+ \toprule
+ abs & 绝对值 & mexp & 指数 \\
+ round & 四舍五入 & mlog & 对数 \\
+ ceiling & 向上圆整 & sind & 正弦 \\
+ floor & 向下圆整 & cosd & 余弦 \\
+ mod & 模余 & normaldeviate & 正态分布随机数 \\
+ sqrt & 开方 & uniformdeviate & 均匀分布随机数 \\
+ \bottomrule
+\end{tabular}
+\end{table}
+
+\subsubsection{循环}
+当执行重复任务时,循环语句可以让程序变得简洁。注意下例中的循环语句是一条命令,之所以分成三行写是为了看起来清晰点。
+
+\begin{fdemo}{\includegraphics{examples/loop.mps}}
+draw (0,0) %注意这里没有分号
+for x=1 upto 3:
+ ..(x*x,x)*u
+endfor;
+\end{fdemo}
+
+循环语句缺省步长是~1,我们也可以改用其它步长。\verb|upto|~其实就是~\verb|step 1 until|~的缩写方式。
+\begin{code}
+for x=1 step .5 until 3:
+\end{code}
+
+\section{PSTricks}
+\label{sec:pstricks}
+
+PSTricks~是一个基于~PS~的宏包,有了它用户就可以直接在~\LaTeX~文档中插入绘图命令。PSTricks~早期的作者是~Timothy Van Zandt\footnote{法国Insead大学经济系教授。},初始开发年月不详,他于~1997~年退居二线,之后由~Denis Girou、Sebastian Rahtz\footnote{牛津大学计算机系网管。}、Herbert Voß~等维护。
+
+本文只介绍~PSTricks~的基本功能,若想深入了解请参阅~Van Zandt~的《PSTricks User's Guide》\citep{Zandt_2007}。另外\Fref{tab:pst_add}~列出了一些可以和~PsTricks~配合使用的辅助宏包。
+
+\begin{table}[htbp]
+\caption{PSTricks~辅助宏包}
+\label{tab:pst_add}
+\centering
+\begin{tabular}{llll}
+ \toprule
+ multido & 循环语句 & pst-eucl & 几何函数 \\
+ pst-plot & 函数绘图 & pst-math & 弧度三角函数 \\
+ pst-plot3d & 三维绘图 & pstricks-add & 极坐标 \\
+ \bottomrule
+\end{tabular}
+\end{table}
+
+\subsection{准备工作}
+首先要引入~PSTricks~宏包。PSTricks~中缺省长度单位是~1cm,我们也可以设置自己的单位。
+\psset{unit=10pt}
+\begin{code}
+\usepackage{pstricks}
+\psset{unit=10pt}
+\end{code}
+
+绘图命令一般要放在~\verb|pspicture|~环境里,这样~\LaTeX~就会给图形预留一个矩形区域,注意这个矩形要能容纳所有图形对象。为了节省空间,在本节后面的示例代码中,~\verb|pspicture|~环境将被略去。
+
+\begin{code}
+\begin{pspicture}(0,0)(4,2)
+...
+\end{pspicture}
+\end{code}
+
+另外需要注意的是,嵌入~\LaTeX~的~PSTricks~生成的是~PS,\verb|dvips|~可以处理,\verb|dvipdfm|~和pdf\LaTeX~则不能。所以如果使用后两种~driver,需要先行生成~EPS。
+
+第一种方法是把~PSTricks~代码放进一个空白的\LaTeX~页面,用它生成一个简单的~DVI。
+
+\begin{code}
+\documentclass{article}
+\usepackage{pstricks}
+\pagestyle{empty} %页面样式为空
+
+\begin{document}
+\psset{unit=10pt}
+\colorbox{white}{%
+ \begin{pspicture}(0,0)(4,2)%
+ \psdot(0,0)%
+ \psdots(0,2)(2,2)(4,2)%
+ \end{pspicture}%
+}
+\end{document}
+\end{code}
+
+然后用以下命令把~DVI~转为~EPS,\verb|-E|~参数即代表~EPS。上面代码中的~colorbox~使得生成的~EPS~有正确的范围框。
+
+\begin{code}
+dvips pst_dots(.dvi) -E -o dots.eps
+\end{code}
+
+第二种方法是用~\verb|pst-eps|~宏包,它能够在线处理~PSTricks~代码并生成~EPS,这样用户就可以在同一文件中使用该~EPS。
+
+然而~\verb|dvipdfmx|~不能正确处理~\verb|pst-eps|~生成的~EPS。它和~\verb|\rput|、\verb|\uput|~命令,\verb|pst-plot|~宏包中的~\verb|\psaxes|~命令都不兼容。类似的~\verb|ps4pdf|~宏包和~\verb|tabularx|~宏包不兼容。
+
+\begin{comment}
+\usepackage{pst-eps}
+\PSTtoEPS[bbllx=0,bblly=0,bburx=4,bbury=2,makeeps=all]
+{dots.eps}{
+ \psdot(0,0)
+ \psdots(0,2)(2,2)(4,2)
+}
+\includegraphics{dots.eps}
+\end{comment}
+
+\subsection{基本图形对象}
+\subsubsection{点}
+我们可以用以下命令画一个或多个点。
+\begin{comment}
+\PSTtoEPS[bbllx=0,bblly=0,bburx=4,bbury=2,makeeps=all]
+{examples/dot.eps}{
+ \psdot(0,0)
+ \psdots(0,2)(2,2)(4,2)
+}
+\end{comment}
+
+\begin{fdemo}{\includegraphics{examples/pst_dot.eps}}
+\psdot(0,0)
+\psdots(0,2)(2,2)(4,2)
+\end{fdemo}
+
+\subsubsection{直线、多边形、矩形}
+\verb|\psline|~命令把多个点用直线段连接起来,线段之间的连接缺省为尖角,也可以设置圆角。
+\begin{comment}
+\PSTtoEPS[bbllx=0,bblly=0,bburx=9,bbury=2,makeeps=all]
+{examples/line.eps}{
+ \psline(0,0)(2,2)(4,0)
+ \psline[linearc=.3](5,0)(7,2)(9,0)
+}
+\end{comment}
+
+\begin{fdemo}{\includegraphics{examples/pst_line.eps}}
+\psline(0,0)(2,2)(4,0)
+\psline[linearc=.3](5,0)(7,2)(9,0)
+\end{fdemo}
+
+\verb|\pspolygon|~命令和~\verb|\psline|~类似,但是它会形成封闭路径。
+\begin{comment}
+\PSTtoEPS[bbllx=0,bblly=0,bburx=9,bbury=2,makeeps=all]
+{examples/polygon.eps}{
+ \pspolygon(0,0)(2,2)(4,0)
+ \pspolygon[linearc=.3](5,0)(7,2)(9,0)
+}
+\end{comment}
+
+\begin{fdemo}{\includegraphics{examples/pst_polygon.eps}}
+\pspolygon(0,0)(2,2)(4,0)
+\pspolygon[linearc=.3](5,0)(7,2)(9,0)
+\end{fdemo}
+
+矩形用~\verb|\psframe|~命令,其参数就是矩形左下角和右上角的坐标。矩形也可以设置圆角。
+\begin{comment}
+\PSTtoEPS[bbllx=0,bblly=0,bburx=9,bbury=2,makeeps=all]
+{examples/frame.eps}{
+ \psframe(0,0)(4,2)
+ \psframe[framearc=.3](5,0)(9,2)
+}
+\end{comment}
+
+\begin{fdemo}{\includegraphics{examples/pst_frame.eps}}
+\psframe(0,0)(4,2)
+\psframe[framearc=.3](5,0)(9,2)
+\end{fdemo}
+
+\subsubsection{圆、椭圆、圆弧、扇形}
+圆形用~\verb|\pscircle|~命令,参数是圆心和半径。椭圆用~\verb|\psellipse|~命令,参数是中心、长径、短径。注意这两个命令的半径参数用不同的括号,可能是作者的笔误。
+\begin{comment}
+\PSTtoEPS[bbllx=0,bblly=0,bburx=7,bbury=2,makeeps=all]
+{examples/circle.eps}{
+ \pscircle(1,1){1}
+ \psellipse(5,1)(2,1)
+}
+\end{comment}
+
+\begin{fdemo}{\includegraphics{examples/pst_circle.eps}}
+\pscircle(1,1){1}
+\psellipse(5,1)(2,1)
+\end{fdemo}
+
+圆弧用~\verb|\psarc|~命令,其参数是圆心、半径、起止角度,逆时针作图。~\verb|\psarcn|~类似,只是顺时针作图。扇形用~\verb|\pswedge|~命令。
+\begin{comment}
+\PSTtoEPS[bbllx=0,bblly=0,bburx=11,bbury=2,makeeps=all]
+{examples/arc.eps}{
+ \psarc(1,0){2}{0}{120}
+ \psarcn(5,0){2}{120}{0}
+ \pswedge(9,0){2}{0}{120}
+}
+\end{comment}
+
+\begin{fdemo}{\includegraphics{examples/pst_arc.eps}}
+\psarc(1,0){2}{0}{120}
+\psarcn(5,0){2}{120}{0}
+\pswedge(9,0){2}{0}{120}
+\end{fdemo}
+
+\subsubsection{曲线}
+\verb|\pscurve|~命令把一系列点用平滑曲线连接起来;它的变形版本~\verb|\psecurve|~命令不显示曲线的两个端点;另一变形命令~\verb|\psccurve|~则把曲线封闭起来。
+
+参数~\verb|showpoints=true|~用来显示曲线的构成点,此参数也可用于其它绘图命令。
+\begin{comment}
+\PSTtoEPS[bbllx=0,bblly=0,bburx=15,bbury=2,makeeps=all]
+{examples/curve.eps}{
+ \pscurve[showpoints=true](0,1)(1,2)(3,0)(4,2)(1,0)
+ \psecurve[showpoints=true](5,1)(6,2)(8,0)(9,2)(5,0)
+ \psccurve[showpoints=true](11,1)(12,2)(14,0)(15,2)(12,0)
+}
+\end{comment}
+
+\begin{code}
+\pscurve[showpoints=true](0,1)(1,2)(3,0)(4,2)(1,0)
+\psecurve[showpoints=true](5,1)(6,2)(8,0)(9,2)(5,0)
+\psccurve[showpoints=true](11,1)(12,2)(14,0)(15,2)(12,0)
+\end{code}
+\begin{out}
+\includegraphics{examples/pst_curve.eps}
+\end{out}
+
+\verb|\psbezier|~命令输出一条贝塞尔曲线,其参数就是曲线的控制点。
+\begin{comment}
+\PSTtoEPS[bbllx=0,bblly=0,bburx=6,bbury=2,makeeps=all]
+{examples/bezier.eps}{
+ \psbezier[showpoints=true]
+ (0,0)(2,2)(4,0)(6,2)
+}
+\end{comment}
+
+\begin{fdemo}{\includegraphics{examples/pst_bezier.eps}}
+\psbezier[showpoints=true]
+ (0,0)(2,2)(4,0)(6,2)
+\end{fdemo}
+
+抛物线用~\verb|\psparabola|~命令,它有两个参数,第一个是抛物线通过的一点,第二个是抛物线的顶点。
+\begin{comment}
+\PSTtoEPS[bbllx=0,bblly=0,bburx=2,bbury=2,makeeps=all]
+{examples/parabola.eps}{
+ \psparabola[showpoints=true]
+ (2,2)(1,0)
+}
+\end{comment}
+
+\begin{fdemo}{\includegraphics{examples/pst_parabola.eps}}
+\psparabola[showpoints=true]
+ (2,2)(1,0)
+\end{fdemo}
+
+\subsubsection{网格和坐标}
+科技制图通常会用到坐标网格。\verb|\psgrid|~命令输出一个矩形网格,它有三个参数点。网格坐标标注在通过第一个点的两条直线上,第二和第三个点是矩形的两个对角顶点。当第一个参数省略时,坐标标注在通过第一个顶点的两条矩形边上。
+\begin{comment}
+\psset{unit=10pt}
+\PSTtoEPS[bbllx=-1,bblly=-1,bburx=8.4,bbury=2.4,makeeps=all]
+{examples/grid.eps}{
+ \psgrid(0,0)(-1,-1)(3,2)
+ \psgrid(5,0)(8,2)
+}
+\end{comment}
+
+\begin{code}
+\psgrid(0,0)(-1,-1)(3,2)
+\psgrid(5,0)(8,2)
+\end{code}
+\begin{out}
+\includegraphics{examples/pst_grid.eps}
+\end{out}
+
+\verb|pst-plot|~宏包提供的~\verb|\psaxes|~命令输出坐标轴。它的参数和~\verb|\psgrid|~的类似,刻度和标注都可以灵活地设置,也可以把坐标轴改成一个矩形框的形式。
+\begin{code}
+\psset{unit=10pt}
+\psaxes{<->}(0,0)(-1,-1)(3,2)
+\psaxes[tickstyle=top,labels=none]{->}(5,0)(8,2)
+\psaxes[axesstyle=frame,tickstyle=top]{->}(10,0)(13,2)
+\end{code}
+\begin{out}
+\includegraphics{examples/pst_axis.eps}
+\end{out}
+
+\subsection{图形控制}
+\subsubsection{线型和箭头}
+PSTricks~中的缺省线宽是~0.8pt,缺省线型是实线。以下参数可以控制单个绘图命令的线宽和线型。
+\begin{comment}
+\psset{unit=10pt}
+\PSTtoEPS[bbllx=0,bblly=0,bburx=9,bbury=4,makeeps=all]
+{examples/linestyle.eps}{
+ \psline[linewidth=1.5pt](0,4)(9,4)
+ \psline[linestyle=dotted](0,2)(9,2)
+ \psline[linestyle=dashed](0,0)(9,0)
+}
+\end{comment}
+
+\begin{fdemo}{\includegraphics{examples/pst_linestyle.eps}}
+\psline[linewidth=1.5pt](0,4)(9,4)
+\psline[linestyle=dotted](0,2)(9,2)
+\psline[linestyle=dashed](0,0)(9,0)
+\end{fdemo}
+
+我们也可以用命令~\verb|\psset|~命令来设置全局参数。
+\begin{code}
+\psset{linewidth=1pt,linestyle=dashed}
+\end{code}
+
+以下参数可以控制绘图命令的箭头。
+\begin{comment}
+\PSTtoEPS[bbllx=0,bblly=0,bburx=9,bbury=4,makeeps=all]
+{examples/arrow.eps}{
+ \psline{->}(0,4)(9,4)
+ \psline{<-}(0,2)(9,2)
+ \psline{<->}(0,0)(9,0)
+}
+\end{comment}
+
+\begin{fdemo}{\includegraphics{examples/pst_arrow.eps}}
+\psline{->}(0,4)(9,4)
+\psline{<-}(0,2)(9,2)
+\psline{<->}(0,0)(9,0)
+\end{fdemo}
+
+\subsubsection{颜色和填充}
+PSTricks~预定义的颜色有~black、darkgray、gray、lightgray、white~等灰度颜色,也有~red、green、blue、cyan、magenta、yellow~等彩色。我们也可以自定义灰度颜色和彩色。
+
+\begin{code}
+\newgray{mygray}{.3}
+\newrgbcolor{mycolor}{.3 .4 .5}
+\end{code}
+
+以下参数可以控制单个绘图命令的颜色,我们也可以用~\verb|\psset|~命令设置全局参数。
+\begin{comment}
+\PSTtoEPS[bbllx=0,bblly=0,bburx=9,bbury=4,makeeps=all]
+{examples/color.eps}{
+ \psline[linecolor=red](0,4)(9,4)
+ \psline[linecolor=green](0,2)(9,2)
+ \psline[linecolor=blue](0,0)(9,0)
+}
+\end{comment}
+
+\begin{fdemo}{\includegraphics{examples/pst_color.eps}}
+\psline[linecolor=red](0,4)(9,4)
+\psline[linecolor=green](0,2)(9,2)
+\psline[linecolor=blue](0,0)(9,0)
+\end{fdemo}
+
+以下参数可以控制单个绘图命令的填充模式和填充颜色,注意只有封闭路径才可以填充。
+\begin{comment}
+\PSTtoEPS[bbllx=0,bblly=0,bburx=11,bbury=2,makeeps=all]
+{examples/fill.eps}{
+ \pscircle[fillstyle=solid,fillcolor=red](1,1){1}
+ \pscircle[fillstyle=vlines](4,1){1}
+ \pscircle[fillstyle=hlines](7,1){1}
+ \pscircle[fillstyle=crosshatch](10,1){1}
+}
+\end{comment}
+
+\begin{code}
+\pscircle[fillstyle=solid,fillcolor=red](1,1){1}
+\pscircle[fillstyle=vlines](4,1){1}
+\pscircle[fillstyle=hlines](7,1){1}
+\pscircle[fillstyle=crosshatch](10,1){1}
+\end{code}
+\begin{out}
+\includegraphics{examples/pst_fill.eps}
+\end{out}
+
+\subsection{对象布局}
+\subsubsection{平移}
+参数~\verb|origin|~可以让一个图形对象平移到指定的坐标点,我们也可以用~\verb|\psset|~命令设置全局平移参数。
+\begin{comment}
+\PSTtoEPS[bbllx=0,bblly=0,bburx=7,bbury=2,makeeps=all]
+{examples/origin.eps}{
+ \psframe(0,0)(3,2)
+ \psframe[origin={4,0}](0,0)(3,2)
+}
+\end{comment}
+
+\begin{fdemo}{\includegraphics{examples/pst_origin.eps}}
+\psframe(0,0)(3,2)
+\psframe[origin={4,0}](0,0)(3,2)
+\end{fdemo}
+
+\subsubsection{旋转}
+\verb|\rput|~命令可以对一个图形对象同时进行旋转和平移操作。它有两个参数,第一个是旋转角度,第二个是平移到的坐标点。
+\begin{fdemo}{\includegraphics{examples/pst_rput.eps}}
+\psframe(0,0)(3,2)
+\rput{30}(5,0){\psframe(0,0)(3,2)}
+\end{fdemo}
+
+\subsubsection{文字标注}
+\verb|\rput|~命令还可以在指定的坐标点标注文字,这时它的第一个参数是坐标点相对于标注的位置。其取值可以是纵向的~t、b(上下),或横向的~l、r(左右),也可以是纵向和横向位置的组合。
+\begin{fdemo}{\includegraphics{examples/pst_label.eps}}
+\pspolygon(0,0)(4,0)(2,3)
+\rput[r](0,0){A}
+\rput[l](4,0){B}
+\rput[b](2,3){C}
+\end{fdemo}
+
+\verb|\rput|~生成的标注就在坐标点上,有时会感觉离图形太近。另一个命令~\verb|\uput|~则生成缺省距离指定坐标点~5pt的标注,它的第一个参数是标注相对于坐标点的角度。
+\begin{fdemo}{\includegraphics{examples/pst_uput.eps}}
+\pspolygon(0,0)(4,0)(2,3)
+\uput[l](0,0){A}
+\uput[r](4,0){B}
+\uput[u](2,3){C}
+\end{fdemo}
+
+\verb|\uput|~的角度参数可以是任意角度,也可以是字母,参见。注意~\verb|\uput|~的角度参数和~\verb|\rput|~命令的参考点位置参数的定义几乎正好相反,这也许反映了作者洒脱的风格。
+
+\begin{table}[htbp]
+\caption{uput~命令的角度参数}
+\label{tab:uput}
+\centering
+\begin{tabular}{lrlr}
+ \toprule
+ r & 0$^\circ$ & ur & 45$^\circ$ \\
+ u & 90$^\circ$ & ul & 135$^\circ$ \\
+ l & 180$^\circ$ & dl & 225$^\circ$ \\
+ d & 270$^\circ$ & dr & 315$^\circ$ \\
+ \bottomrule
+\end{tabular}
+\end{table}
+
+\section{PGF}
+\label{sec:pgf}
+PGF~和~Beamer~的作者都是~Till Tantau\footnote{德国Lübeck大学计算机研究所教授。}。Tantau~当初开发~Beamer~是为了应付~2003~年他的博士学位论文答辩,之后它在~CTAN~上流行开来。2005~年~PGF~从~Beamer~项目中分离出来,成为一个独立的宏包。
+
+本文只对~PGF~作简单介绍,若想深入了解请参阅~Tantau~的《TikZ and PGF Manual》\citep{Tantau_2008}。
+
+\subsection{准备工作}
+一般人们并不直接使用~PGF~命令,而是通过它前端~TikZ~来调用~PGF。在引用~\verb|tikz|~宏包之前,用户需要设置~PGF~系统~driver。
+\begin{code}
+\def\pgfsysdriver{pgfsys-dvipdfmx.def}
+\usepackage{tikz}
+\end{code}
+
+PGF~的缺省长度单位是~1cm,我们也可以改用其它单位。注意这样预定义的长度单位有时会失效,这可能是~PGF~的~bug。
+\begin{code}
+\pgfsetxvec{\pgfpoint{10pt}{0}}
+\pgfsetyvec{\pgfpoint{0}{10pt}}
+\end{code}
+
+TikZ~提供一个~\verb|tikz|~命令和一个~\verb|tikzpicture|~环境,具体绘图指令可以放在~\verb|tikz|~后面,也可以放在~\verb|tikzpicture|~中间。两种方法效果相同,用户可以任意选择。为了节省空间,本节的示例将省略部分环境代码。
+\begin{code}
+\tikz ... %绘图命令
+\begin{tikzpicture}
+... %绘图命令
+\end{tikzpicture}
+\end{code}
+
+\subsection{基本图形对象}
+\subsubsection{直线、多边形、矩形}
+TikZ~中直线的语法和~\MP~类似,加~\verb|cycle|~参数才能构成真正的封闭路径。
+\begin{fdemo}{
+\begin{tikzpicture}
+\draw (0,0)--(4,0)--(2,2)--(0,0);
+\draw (5,0)--(9,0)--(7,2)--cycle;
+\end{tikzpicture}
+}
+\draw (0,0)--(4,0)--(2,3)--(0,0);
+\draw (5,0)--(9,0)--(7,3)--cycle;
+\end{fdemo}
+
+矩形命令如下,它的两个参数是矩形的两个对角顶点。
+\begin{fdemo}{
+\begin{tikzpicture}
+\draw (0,0) rectangle (4,2);
+\end{tikzpicture}
+}
+\draw (0,0) rectangle (4,2);
+\end{fdemo}
+
+\subsubsection{圆、椭圆、弧}
+圆和椭圆命令如下,圆的参数是圆心和半径,椭圆的参数是中心、长径、短径。
+\begin{fdemo}{
+\begin{tikzpicture}
+\draw (1,1) circle (1);
+\draw (5,1) ellipse (2 and 1);
+\end{tikzpicture}
+}
+\draw (1,1) circle (1);
+\draw (5,1) ellipse (2 and 1);
+\end{fdemo}
+
+圆弧和椭圆弧命令如下,圆弧的参数是起始点,起始角度、终止角度、半径;椭圆弧则把半径换成了长径和短径。
+\begin{fdemo}{
+\begin{tikzpicture}
+\draw (2,1) arc (0:270:1);
+\draw (7,1) arc (0:270:2 and 1);
+\end{tikzpicture}
+}
+\draw (2,1) arc (0:270:1);
+\draw (7,1) arc (0:270:2 and 1);
+\end{fdemo}
+
+\subsubsection{曲线和抛物线}
+曲线命令如下,中间的参数是控制点。
+\begin{fdemo}{
+\begin{tikzpicture}
+\draw (0,0) .. controls (2,2)
+ and (4,2) .. (4,0);
+\filldraw (0,0) circle (.1)
+ (2,2) circle (.1)
+ (4,2) circle (.1)
+ (4,0) circle (.1);
+\end{tikzpicture}
+}
+\draw (0,0) .. controls (2,2)
+ and (4,2) .. (4,0);
+\end{fdemo}
+
+抛物线命令如下,除了起止点还可以指定顶点。
+\begin{fdemo}{
+\begin{tikzpicture}
+\draw (-1,1) parabola bend (0,0) (1.414,2);
+\filldraw (-1,1) circle (.1)
+ (0,0) circle (.1)
+ (1.414,2) circle (.1);
+\end{tikzpicture}
+}
+\draw (-1,1) parabola
+ bend (0,0) (1.414,2);
+\end{fdemo}
+
+\subsection{图形控制}
+\subsubsection{线型和箭头}
+绘图命令可以设置线型和箭头参数。
+\begin{fdemo}{
+\begin{tikzpicture}
+\draw[line width=2pt] (0,3)--(9,3);
+\draw[->] (0,2)--(9,2);
+\draw[<-] (0,1)--(9,1);
+\draw[<->] (0,0)--(9,0);
+\end{tikzpicture}
+}
+\draw[line width=2pt] (0,0)--(9,0);
+\draw[->] (0,1)--(9,1);
+\draw[<-] (0,2)--(9,2);
+\draw[<->] (0,3)--(9,3);
+\end{fdemo}
+
+\subsubsection{颜色、填充、阴影}
+颜色参数的用法如下。PGF~可以使用~\verb|xcolor|~宏包\citep{Kern_2007}中定义的所有颜色。
+\begin{fdemo}{
+\begin{tikzpicture}
+\draw[red] (0,4)--(9,4);
+\draw[green] (0,2)--(9,2);
+\draw[blue] (0,0)--(9,0);
+\end{tikzpicture}
+}
+\draw[red] (0,4)--(9,4);
+\draw[green] (0,2)--(9,2);
+\draw[blue] (0,0)--(9,0);
+\end{fdemo}
+
+封闭路径可以用颜色填充,\verb|\filldraw|~命令可以分别指定边框色和填充色。
+\begin{fdemo}{
+\begin{tikzpicture}
+\fill[red] (1,1) circle (1);
+\filldraw[fill=lightgray,draw=black]
+ (4,1) circle (1);
+\end{tikzpicture}
+}
+\fill[red] (1,1) circle (1);
+\filldraw[fill=lightgray,draw=black]
+ (4,1) circle (1);
+\end{fdemo}
+
+\verb|\shade|~命令可以产生渐变和光影效果,缺省是从上到下,灰色渐变为白色。我们也可以使用其它方向和颜色的渐变。
+\begin{code}
+\shade (0,0) rectangle (2,2);
+\shade[left color=red,right color=orange] (3,0) rectangle (5,2);
+\shade[inner color=red,outer color=orange] (6,0) rectangle (8,2);
+\shade[ball color=blue] (10,1) circle (1);
+\end{code}
+
+\begin{out}
+\begin{tikzpicture}
+\shade (0,0) rectangle (2,2);
+\shade[left color=red,right color=orange] (3,0) rectangle (5,2);
+\shade[inner color=red,outer color=orange] (6,0) rectangle (8,2);
+\shade[ball color=blue] (10,1) circle (1);
+\end{tikzpicture}
+\end{out}
+
+\subsubsection{图形变换}
+对图形对象可以进行平移和旋转操作,注意如果两种操作同时进行,它们是有顺序的。注意预定义的长度单位在这里对平移参数失效。
+\begin{code}
+\draw (0,0) rectangle (2,2);
+\draw[xshift=30pt] (0,0) rectangle (2,2);
+\draw[xshift=75pt,rotate=45] (0,0) rectangle (2,2);
+\end{code}
+
+\begin{out}
+\begin{tikzpicture}
+\draw (0,0) rectangle (2,2);
+\draw[xshift=30pt] (0,0) rectangle (2,2);
+\draw[xshift=75pt,rotate=45] (0,0) rectangle (2,2);
+\end{tikzpicture}
+\end{out}
+
+\subsection{样式}
+PGF~比~\MP~和~PSTricks~多了一个有趣的概念:样式(style),它的思路和~HTML~的~CSS~相近。我们可以先定义两种样式,
+\tikzset{
+ myline/.style={line width=2pt},
+ myblueline/.style={myline,blue}
+}
+\begin{code}
+\tikzset{
+ myline/.style={line width=2pt},
+ myblueline/.style={myline,blue}
+}
+\end{code}
+
+然后就可以在绘图命令中这样使用样式。
+\begin{fdemo}{
+\begin{tikzpicture}
+\draw[myline] (0,2)--(9,2);
+\draw[myblueline] (0,0)--(9,0);
+\end{tikzpicture}
+}
+\draw[myline] (0,2)--(9,2);
+\draw[myblueline] (0,0)--(9,0);
+\end{fdemo}
+
+除了用~\verb|\tikzset|~命令定义样式,我们也可以在~\verb|tikzpicture|~环境头部声明样式。前者是全局性的,后者则是局部性的。
+\begin{code}
+\begin{tikzpicture}[
+ thickline/.style=2pt,
+ bluethickline/.style={thickline,color=blue}
+]
+...
+\end{tikzpicture}
+\end{code}
+
+注意在样式中预定义长度单位有时会失效,所以最好使用绝对单位。
+
+\subsection{流程图}
+\subsubsection{节点}
+PGF~中的节点(node)可以是简单的标签,也可以有各种形状的边框,还可以有各种复杂的属性。比如下例中的节点样式:\verb|box|,它的边框是矩形,有圆角;它有最小宽度、高度、文字和边框的距离,边框和填充颜色等属性。
+
+\begin{code}
+\tikzset{
+ box/.style={rectangle, rounded corners=6pt,
+ minimum width=50pt, minimum height=20pt, inner sep=6pt,
+ draw=gray,thick, fill=lightgray}
+}
+\end{code}
+
+除了上述类别属性,节点还可以有名字、位置等属性。在下例中,我们先画了三个有名字的文本框;然后用箭头把文本框连接起来,注意连接时要引用文本框的名字;接着在箭头上加了标签。
+\begin{code}
+\node[box] (tex) at(0,0) {.tex}; %文本框
+\node[box] (dvi) at(10,0) {.dvi}; %文本框
+\node[box] (pdf) at(20,0) {.pdf}; %文本框
+\draw[->] (tex)--(dvi); %箭头
+\draw[->] (dvi)--(pdf); %箭头
+\node at (5,1) {latex}; %标签
+\node at (15,1) {dvipdfmx}; %标签
+\end{code}
+
+\begin{out}
+\begin{tikzpicture}
+\node[box] (tex) at(0,0) {.tex};
+\node[box] (dvi) at(10,0) {.dvi};
+\node[box] (pdf) at(20,0) {.pdf};
+\draw[->] (tex)--(dvi);
+\draw[->] (dvi)--(pdf);
+\node at (5,1) {latex};
+\node at (15,1) {dvipdfmx};
+\end{tikzpicture}
+\end{out}
+
+在上例中的节点都使用了绝对位置,PGF~中还可以使用更灵活一点的相对位置。比如在下例中,dvi~节点在~tex~节点右边~50pt~处(我们前面定义的基本长度单位是~10pt),而~pdf~节点又在~dvi~节点右边~50pt~处。
+
+箭头可以换为专门用来连接节点的~\verb|edge|~;标签也改成相对位置,箭头上方~5pt~处。
+\begin{code}
+\node[box] (tex) {.tex};
+\node[box,right=5 of tex] (dvi) {.dvi};
+\node[box,right=6 of dvi] (pdf) {.pdf};
+\path (tex) edge[->] node[above=.5] {latex} (dvi)
+ (dvi) edge[->] node[above=.5] {dvipdfmx} (pdf);
+\end{code}
+
+\begin{out}
+\begin{tikzpicture}
+\node[box] (tex) {.tex};
+\node[box,right=5 of tex] (dvi) {.dvi};
+\node[box,right=6 of dvi] (pdf) {.pdf};
+\path (tex) edge[->] node[above=.5] {latex} (dvi)
+ (dvi) edge[->] node[above=.5] {dvipdfmx} (pdf);
+\end{tikzpicture}
+\end{out}
+
+\subsubsection{树}
+下面是一棵简单的树。我们可以用一个参数控制相邻节点的距离,预定义长度单位对此参数也会失效。
+\begin{code}
+\begin{tikzpicture}[sibling distance=80pt]
+\node[box] {TeX}
+ child {node[box] {Plain\TeX}}
+ child {node[box] {\LaTeX}
+ child {node[box] {MiKTeX}}
+ child {node[box] {TeX Live}}
+ child {node[box] {MacTeX}}
+ };
+\end{tikzpicture}
+\end{code}
+
+\begin{out}
+\begin{tikzpicture}[sibling distance=80pt]
+\node[box] {TeX}
+ child {node[box] {Plain\TeX}}
+ child {node[box] {\LaTeX}
+ child {node[box] {MiKTeX}}
+ child {node[box] {TeX Live}}
+ child {node[box] {MacTeX}}
+ };
+\end{tikzpicture}
+\end{out}
+
+\bibliographystyle{unsrtnat}
+\bibliography{reading}
+\newpage