1.前言

  PostScript是一种编程语言,直译为"后处理脚本"[相对印刷过程而言],学名为页面描述语言。更为详细的解释见维基百科,以及其翻译版百度百科

  值得一提的是,PostScript于1985年由Adobe推出,而Adobe的软件Photoshop 1.0版本于1990发布,两者的缩写均为PS。虽然就知名度而言,PhotoShop更为人所熟知,但是在Adobe的发家史中,PostScript扮演着非常重要的作用,时至今日PostScript的衍生技术PDF已经是一项ISO标准。

  老实说,关于PostScript的基础知识,大家看维基百科的介绍以及附录的四本书就够了,四本书分别是:PostScript语言参考PostScript语言教程与手册PostScript程序设计数学图表:几何与PostScript手册 。本文只是介绍PostScript的简单绘图知识。

  大多数人开始接触PostScript大概是因为LaTeX,参考如何在论文中画出漂亮的插图?中 地铁风 的回答。LaTeX中常用的矢量图格式是EPS[Encapsulated PostScript],不过对PDF格式的支持应该是最好的。大多数与LaTeX相关的绘图与渲染都是基于PostScript技术的,如PSTricksTikZ /PGFMetaPost以及AsymptoteTexample.net上有大量关于Tikz的例子Asymptote官网也有大量 asy的例子

2.简单例子

  在学习之前,你需要两个软件:GhostScriptSumatraPDF。GhostScript是PostScript的一个开源解释器;SumatraPDF是一个文档阅读器,默认支持PDF,结合GhostScript可以支持PostScript。

  HelloWorld的例子,保存到文本文件HelloWorld.ps, 用SumatraPDF打开:

 %!PS
/Courier % name the desired font
selectfont % choose the size in points and establish
% the font as the current one
moveto % position the current point at
% coordinates , (the origin is at the
% lower-left corner of the page)
(Hello world!) show % stroke the text in parentheses
showpage % print all on the page

  下面给出C语言生成PostScript图案的一个简单例子:

 #include <math.h>
#include <stdio.h>
void init(FILE* fp)
{
int w=,h=;
fputs("%!PS-Adobe-3.0 EPSF-3.0\n",fp);
fprintf(fp,"%%%%BoundingBox: 0 0 %d %d\n",w,h);
fputs("/rgb {setrgbcolor} def\n",fp);
fputs("/np {newpath} def\n",fp);
fputs("/cp {closepath} def\n",fp);
fputs("/mt {moveto} def\n",fp);
fputs("/ll {lineto} def\n",fp);
fputs("/st {stroke} def\n",fp);
fputs("/lw {setlinewidth} def\n",fp);
fputs("/line {np mt ll st} def\n",fp);
}
void close(FILE* fp)
{
fputs("showpage\n%%EOF",fp);
fclose(fp);
}
void line(FILE* fp,float x[],float y[],int n)
{
fprintf(fp,"0 0 1 rgb\nnp\n%.3f %.3f mt\n",x[],y[]);
for(int i=;i<n;i++){
fprintf(fp,"%.3f %.3f ll\n",x[i],y[i]);
}
fprintf(fp,"st\n");
}
#define N 628
int main()
{ FILE* fp=fopen("main.ps","wb");
init(fp);
//
float x[N],y[N],t;
for(int i=;i<N;i++){
t=-3.14+i/100.0;
x[i]=*sin(*t)*cos(t)+;
y[i]=*sin(*t)*sin(t)+;
}
line(fp,x,y,N);
//
close(fp);
return ;
}

  如图所示,更多的例子可以看之前提到的四本书,三维绘图请看第四本数学图表:几何与PostScript手册

  

   另一个简单例子,可以作为一个练习,更多例子见我的GitHub:LearnPostScript

  

3.复杂一点的例子

  这个例子需要一点三维旋转矩阵的知识,代码仅作演示:

 #include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#define Random rand()%255
#define Length(x) (sizeof(x)/sizeof(x[0])/3)
const float PI=3.1415926536;
typedef float vector3[];
//三维点数组结构
typedef struct {
int length;
float *x, *y, *z;
}PointArray ;
//
//三维点初始化
PointArray Array3d(int n)
{
PointArray r;
r.length = n;
r.x = (float*)malloc(n*sizeof(float));
r.y = (float*)malloc(n*sizeof(float));
r.z = (float*)malloc(n*sizeof(float));
for (int i = ; i < n; i++) {
r.x[i] = r.y[i] = r.z[i] = 0.0;
}
return r;
}
//三维点通过数组赋值
PointArray eval(float *a, int n)
{
PointArray r;
r.length = n;
r.x = (float*)malloc(n*sizeof(float));
r.y = (float*)malloc(n*sizeof(float));
r.z = (float*)malloc(n*sizeof(float));
for (int i = ; i < n; i++) {
r.x[i] = a[*i];
r.y[i] = a[*i + ];
r.z[i] = a[*i + ];
}
return r;
}
//输出三维点数组的数据
void print(PointArray r)
{
for (int i = ; i < r.length; i++) {
printf("%f %f %f\n", r.x[i], r.y[i], r.z[i]);
}
}
//
void fileprint(FILE* fp,PointArray r)
{
for (int i = ; i < r.length; i++) {
fprintf(fp,"%f %f ", r.x[i], r.y[i], r.z[i]);
}
fprintf(fp," quad\n");
}
//
//对三维点进行旋转
void Rotate(PointArray pa, vector3 vec,float t)
{
float x,y,z,a,b,c;
float base=sqrt(vec[]*vec[]+vec[]*vec[]+vec[]*vec[]);
a=vec[]/base,b=vec[]/base,c=vec[]/base;
for (int i = ; i < pa.length; i++) {
x=pa.x[i],y=pa.y[i],z=pa.z[i];
//
pa.x[i]=(cos(t)+(-cos(t))*a*a)*x+
((-cos(t))*a*b-sin(t)*c)*y+
((-cos(t))*a*c+sin(t)*b)*z;
//
pa.y[i]=((-cos(t))*b*a+sin(t)*c)*x+
(cos(t)+(-cos(t))*b*b)*y+
((-cos(t))*b*c-sin(t)*a)*z;
//
pa.z[i]=((-cos(t))*c*a-sin(t)*b)*x+
((-cos(t))*c*b+sin(t)*a)*y+
(cos(t)+(-cos(t))*c*c)*z;
}
}
//
void RotateX(PointArray pa,float t)
{
float x,y,z; for (int i = ; i < pa.length; i++) {
x=pa.x[i],y=pa.y[i],z=pa.z[i]; pa.x[i]=x;
//
pa.y[i]=y*cos(t)-z*sin(t);
//
pa.z[i]=y*sin(t)+z*cos(t);
}
}
//
void RotateY(PointArray pa,float t)
{
float x,y,z;
for (int i = ; i < pa.length; i++) {
x=pa.x[i],y=pa.y[i],z=pa.z[i];
//
pa.x[i]=z*sin(t)+x*cos(t);
pa.y[i]=y;
pa.z[i]=z*cos(t)-x*sin(t);
}
}
//
void RotateZ(PointArray pa,float t)
{
float x,y,z;
for (int i = ; i < pa.length; i++) {
x=pa.x[i],y=pa.y[i],z=pa.z[i];
pa.x[i]=x*cos(t)-y*sin(t);
pa.y[i]=x*sin(t)+y*cos(t);
pa.z[i]=z;
}
}
//透视投影
void Perspective(PointArray pa,float ez,float n,float f)
{
float x,y,z;
for (int i = ; i < pa.length; i++) {
x=pa.x[i],y=pa.y[i],z=pa.z[i];
pa.x[i]=(ez-z)/(n-f)*x;
pa.y[i]=(ez-z)/(n-f)*y;
pa.z[i]=z;
}
}
//
static float yrot=;
//
inline float fun(float x,float y)
{
//Matlab Peaks Function
float z=*(-x)*(-x)*exp(-x*x - (y+)*(y+))
- *(x/ - x*x*x - y*y*y*y*y)*exp(-x*x-y*y)
- 1.0/*exp(-(x+)*(x+) - y*y);
return z*;
}
//
void display()
{
float a[];
PointArray ptsa,ptsb;
float d=0.1,factor=;
float x,y,z1,z2,z3,z4;
FILE* fp=fopen("main.ps","wb");
fprintf(fp,"%%!PS-Adobe-3.0 EPSF-3.0\n%%%%BoundingBox: -250 -250 250 250\n/rgb {setrgbcolor} def\n/np {newpath} def\n/cp {closepath} def\n/mt {moveto} def\n/rmt {rmoveto} def\n/ll {lineto} def\n/rl {rlineto} def\n/st {stroke} def\n/lw {setlinewidth} def\n/line {np mt ll st} def\n/quad {np mt ll ll ll cp st} def\n0 0 1 rgb\n0.2 lw\n");
for(x=-; x<; x+=d) {
for(y=-; y<; y+=d) {
z1=fun(x,y);
a[]=x*factor,a[]=z1,a[]=y*factor;
z2=fun(x+d,y);
a[]=(x+d)*factor,a[]=z2,a[]=y*factor;
z3=fun(x+d,y+d);
a[]=(x+d)*factor,a[]=z3,a[]=(y+d)*factor;
z4=fun(x,y+d);
a[]=x*factor,a[]=z4,a[]=(y+d)*factor;
//
ptsa=eval(a,Length(a));
RotateY(ptsa,yrot);
RotateX(ptsa,**PI/);
//ptsb=RotateZ(ptsb,6);
fileprint(fp,ptsa);
}
}
fprintf(fp,"\nshowpage\n%%%%EOF\n");
fclose(fp);
yrot+=0.1;
}
int main()
{
display();
}

  

4.结束语

  虽然越来越多的新技术涌现出来,但是它们都不是凭空产生的。PostScript作为一项古老的技术,对于文档的排版和印刷而言,依然是值得学习的。

  

PostScript学习:另一种缩写为PS的技术的更多相关文章

  1. linux命令学习笔记(41):ps命令

    Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前 那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程 ...

  2. WebGL three.js学习笔记 6种类型的纹理介绍及应用

    WebGL three.js学习笔记 6种类型的纹理介绍及应用 本文所使用到的demo演示: 高光贴图Demo演示 反光效果Demo演示(因为是加载的模型,所以速度会慢) (一)普通纹理 计算机图形学 ...

  3. 《BI那点儿事》浅析十三种常用的数据挖掘的技术

    一.前沿 数据挖掘就是从大量的.不完全的.有噪声的.模糊的.随机的数据中,提取隐含在其中的.人们事先不知道的但又是潜在有用的信息和知识的过程.数据挖掘的任务是从数据集中发现模式,可以发现的模式有很多种 ...

  4. 浅析十三种常用的数据挖掘的技术&五个免费开源的数据挖掘软件

    一.前 沿 数据挖掘就是从大量的.不完全的.有噪声的.模糊的.随机的数据中,提取隐含在其中的.人们事先不知道的但又是潜在有用的信息和知识的过程.数据挖掘的任务是从数据集中发现模式,可以发现的模式有很多 ...

  5. 一文读懂四种常见的XML解析技术

    之前的文章我们讲解了<XML系列教程之Schema技术_上海尚学堂java培训技术干货><XML的概念.特点与作用.XML申明_上海Java培训技术干货>,大家可以点击回顾一下 ...

  6. OpenVZ安装指南,一种操作系统级别的虚拟化技术

    鼎鼎大名的 OpenVZ 谁不知道?在主机行业被使用(滥用)很多年,依然在茁壮发展.作为一种操作系统级别的虚拟化技术,运行 OpenVZ 没有硬性的硬件要求.OpenVZ 能够创建被称为容器(cont ...

  7. C# 桌面软件开发-深入学习[2]- AY-C#人爱学不学-aaronyang技术分享

    原文:C# 桌面软件开发-深入学习[2]- AY-C#人爱学不学-aaronyang技术分享 1 : C# Assembly.GetEntryAssembly().GetName().Version. ...

  8. C# 桌面软件开发-深入学习 [1]- AY-C#人爱学不学-aaronyang技术分享

    原文:C# 桌面软件开发-深入学习 [1]- AY-C#人爱学不学-aaronyang技术分享 曾经我做office,不想依赖别人dll,就使用了 Type.GetTypeFromProgID 可以根 ...

  9. shell学习五十天----查看进程ps命令

    进程列表 列出进程中最重要的命令便是进程状态命令:ps. ps命令是进程状态(Process Status)的缩写.ps命令用来列出系统中当前执行的那些进程.ps命令列出的是当前那些进程的快照,就是执 ...

随机推荐

  1. solr中重跑索引

    solr与.net系列课程(八)solr中重跑索引的注意事项   solr与.net系列课程(八)solr中重跑索引的注意事项 我们如果在项目中使用solr,那肯定就是把数据库中的数据跑进solr服务 ...

  2. leetcode第36题--Sudoku Solver

    题目: Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated b ...

  3. C# 图片存入SQL Server数据库

    OpenFileDialog openfiledialog1 = new OpenFileDialog(); if (openfiledialog1.ShowDialog() == DialogRes ...

  4. 【工作笔记二】ASP.NET MVC框架下使用MVVM模式

    ASP.NET MVC框架下使用MVVM模式 原文:http://www.cnblogs.com/n-pei/archive/2011/07/21/2113022.html 对于asp.net mvc ...

  5. NodeJS热部署工具 — supervisor

    NodeJS热部署工具 — supervisor 大家都在开发nodejs应用时遇到过这样的情况,修改nodejs应用中的程序文件后必须重启nodejs才能重新加载应用代码.这是因为nodejs加载过 ...

  6. EF 关系描述

    网络上常常看到有ef 1对1 1对多等关系的描述,按照我的理解,其根本就是为了呈现出一个视图,我最近设计了一个ef关系,请大家看一看. 需求描述 在gps车辆信息管理中,有个开户需求,其根本就是三种关 ...

  7. 玩转python之测试一个对象是否是类字符串

    提到类型测试,我首先想到python中“鸭子类型”的特点,所谓鸭子类型,即如果它走路像鸭子,叫声也像鸭子, 那么对于我们的应用而言,就可以认为它是鸭子了!这一切都是为了功能复用. 我们总是需要测试一个 ...

  8. C语言基础复习总结

    C语言基础复习总结 大一学的C++,不过后来一直没用,大多还给老师了,最近看传智李明杰老师的ios课程的C语言入门部分,用了一周,每晚上看大概两小时左右,效果真是顶一学期的课,也许是因为有开发经验吧, ...

  9. Bootstrap相关优质项目推荐

    Bootstrap 编码规范by @mdo Bootstrap 编码规范:编写灵活.稳定.高质量的 HTML 和 CSS 代码的规范. jQuery API 中文手册 根据最新的 jQuery 1.1 ...

  10. ODP.NET Managed正式推出

    NET Oracle Developer的福音——ODP.NET Managed正式推出 在.NET平台下开发Oracle应用的小伙伴们肯定都知道一方面做Oracle开发和实施相比SqlServer要 ...