PostScript语言教程(六、图形变换)
6.1、坐标系变换
POSTSCRIPT图形操作是在一个坐标系中,这个坐标系被称为用户坐标系或用户空间,该坐标系独立于任何物理设备。POSTSCRIPT在用户空间中进行绘制,并将结果传输到特定的打印机设备(设备空间)中。
在程序中,通常使用默认的坐标系。在这个空间中,原点是在页面的左下角,量度是1/72英寸长度。
然而,用户空间是可塑性的,他的坐标系可能是在位置,方向,大小变化后的。
6.1.1、用户空间的平移
translation是从一个地方运动到另一个地方。这个运动是原点的运动。例如:
100 200 translate
将会把原点右移100个单位,上移200个单位,随后的操作都是根据这个新的原点进行测量。
下面的程序将说明这个转化效果。
/Times-Roman findfont 30 scalefont setfont /square %一个填充的方块
{
newpath
0 0 moveto
90 0 lineto %定义正方形的路径
90 90 lineto
0 90 lineto
closepath fill %进行填充
6 92 moveto %文本显示
(A Box) show } def square %绘制一个方块
200 250 translate %将原点移动x + 200 y + 250
square %绘制第二个方块
200 250 translate %原点再次移动x + 200 y + 250
square %绘制第三个方块
showpage
这个程序定义了一个方块,然后通过原点变换获得了三个方块。
注:原点的变换是相对于当前原点而不是起始原点。
6.1.2、用户空间的旋转
rotate是从栈中取出一个数然后进行逆时针旋转坐标轴。(旋转的单位是度)
/Times-Roman findfont 30 scalefont setfont /square
{
newpath
0 0 moveto
90 0 lineto
90 90 lineto
0 90 lineto
closepath fill
6 92 moveto
(A Box) show } def square
300 150 translate
60 rotate %逆时针旋转90度
square
300 150 translate
60 rotate %逆时针旋转60度
square
showpage
在此,我们只是改变了坐标系的位置,方块实际上的定义从未改变。
6.1.3、用户空间的缩放
scale运算符允许更改坐标单元的大小,这个运算符获取两个参数,一个x缩放,一个y缩放,例:
3 3 scale
执行此操作,将会将x,y放大为原来的三倍。
在此通过小方块例子
/Times-Roman findfont 30 scalefont setfont /square
{
newpath
0 0 moveto
90 0 lineto
90 90 lineto
0 90 lineto
closepath fill
6 92 moveto
(A Box) show } def square
300 150 translate
1.5 1.5 scale %扩大1.5倍
square
300 150 translate
0.5 2 scale %x 缩小到原来的1/2 y变为原来的2倍
square
showpage
6.2、绘图状态
目前为止,我们工作在当前的绘图状态中,构成当前环境包括(路径,点,灰度值,字体,线宽,用户坐标系)。
6.2.1、保存当前的图形状态
有时候我们需要保存当前的图形状态,以便以后可以随时得到他。
例如:如果想要打印一个填充的图形,我们就必须要构建一个适合的路径,然后填充他。不幸的是fill操作符将会清除当前的路径。所以在执行fill前应先保存当前的路径,在fill之后再恢复保存的路径就可以了。
保存和恢复图形状态的操作符是gsave和grestore。
gsave操作符将当前图形状态的副本保存在图形状态的堆栈中。这个堆栈最多可保存32个图形状态(包括当前图形状态)。
grestore操作符恢复最新的gsave图形状态。包括当时的所有特征,路径,灰度,线宽,用户坐标系。
下面是一个五角星来演示这些操作符的使用
/starside
{
72 0 lineto
currentpoint translate
-144 rotate } def /star %stack: x y
{
moveto
currentpoint translate
4 {starside} repeat
closepath
gsave
.5 setgray fill
grestore
stroke }def 200 200 star
showpage
在这个程序,定义了两个步骤
starside绘制了组成该星星的一条直线。
star根据坐标点填充星星。
添加一条水平线
72 0 lineto %星星的边长为72
将坐标系原点移动到水平线的末尾
currentpoint translate
再讲坐标系顺时针旋转144度
-144 rotate
repeat:这个运算符需要两个参数
一个数字(例子中的4)
一组用括号括起来的运算(starside)
意思为执行指定运算4次
4 {starside} repeat
然后跟上结束符,完成路径绘制
closepath %画笔回到起点
进行图形的填充(填充操作会清空路径信息所以要提前保存,不保存的话1.路径被清空,不会显示变沿线以及中间的五边形,灰度清空所有线的灰度值会一样,看不出轮廓)
gsave
.5 setgray fill %将灰度值设置为0.5进行填充
grestore %恢复保存的默认状态
以200 200的坐标点绘制当前图形,然后提交当前页面到纸张。
200 200 star
showpage
6.3、曲线
通常图形图像不仅仅是由直线构成,在postscript中可以使用运算符来定义任何期望的曲线。
6.3.1、圆弧
在本节中我们将讨论圆弧曲线arc
arc操作符是将圆弧添加到当前路径,他需要五个参数
弧的曲率中心的x,y坐标、曲率半径、以及从正x轴逆时针测量的弧的起始和结束角。
例:中心在100 150 半径为36 从逆时针45到90
100 150 36 45 90 arc
arcn运算符和arc类似,只是在方向上相反,为顺时针
100 150 36 45 90 arcn
第一条线是画了一个圆弧
第二条线是先将图龟移动到300 365 然后以40度起点到60度起点画弧
newpath
300 400 54 40 140 arc stroke
newpath
300 365 moveto
340 345 54 40 140 arc stroke
showpage
6.3.2、椭圆
圆可以认为是一个0到360的弧线
椭圆可以认为是将坐标系非均匀缩放之后的圆
/doACircle
{
0 0 54 0 360 arc stroke } def
/doAnEllipse
{
1 .75 scale %横坐标不变,纵坐标变为原来的0.75
doACircle %绘制圆
stroke } def
300 500 translate doACircle
4 {0 -72 translate %不断缩放坐标系
doAnEllipse} repeat
showpage
6.3.3、圆角
相交线经常通过圆角进行连接,postscript的arcto运算符提供了一种方法。
操作员除了当前点意外需要两个点和一个半径
可以这样理解:以起始点开始,第一个点为线段连线,再将第一个点和第二个点连线,组成相交的一个角,以r为半径的圆相切与这两个直线,最后形成的弧度即为圆角。
例:列出了两个圆角,分别为两条线段的角度,相同,第一条线段的长度相同,第二条线段的长度不同,可以看到,两个弧度的大小是一样的。
/DrawAnX
{
3 3 rmoveto
-6 -6 rlineto
0 6 rmoveto
6 -6 rlineto
stroke
}def 50 50 moveto DrawAnX
50 150 moveto DrawAnX
150 150 moveto DrawAnX
50 50 moveto
50 150 150 150 36 arcto
4 {pop} repeat 200 50 moveto DrawAnX
200 150 moveto DrawAnX
400 150 moveto DrawAnX 200 50 moveto
200 150 400 150 36 arcto
4 {pop} repeat stroke
showpage
注意:在圆角绘制完成后,当前的图龟停留在最后一次相切的圆角的末端。以第一个圆弧为例,
起始点 50 50
圆规确定的点是 50 150 150 150 36
此时在arcto运算符执行后有一组数据保留在了堆栈中,分别是圆角的起始点和终止点。
起始点 50,150 - 36 = 114
终止点 50 + 36 = 86,150
这四个点对于我们来说是没有必要的,所以,我们要将其从堆栈中删除。
例:打印一个logo
% ------------ Define Procedures -------------
/Helvetica-Bold findfont 27 scalefont setfont /fourpops %四次出栈
{
4 {pop} repeat } def /background %绘制背景
{
0 18 moveto
0 72 108 72 18 arcto fourpops
108 72 108 0 18 arcto fourpops
108 0 0 0 18 arcto fourpops
0 0 0 72 18 arcto fourpops
fill } def /moon
{
.6 setgray %绘制logo中的小圆
81 45 18 0 360 arc fill
} def /omaha %绘制字体
{
1 setgray
0 -1 moveto
1 2 scale %更改坐标系比例
(OMAHA) stringwidth pop %获取OMAHA字符串的宽度
108 exch sub 2 div %108 - (字符宽度 / 2)作为x的偏移量
0 rmoveto %将图龟移动到该点进行字符串显示(目的为让字符串显示在logo的正中央)
(OMAHA) show } def 255 465 translate background
moon
omaha
showpage
6.4、总结
repeat
重复执行程序n次
rotate
逆时针方向旋转坐标系
scale
x,y方向缩放坐标系
translate
将坐标原点进行移动
grestore
恢复上一次保存的图形状态
gsave
保存当前图形状态
arc x y r ang1 ang2 -> —
逆时针添加圆弧
arcn x y r ang1 ang2 -> —
顺时针添加圆弧
arcto x1 y1 x2 y2 r -> xt1 yt1 xt2 yt2
绘制圆弧,参数五个,两点一个半径,返回值为圆弧的起始点和终止点
currentpoint — -> x y
返回当前点的坐标
PostScript语言教程(六、图形变换)的更多相关文章
- WebGL简易教程(五):图形变换(模型、视图、投影变换)
[toc] 1. 概述 通过之前的教程,对WebGL中可编程渲染管线的流程有了一定的认识.但是只有前面的知识还不足以绘制真正的三维场景,可以发现之前我们绘制的点.三角形的坐标都是[-1,1]之间,Z值 ...
- [译]Vulkan教程(13)图形管道基础之Shader模块
[译]Vulkan教程(13)图形管道基础之Shader模块 Shader modules Unlike earlier APIs, shader code in Vulkan has to be s ...
- Swift语言教程中文文档
Swift语言教程中文文档 Swift语言教程(一)基础数据类型 Swift语言教程(二)基础数据类型 Swift语言教程(三)集合类型 Swift语言教程(四) 集合类型 Swift语言教程(五)控 ...
- 转:spring boot log4j2配置(使用log4j2.yml文件)---YAML 语言教程
转:spring boot log4j2配置(使用log4j2.yml文件) - CSDN博客http://blog.csdn.net/ClementAD/article/details/514988 ...
- webpack4 系列教程(六): 处理SCSS
这节课讲解webpack4中处理scss.只需要在处理css的配置上增加编译scss的 LOADER 即可.了解更多处理css的内容 >>> >>> 本节课源码 & ...
- YAML 语言教程(转载)
用YAML语言读取配置是最快的,之前的suricata中用yaml读取了配置,并且在代码运行期间,对配置进行了维护,所以抽点时间,来了解一下YAML语言编程,下文虽然对YAML语言和JAVAScrip ...
- 《Real Time Rendering》第四章 图形变换
图形变换是一个将例如点.向量或者颜色等实体进行某种转换的操作.对于计算机图形学的先驱者,掌握图形变换是极为重要的.有了他们,你就可以对象.光源以及摄像机进行定位,变形以及动画添加.你也可以确认所有的计 ...
- WebGL简易教程(六):第一个三维示例(使用模型视图投影变换)
目录 1. 概述 2. 示例:绘制多个三角形 2.1. Triangle_MVPMatrix.html 2.2. Triangle_MVPMatrix.js 2.2.1. 数据加入Z值 2.2.2. ...
- [译]Vulkan教程(12)图形管道基础之入门
[译]Vulkan教程(12)图形管道基础之入门 Introduction 入门 Over the course of the next few chapters we'll be setting u ...
- [转]Oracle 11g 基于CentOS7静默安装教程(无图形界面,远程安装) --有部份地方有问题
Oracle 11g 基于CentOS7静默安装教程(无图形界面,远程安装) [转载]原文地址:http://canonind.blog.51cto.com/8239025/1883066 一.安装前 ...
随机推荐
- robocopy超快小文件复制工具
robocopy i:\. d:\oldd /e /mir /mt:120 /xd "$recycle.bing"/xd "system volume informat ...
- clear
BFC虽然可以达到外部背景由内部内容撑开的效果,但是存在副作用 所以由clear将affter受浮动效果解除,来解决以上问题
- php 常用助手函数
1 <?php 2 3 if (!function_exists('bcSum')) { 4 function bcSum($scale, ...$args): string 5 { 6 $re ...
- web服务器应答状态代码(status)及其含义
Web服务器响应浏览器或其他客户程序的请求时,其应答一般由以下几个部分组成:一个状态行,几个应答 头,一个空行,内容文档.下面是一个最简单的应答 : 状态行包含HTTP版本.状态代码.与状态代码对 ...
- Go--解析yaml文件
yaml 文件是目前最常用的配置文件,使用go语言编写代码和工具时,也会用到yaml文件,将服务配置及中间件等信息定义到yaml文件中,后续可根据实际场景来选用. //先下载外部包 go get -u ...
- python+ffmpeg,批量转换手机中的m3u8文件
前段时间,有朋友找我帮忙,自述其手机上使用UC浏览器,缓存的电影有近千个,手机存储不够了,想把这些电影转存到PC机上,并且将其转换为Mp4文件.小事情,安排! 一.分析情况,确定方案. 首先连接手机, ...
- python 中的lamda 表达式
#1. print(list(filter(lambda x: x%2,range(10)))) #[1, 3, 5, 7, 9]# 非lamda表示def odd(x): return x ...
- java使用apache-commons-lang3生成随机字符串(可自定义规则)
在日常开发中,我们经常会遇到生成随机字符串的需求.可能是大小写字母+数字,也可能是其他各种字符.作为一个常用功能,我们完全没必要自己实现,有很多优质的类库已经做的很完善了.本文介绍的就是apache- ...
- python中items()和iteritems()的区别
items()函数,将一个字典以dict_items的形式返回,因为字典是无序的,所以返回的列表也是无序的: 1 a ={'a':1,'b':2,'c':3,'d':4} 2 print(a.item ...
- The Semantics of Constructors——2.4 成员初始化列表
2.4 成员初始化列表(Member Initialization List) 当你写下一个constructor时,就有机会设定class members的初值.要不是经由member initia ...