LaTeX/Picture
The picture 环境允许在 LaTeX 中直接编程图片。一方面,存在相当严格的约束,因为线段的斜率和圆形的半径被限制在一组狭窄的值中。另一方面,LaTeX2e 的 picture 环境带来了 \qbezier
命令,“q” 代表 _二次_。许多常用的曲线,例如圆形、椭圆和 悬链线 可以通过二次贝塞尔曲线得到令人满意的近似,尽管这可能需要一些数学上的努力。如果使用 Java 等编程语言生成 LaTeX 输入文件的 \qbezier
块,picture 环境将变得非常强大。
尽管在 LaTeX 中直接编程图片受到严格限制,并且通常非常繁琐,但仍然有这样做的理由。因此生成的文档在字节方面“很小”,并且没有额外的图形文件需要拖动。
像 pict2e、epic、eepic 或 pstricks 这样的包增强了原始的 picture 环境,并极大地增强了 LaTeX 的图形能力。
一个 picture 环境可以在任何 LaTeX 发行版中使用,无需加载任何外部包。此环境是使用以下两个命令之一创建的
\begin{picture}(x, y)
...
\end{picture}
|
或
\begin{picture}(x, y)(x0, y0)
...
\end{picture}
|
第一对,,影响文档中为图片保留的矩形空间。
可选的第二对,,将任意坐标分配给保留矩形的左下角。
数字 x、y、x0、y0 是 \unitlength
单位的数字(长度),可以随时重置(但不能在 picture 环境中)使用以下命令
\setlength{\unitlength}{1.2cm}
|
\unitlength
的默认值为 1pt.
大多数绘图命令具有以下两种形式之一
\put(x, y){object}
|
或
\multiput(x, y)(dx, dy){n}{object}
|
贝塞尔曲线是一个例外。它们使用以下命令绘制
\qbezier(x1, y1)(x2, y2)(x3, y3)
|
使用 picture 包,除了相对于 \unitlength
的数字之外,还允许使用绝对尺寸(如 15pt)和表达式。
线段使用以下命令绘制
\put(x, y){ \line(x1, y1){length} }
|
\line
命令有两个参数
- 一个方向向量,
- 一个“长度”(有点像:这个参数在垂直线段的情况下是垂直长度,在所有其他情况下是线的水平距离,而不是线段本身的长度)。
方向向量的分量被限制为整数 (−6, −5, ... , 5, 6) 并且它们必须互质(除了 1 之外没有公因子)。下图说明了第一象限中所有 25 种可能的斜率值。长度相对于 \unitlength
。
\setlength{\unitlength}{5cm}
\begin{picture}(1,1)
\put(0,0){\line(0,1){1}}
\put(0,0){\line(1,0){1}}
\put(0,0){\line(1,1){1}}
\put(0,0){\line(1,2){.5}}
\put(0,0){\line(1,3){.3333}}
\put(0,0){\line(1,4){.25}}
\put(0,0){\line(1,5){.2}}
\put(0,0){\line(1,6){.1667}}
\put(0,0){\line(2,1){1}}
\put(0,0){\line(2,3){.6667}}
\put(0,0){\line(2,5){.4}}
\put(0,0){\line(3,1){1}}
\put(0,0){\line(3,2){1}}
\put(0,0){\line(3,4){.75}}
\put(0,0){\line(3,5){.6}}
\put(0,0){\line(4,1){1}}
\put(0,0){\line(4,3){1}}
\put(0,0){\line(4,5){.8}}
\put(0,0){\line(5,1){1}}
\put(0,0){\line(5,2){1}}
\put(0,0){\line(5,3){1}}
\put(0,0){\line(5,4){1}}
\put(0,0){\line(5,6){.8333}}
\put(0,0){\line(6,1){1}}
\put(0,0){\line(6,5){1}}
\end{picture}
|
箭头使用以下命令绘制
\put(x, y){\vector(x1, y1){length}}
|
对于箭头,方向向量的分量比线段的限制更窄,即限制为整数 (−4, −3, ... , 3, 4)。分量也必须互质(除了 1 之外没有公因子)。请注意 \thicklines
命令对指向左上角的两个箭头产生的影响。
\setlength{\unitlength}{0.75mm}
\begin{picture}(60,40)
\put(30,20){\vector(1,0){30}}
\put(30,20){\vector(4,1){20}}
\put(30,20){\vector(3,1){25}}
\put(30,20){\vector(2,1){30}}
\put(30,20){\vector(1,2){10}}
\thicklines
\put(30,20){\vector(-4,1){30}}
\put(30,20){\vector(-1,4){5}}
\thinlines
\put(30,20){\vector(-1,-1){5}}
\put(30,20){\vector(-1,-4){5}}
\end{picture}
|
命令
\put(x, y){\circle{diameter}}
|
绘制一个以 (x, y) 为中心,直径(不是半径)由 diameter 指定的圆形。picture 环境只允许大约 14mm 的直径,即使在这个限制以下,也不是所有直径都是可能的。 \circle*
命令生成圆盘(填充圆形)。与线段一样,可能需要使用其他包,例如 eepic、pstricks 或 tikz。
\setlength{\unitlength}{1mm}
\begin{picture}(60, 40)
\put(20,30){\circle{1}}
\put(20,30){\circle{2}}
\put(20,30){\circle{4}}
\put(20,30){\circle{8}}
\put(20,30){\circle{16}}
\put(20,30){\circle{32}}
\put(40,30){\circle{1}}
\put(40,30){\circle{2}}
\put(40,30){\circle{3}}
\put(40,30){\circle{4}}
\put(40,30){\circle{5}}
\put(40,30){\circle{6}}
\put(40,30){\circle{7}}
\put(40,30){\circle{8}}
\put(40,30){\circle{9}}
\put(40,30){\circle{10}}
\put(40,30){\circle{11}}
\put(40,30){\circle{12}}
\put(40,30){\circle{13}}
\put(40,30){\circle{14}}
\put(15,10){\circle*{1}}
\put(20,10){\circle*{2}}
\put(25,10){\circle*{3}}
\put(30,10){\circle*{4}}
\put(35,10){\circle*{5}}
\end{picture}
|
picture 环境中还有另一种可能性。如果你不害怕进行必要的计算(或者将它们留给程序),则可以将任意圆形和椭圆从二次贝塞尔曲线中拼凑起来。请参阅 _LaTeX2e 中的图形_ 以获取示例和 Java 源文件。
正如本示例所示,可以使用 \put
命令在环境中以通常的方式写入文本和公式
\setlength{\unitlength}{0.8cm}
\begin{picture}(6,5)
\thicklines
\put(1,0.5){\line(2,1){3}}
\put(4,2){\line(-2,1){2}}
\put(2,3){\line(-2,-5){1}}
\put(0.7,0.3){$A$}
\put(4.05,1.9){$B$}
\put(1.7,2.95){$C$}
\put(3.1,2.5){$a$}
\put(1.3,1.7){$b$}
\put(2.5,1.05){$c$}
\put(0.3,4){$F=\sqrt{s(s-a)(s-b)(s-c)}$}
\put(3.5,0.4){$\displaystyle s:=\frac{a+b+c}{2}$}
\end{picture}
|
命令
\multiput(x, y)(dx, dy ){n}{object}
|
有 4 个参数:起点、从一个对象到下一个对象的平移向量、对象的数量以及要绘制的对象。该\linethickness命令适用于水平和垂直线段,但不适用于斜线段或圆形。但是,它确实适用于二次贝塞尔曲线!
\setlength{\unitlength}{2mm}
\begin{picture}(30,20)
\linethickness{0.075mm}
\multiput(0,0)(1,0){26}%
{\line(0,1){20}}
\multiput(0,0)(0,1){21}%
{\line(1,0){25}}
\linethickness{0.15mm}
\multiput(0,0)(5,0){6}%
{\line(0,1){20}}
\multiput(0,0)(0,5){5}%
{\line(1,0){25}}
\linethickness{0.3mm}
\multiput(5,0)(10,0){2}%
{\line(0,1){20}}
\multiput(0,5)(0,10){2}%
{\line(1,0){25}}
\end{picture}
|
命令
\put(x, y){\oval(w, h)}
|
或
\put(x, y){\oval(w, h)[position]}
|
生成一个以(x, y)为中心,宽度为w,高度为h的椭圆。可选的位置参数b, t, l, r分别代表“顶部”,“底部”,“左侧”,“右侧”,可以组合使用,如示例所示。线条粗细可以通过两种命令控制:一方面是\linethickness{''length''}
,另一方面是\thinlines
和\thicklines
。虽然\linethickness{''length''}
仅适用于水平和垂直线(以及二次贝塞尔曲线),但\thinlines
和\thicklines
也适用于斜线段以及圆形和椭圆。
\setlength{\unitlength}{0.75cm}
\begin{picture}(6,4)
\linethickness{0.075mm}
\multiput(0,0)(1,0){7}%
{\line(0,1){4}}
\multiput(0,0)(0,1){5}%
{\line(1,0){6}}
\thicklines
\put(2,3){\oval(3,1.8)}
\thinlines
\put(3,2){\oval(3,1.8)}
\thicklines
\put(2,1){\oval(3,1.8)[tl]}
\put(4,1){\oval(3,1.8)[b]}
\put(4,3){\oval(3,1.8)[r]}
\put(3,1.5){\oval(1.8,0.4)}
\end{picture}
|
图片框可以通过命令进行声明
\newsavebox{name}
|
然后通过以下命令进行定义
\savebox{name}(width,height)[position]{content}
|
最后,可以任意多次使用以下命令进行绘制
\put(x, y){\usebox{name}}
|
可选的位置参数的作用是定义保存框的“锚点”。在示例中,它被设置为“bl”,将锚点放置在保存框的左下角。其他位置指定符为顶部和右侧。
name参数引用一个 LaTeX 存储箱,因此具有命令性质(这解释了当前示例中的反斜杠)。框图可以嵌套:在本示例中,\foldera
在\folderb
的定义中使用。\oval
命令必须使用,因为如果线段长度小于约 3 毫米,\line
命令将无法工作。
\setlength{\unitlength}{0.5mm}
\begin{picture}(120,168)
\newsavebox{\foldera}
\savebox{\foldera}
(40,32)[bl]{% definition
\multiput(0,0)(0,28){2}
{\line(1,0){40}}
\multiput(0,0)(40,0){2}
{\line(0,1){28}}
\put(1,28){\oval(2,2)[tl]}
\put(1,29){\line(1,0){5}}
\put(9,29){\oval(6,6)[tl]}
\put(9,32){\line(1,0){8}}
\put(17,29){\oval(6,6)[tr]}
\put(20,29){\line(1,0){19}}
\put(39,28){\oval(2,2)[tr]}
}
\newsavebox{\folderb}
\savebox{\folderb}
(40,32)[l]{% definition
\put(0,14){\line(1,0){8}}
\put(8,0){\usebox{\foldera}}
}
\put(34,26){\line(0,1){102}}
\put(14,128){\usebox{\foldera}}
\multiput(34,86)(0,-37){3}
{\usebox{\folderb}}
\end{picture}
|
命令
\qbezier(x1, y1)(x, y)(x2, y2)
|
绘制一个二次贝塞尔曲线,其中,表示端点,而表示中间控制点。相应的切线斜率,和,可以从以下方程式中获得
参见LaTeX2e 中的图形,获取一个生成必要\qbezier
命令行的 Java 程序。
\setlength{\unitlength}{0.8cm}
\begin{picture}(6,4)
\linethickness{0.075mm}
\multiput(0,0)(1,0){7}
{\line(0,1){4}}
\multiput(0,0)(0,1){5}
{\line(1,0){6}}
\thicklines
\put(0.5,0.5){\line(1,5){0.5}}
\put(1,3){\line(4,1){2}}
\qbezier(0.5,0.5)(1,3)(3,3.5)
\thinlines
\put(2.5,2){\line(2,-1){3}}
\put(5.5,0.5){\line(-1,5){0.5}}
\linethickness{1mm}
\qbezier(2.5,2)(5.5,0.5)(5,3)
\thinlines
\qbezier(4,2)(4,3)(3,3)
\qbezier(3,3)(2,3)(2,2)
\qbezier(2,2)(2,1)(3,1)
\qbezier(3,1)(4,1)(4,2)
\end{picture}
|
如本例所示,将圆形拆分成 4 个二次贝塞尔曲线并不令人满意。至少需要 8 个。图再次显示了\linethickness
命令对水平或垂直线的影响,以及\thinlines
和\thicklines
命令对斜线段的影响。它还显示了两种命令都影响二次贝塞尔曲线,每个命令覆盖所有之前的命令。
\setlength{\unitlength}{1cm}
\begin{picture}(4.3,3.6)(-2.5,-0.25)
\put(-2,0){\vector(1,0){4.4}}
\put(2.45,-.05){$x$}
\put(0,0){\vector(0,1){3.2}}
\put(0,3.35){\makebox(0,0){$y$}}
\qbezier(0.0,0.0)(1.2384,0.0)
(2.0,2.7622)
\qbezier(0.0,0.0)(-1.2384,0.0)
(-2.0,2.7622)
\linethickness{.075mm}
\multiput(-2,0)(1,0){5}
{\line(0,1){3}}
\multiput(-2,0)(0,1){4}
{\line(1,0){4}}
\linethickness{.2mm}
\put( .3,.12763){\line(1,0){.4}}
\put(.5,-.07237){\line(0,1){.4}}
\put(-.7,.12763){\line(1,0){.4}}
\put(-.5,-.07237){\line(0,1){.4}}
\put(.8,.54308){\line(1,0){.4}}
\put(1,.34308){\line(0,1){.4}}
\put(-1.2,.54308){\line(1,0){.4}}
\put(-1,.34308){\line(0,1){.4}}
\put(1.3,1.35241){\line(1,0){.4}}
\put(1.5,1.15241){\line(0,1){.4}}
\put(-1.7,1.35241){\line(1,0){.4}}
\put(-1.5,1.15241){\line(0,1){.4}}
\put(-2.5,-0.25){\circle*{0.2}}
\end{picture}
|
在本图中,悬链线的每个对称半部分都由一个二次贝塞尔曲线近似。曲线的右侧半部分在点 (2, 2.7622) 处结束,那里的斜率值为 m = 3.6269。再次使用方程式 (*),我们可以计算中间控制点。它们结果是 (1.2384, 0) 和 (-1.2384, 0)。十字表示真实悬链线的点。误差几乎不可察觉,小于百分之一。本例指出了\{picture}
命令可选参数的用法。图片在方便的“数学”坐标中定义,而通过命令
\begin{picture}(4.3,3.6)(-2.5,-0.25)
|
它的左下角(用黑色圆盘标记)被分配坐标 (-2.5, -0.25)。
\setlength{\unitlength}{1cm}
\begin{picture}(6,6)(-3,-3)
\put(-1.5,0){\vector(1,0){3}}
\put(2.7,-0.1){$\chi$}
\put(0,-1.5){\vector(0,1){3}}
\multiput(-2.5,1)(0.4,0){13}
{\line(1,0){0.2}}
\multiput(-2.5,-1)(0.4,0){13}
{\line(1,0){0.2}}
\put(0.2,1.4)
{$\beta=v/c=\tanh\chi$}
\qbezier(0,0)(0.8853,0.8853)
(2,0.9640)
\qbezier(0,0)(-0.8853,-0.8853)
(-2,-0.9640)
\put(-3,-2){\circle*{0.2}}
\end{picture}
|
两个贝塞尔曲线的控制点是根据公式 (*) 计算的。正分支由 , 和 ,。同样,图像在数学上方便的坐标系中定义,左下角被分配了数学坐标 (−3,−2) (黑色圆盘)。
强大的科学绘图软件包 gnuplot 能够直接输出到 LaTeX picture 环境。直接绘制到 LaTeX 通常会方便得多,因为它可以避免处理可能存在问题的 PostScript 文件。以这种方式绘制科学数据(或数学图形)提供了比其他方式(例如 PostScript)更大的控制能力,当然也提供了排版能力。然后可以使用 \include{}
命令将这些图像添加到文档中。
注意,gnuplot 是一款功能强大的软件,拥有大量命令。本说明无法全面讨论 gnuplot。请参阅 [1] 获取教程。