该图形环境允许直接在 LaTeX 中编程图形。一方面,存在相当严格的约束,因为线段的斜率和圆的半径仅限于一小部分数值。另一方面,LaTeX2e 的图形环境引入了 \qbezier 命令,其中“q”表示二次的意思。许多常用的曲线,如圆、椭圆和悬链线,可以通过二次贝塞尔曲线得到令人满意的近似,尽管这可能需要一些数学计算。如果像 Java 这样的编程语言被用来生成 LaTeX 输入文件中的 \qbezier 块,那么图形环境将变得非常强大。

尽管直接在 LaTeX 中编程图形受到严格限制,并且通常相当繁琐,但仍然有这样做的理由。这样生成的文档在字节数上相对“较小”,而且不需要额外拖带其他图形文件。

像 pict2e、epic、eepic 或 pstricks 这样的包扩展了原始的图形环境,大大增强了 LaTeX 的图形功能。

基本命令
在任何 LaTeX 发行版中都可以使用图形环境,而无需加载任何外部包。这个环境可以通过以下两个命令之一来创建:

\begin{picture}(x, y)
...
\end{picture}

或者

\begin{picture}(x, y)(x0, y0)
...
\end{picture}

第一个括号对 (x, y) 用于在文档中预留矩形空间用于图形。

可选的第二对括号 (x0, y0) 为预留矩形的左下角指定任意坐标。

其中,x、y、x0、y0 是以 \unitlength 单位的数值(长度),\unitlength 可以在任何时候重置(但不能在图形环境中进行重置),例如:

\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 包时,允许使用绝对尺寸(如 15pt)和表达式,除了相对于 \unitlength 的数值外。

线段
线段通过以下命令绘制:

\put(x, y){ \line(x1, y1){length} }

\line 命令有两个参数:

  1. 一个方向向量,

  2. 一个“长度”(这个参数是垂直线段的垂直长度,其他情况下则是线段的水平距离,而非线段的实际长度)。

方向向量的分量限制为整数(−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) 为中心,直径为指定值的圆(不是半径)。图形环境只允许直径最大约为 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}

在图形环境中,还有另一种可能性。如果不介意进行必要的计算(或将它们交给程序),可以通过二次贝塞尔曲线拼接出任意的圆形和椭圆。有关示例和 Java 源文件,请参见《LaTeX2e 图形》一书。

文本和公式
如以下示例所示,文本和公式可以通过 \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 和 \linethickness
命令

\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 的椭圆。可选的 position 参数(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}}

可选的 position 参数定义了保存框的“锚点”。在示例中,锚点设置为 "bl",这将锚点放置在保存框的左下角。其他位置指定符包括顶部(top)和右侧(right)。

name 参数指的是一个 LaTeX 存储箱,因此是一个命令性质的对象(这解释了示例中反斜杠的存在)。图片框可以嵌套:在此示例中,\foldera 在定义 \folderb 时被使用。由于 \line 命令在线段长度小于约 3 毫米时无法工作,因此使用了 \oval 命令。

\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)

绘制一个二次贝塞尔曲线,其中 P 1 = ( x 1 , y 1 ) P_1 = (x_1, y_1) P 2 = ( x 2 , y 2 ) P_2 = (x_2, y_2) 是端点, S = ( x , y ) S = (x, y) 是中间控制点。相应的切线斜率 m 1 m_1 m 2 m_2 可以通过以下方程求得:

{ x = m 2 x 2 m 1 x 1 ( y 2 y 1 ) m 2 m 1 y = y i + m i ( x x i ) ; ( i = 1 , 2  gives same solution ) \begin{cases} x = \frac{m_2 x_2 - m_1 x_1 - (y_2 - y_1)}{m_2 - m_1} \\ y = y_i + m_i (x - x_i) ; \quad (i = 1, 2 \text{ gives same solution}) \end{cases}

以下示例演示了使用二次贝塞尔曲线来绘制曲线:

\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}

如示例所示,将一个圆分成四个二次贝塞尔曲线是不够的,至少需要 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}

在此图中,悬链线的每个对称半部分 y = cosh x 1 y = \cosh x - 1 都通过二次贝塞尔曲线进行了逼近。右半部分的曲线终止于点 (2, 2.7622),其斜率为 m = 3.6269 m = 3.6269 。通过公式(*),我们可以计算出中间控制点,它们分别是 (1.2384, 0) 和 (-1.2384, 0)。交叉点表示实际悬链线的点,误差几乎不可察觉,小于 1%。

绘制图形
以下是绘制图形的示例:

\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}

该图显示了通过公式(*)计算得出的两个贝塞尔曲线的控制点。正分支由 P 1 = ( 0 , 0 ) P_1 = (0,0) , m 1 = 1 m_1 = 1 P 2 = ( 2 , tanh 2 ) P_2 = (2, \tanh 2) , m 2 = 1 / cosh 2 2 m_2 = 1 / \cosh^2 2 确定。此图也使用了方便的数学坐标,左下角坐标为 (-3, -2)。

图片环境与 gnuplot
强大的科学绘图包 gnuplot 可以直接输出到 LaTeX 图片环境中。直接绘制到 LaTeX 通常比处理潜在麻烦的后处理文件要方便得多。这种方式绘制科学数据(或数学图形)提供了比其他方法(如 postscript)更大的控制权和排版能力。这些图形可以通过 \include{} 命令添加到文档中。

注意:gnuplot 是一个功能强大的软件,拥有大量的命令,关于 gnuplot 的完整讨论超出了此笔记的范围。请参阅 [1] 以获取教程。


Last modified: Wednesday, 23 April 2025, 9:50 AM