本书介绍了如何在PostScript中绘制图形, 当然也必然涉及一些几何.
GS>newpath
GS>144 144 moveto
GS>288 288 lineto
GS>stroke
GS>newpath. 这就像拿起笔准备画画.moveto. 这就像将笔置于路径的起点.lineto为路径添加线条. 这就像在纸上移动笔.stroke绘制它, 或者说使其变得可见.以下命令序列可以绘制一个边长为英寸的正方形.
newpath
144 144 moveto
288 144 lineto
288 288 lineto
144 288 lineto
144 144 lineto
stroke当然PoscScript中存在许多不同的方式来绘制这个正方形.
newpath
144 144 moveto
144 0 rlineto
0 144 rlineto
-144 0 rlineto
closepath
strokerlineto是lineto的相对 (relative) 位置版本. closepath通过回到上一个应用moveto的位置以封闭路径.
newpath
144 144 moveto
144 0 rlineto
0 144 rlineto
-144 0 rlineto
closepath
fillfill和stroke有着不同的效果.
0.5 setgray
newpath
144 144 moveto
144 0 rlineto
0 144 rlineto
-144 0 rlineto
closepath
fill1 0 0 setrgbcolor
newpath
144 144 moveto
144 0 rlineto
0 144 rlineto
-144 0 rlineto
closepath
fill对于生活在北美的人而言, 既然默认的页面尺寸为, 与单位英寸打交道通常来得更加容易. 以下命令可以将基本的长度单位转换为英寸.
72 72 scale当进行缩放的时候, 需要注意默认的线宽是一个单位. 如果什么都不做, 那么现在线宽就是英寸了.
0.01389 setlinewidth你可以使用0.01389 setlinewidth将其改回来, 因为约等于.
1 2 translate你可以使用translate进行平移, 比如这里将坐标原点右移了个单位, 上移了个单位.
72 72 scale
4.25 5.5 translate如此原点就移动了到了页面的中心.
还有一种简单的坐标变换, 即旋转rotate.
144 144 translate
30 rotate
newpath
0 0 moveto
144 0 lineto
144 144 lineto
0 144 lineto
0 0 lineto
stroke旋转总是围绕当前原点进行, 注意到PostScript的角度单位是角度制而不是弧度制.
PostScript是一种完备的编程语言.
GS>3 4 add
GS<1>你可能想问<1>是什么意思, 它指的是栈的深度.
GS>3 4 add
GS<1>=
7
GS>=移除栈顶的元素, 并将其输出. ==与=类似, 但是输出在某种意义上更加美观, 所以你总是应该使用==.
GS>3 4 add
GS<1>stack
7
GS<1>stack输出整个栈, 类似的命令还有pstack. pstack之于stack就像==之于=.
GS>3 3 mul
GS<1>4 4 mul
GS<2>add
GS<1>sqrt
GS<1>=
5.0
GS>linecap | 样式 |
|---|---|
0 | |
1 | |
2 |
默认情况下linecap为0, 你可以通过setlinecap来设置这个参数.
9 setlinewidth
% linejoin = 0 by default
newpath
0 0 moveto
0 72 lineto
72 0 lineto
strokelinejoin是一个与linecap有点联系的参数, 它控制line join的样式, 其值同样仅可能为0, 1, 2, 并使用setlinejoin修改.
newpath
144 144 moveto
144 0 rlineto
0 144 rlineto
-144 0 rlineto
closepath
gsave
1 0 0 setrgbcolor
fill
grestore
0 setgray
strokenewpath
moveto
lineto
rmoveto
rlineto
closepath
stroke
filltranslate
scale
rotatesetlinewidth
setrgbcolor
setgray
setlinejoin
setlinecapgsave
grestore
showpage如果是一个点而是一个向量, 那么是一个点, 其是满足的点. 我们称是平移得到的. 若给定实数以及点和, 我们可以构造一个点. 若, 那么该点在线段上. 当时, 该点即的中点. 我们可以将写成的形式.
/s 1 def
newpath
0 0 moveto
s 0 rlineto
0 s rlineto
s neg 0 rlineto
closepath
strokePostScript在内部(至少是隐式地)处理三种坐标系统. 第一种是物理坐标系. 物理坐标系的基本单位是像素. 第二种是页面坐标系. 其原点位于页面的左下角, 单位长度为一个Adobe点, 等于英寸. 页面可以被视为一种理想化了的物理设备. 第三种是用户坐标系, 这是用户绘制图像时使用的坐标系. 最初页面坐标系和用户坐标系是相同的, 但是特定的操作, 例如scale, translate, rotate, 可以改变其间的关系.
仿射变换可以看成是一个线性变换加上一个平移分量, 其具有特定的性质: 直线经过变换仍然是直线, 平行线经常变换仍然是平行的.
确定一个仿射坐标变换所需要的数据被存储在一个长度为六的数组[a b c d e f]里, 其被称为matrix. 命令matrix将数组[1 0 0 1 0 0]置于栈上, 此即恒等变换. 若此时再使用currentmatrix命令, 则会将当前变换置于该数组之中.
GS>matrix currentmatrix ==
[1.33333337 0.0 0.0 1.33333337 0.0 0.0]
GS>[注记: 至少若是在Windows系统之中调整缩放比例, 结果是会改变的, 当然这也是相当合理的.] defaultmatrix和currentmatrix有些类似, 但是顾名思义, 其将从页面到物理坐标系的变换置于栈顶的数组之中. 如果什么都没动, 这两个命令的效果显然是一样的. [译注: currentmatrix当然就是从用户到物理坐标系的变换了.]现在我们想要解方程以用和表达和. 我们考虑将其写成的形式. 假定可逆, 我们得到也就是说, 这个逆变换同样是仿射变换. 实际上, PostScript拥有一个计算逆变换的命令, 即invertmatrix. 另外, concatmatrix可以用来计算变换的复合. 它们的用法如下.
M matrix invertmatrix这可以将M的逆变换置于栈上.A B matrix concatmatrix这可以将A和B的复合置于栈上. [译注: 先施行变换A, 后施行变换B.]显然, 我们可以藉由这些操作来计算从用户到页面坐标系的变换.
/user-to-page-matrix {
matrix currentmatrix
matrix defaultmatrix
matrix invertmatrix
matrix concatmatrix
} def当前变换是, 默认变换是, 逆就是, 当前变换和{默认变换的逆}复合一下就得到了.注记: 本节考虑的不是三维的仿射变换的情形, 而是仿射坐标系的诸多事宜.
实际上, 我们可以在三维的情况下用线性变换表示二维的仿射变换.可以被重写为这样之后, 仿射变换的复合就变成纯粹的矩阵乘法了.
现在我们可以检视如何以矩阵表示先前的几种简单变换.
a b scalex rotatea b translate当然了, 最一般的变换如下.[a b c d e f] concat以上这些变换的效果都是给当前矩阵左乘其变换矩阵.72 72 scale
4 5 translate
30 rotate之后, 从用户到页面坐标系的变换矩阵应该是什么?在Racket写了点简单的程序算一算.
> (matrix-print
(matrix* (make-scale 72 72)
(make-translation 4 5)
(make-rotation (/ pi 6))))
62.353829072479584 -35.99999999999999 288
35.99999999999999 62.353829072479584 360
0 0 1 当然, 我的这个采用的是通行的左乘而不是PostScript的右乘, 所以结果应该是其转置.GS>/user-to-page-matrix {
matrix currentmatrix
matrix defaultmatrix
matrix invertmatrix
matrix concatmatrix
} def
GS>72 72 scale
GS>4 5 translate
GS>30 rotate
GS>user-to-page-matrix
GS<1>==
[62.3538284 36.0 -36.0 62.3538284 288.0 360.0]
GS>我们再在PostScript的REPL里算一遍, 的确如此.