zoukankan      html  css  js  c++  java
  • PostScript学习:另一种缩写为PS的技术

    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
     20 selectfont              % choose the size in points and establish 
                                      % the font as the current one
     72 500 moveto           % position the current point at 
                                      % coordinates 72, 500 (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图案的一个简单例子:

     1 #include <math.h>
     2 #include <stdio.h>
     3 void init(FILE* fp)
     4 {
     5     int w=640,h=480;
     6     fputs("%!PS-Adobe-3.0 EPSF-3.0
    ",fp);
     7     fprintf(fp,"%%%%BoundingBox: 0 0 %d %d
    ",w,h);
     8     fputs("/rgb {setrgbcolor} def
    ",fp);
     9     fputs("/np {newpath} def
    ",fp);
    10     fputs("/cp {closepath} def
    ",fp);
    11     fputs("/mt {moveto} def
    ",fp);
    12     fputs("/ll {lineto} def
    ",fp);
    13     fputs("/st {stroke} def
    ",fp);
    14     fputs("/lw {setlinewidth} def
    ",fp);
    15     fputs("/line {np mt ll st} def
    ",fp);
    16 }
    17 void close(FILE* fp)
    18 {
    19     fputs("showpage
    %%EOF",fp);
    20     fclose(fp);
    21 }
    22 void line(FILE* fp,float x[],float y[],int n)
    23 {
    24     fprintf(fp,"0 0 1 rgb
    np
    %.3f %.3f mt
    ",x[0],y[0]);
    25     for(int i=1;i<n;i++){
    26         fprintf(fp,"%.3f %.3f ll
    ",x[i],y[i]);
    27     }
    28     fprintf(fp,"st
    ");
    29 }
    30 #define N 628
    31 int main()
    32 {
    33 
    34     FILE* fp=fopen("main.ps","wb");
    35     init(fp);
    36     //
    37     float x[N],y[N],t;
    38     for(int i=0;i<N;i++){
    39         t=-3.14+i/100.0;
    40         x[i]=200*sin(3*t)*cos(t)+320;
    41         y[i]=200*sin(3*t)*sin(t)+240;
    42     }
    43     line(fp,x,y,N);
    44     //
    45     close(fp);
    46     return 0;
    47 }
    View Code

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

      

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

      

    3.复杂一点的例子

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

      1 #include <math.h>
      2 #include <time.h>
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #define Random rand()%255
      6 #define Length(x) (sizeof(x)/sizeof(x[0])/3)
      7 const float PI=3.1415926536;
      8 typedef float vector3[3];
      9 //三维点数组结构
     10 typedef struct {
     11     int length;
     12     float *x, *y, *z;
     13 }PointArray ;
     14 //
     15 //三维点初始化
     16 PointArray Array3d(int n)
     17 {
     18     PointArray r;
     19     r.length = n;
     20     r.x = (float*)malloc(n*sizeof(float));
     21     r.y = (float*)malloc(n*sizeof(float));
     22     r.z = (float*)malloc(n*sizeof(float));
     23     for (int i = 0; i < n; i++) {
     24         r.x[i] = r.y[i] = r.z[i] = 0.0;
     25     }
     26     return r;
     27 }
     28 //三维点通过数组赋值
     29 PointArray eval(float *a, int n)
     30 {
     31     PointArray r;
     32     r.length = n;
     33     r.x = (float*)malloc(n*sizeof(float));
     34     r.y = (float*)malloc(n*sizeof(float));
     35     r.z = (float*)malloc(n*sizeof(float));
     36     for (int i = 0; i < n; i++) {
     37         r.x[i] = a[3*i];
     38         r.y[i] = a[3*i + 1];
     39         r.z[i] = a[3*i + 2];
     40     }
     41     return r;
     42 }
     43 //输出三维点数组的数据
     44 void print(PointArray r)
     45 {
     46     for (int i = 0; i < r.length; i++) {
     47         printf("%f %f %f
    ", r.x[i], r.y[i], r.z[i]);
     48     }
     49 }
     50 //
     51 void fileprint(FILE* fp,PointArray r)
     52 {
     53     for (int i = 0; i < r.length; i++) {
     54         fprintf(fp,"%f %f ", r.x[i], r.y[i], r.z[i]);
     55     }
     56     fprintf(fp," quad
    ");
     57 }
     58 //
     59 //对三维点进行旋转
     60 void Rotate(PointArray pa, vector3 vec,float t)
     61 {
     62     float x,y,z,a,b,c;
     63     float base=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);
     64     a=vec[0]/base,b=vec[1]/base,c=vec[2]/base;
     65     for (int i = 0; i < pa.length; i++) {
     66         x=pa.x[i],y=pa.y[i],z=pa.z[i];
     67         //
     68         pa.x[i]=(cos(t)+(1-cos(t))*a*a)*x+
     69                 ((1-cos(t))*a*b-sin(t)*c)*y+
     70                 ((1-cos(t))*a*c+sin(t)*b)*z;
     71         //
     72         pa.y[i]=((1-cos(t))*b*a+sin(t)*c)*x+
     73                 (cos(t)+(1-cos(t))*b*b)*y+
     74                 ((1-cos(t))*b*c-sin(t)*a)*z;
     75         //
     76         pa.z[i]=((1-cos(t))*c*a-sin(t)*b)*x+
     77                 ((1-cos(t))*c*b+sin(t)*a)*y+
     78                 (cos(t)+(1-cos(t))*c*c)*z;
     79     }
     80 }
     81 //
     82 void RotateX(PointArray pa,float t)
     83 {
     84     float x,y,z;
     85 
     86     for (int i = 0; i < pa.length; i++) {
     87         x=pa.x[i],y=pa.y[i],z=pa.z[i];
     88 
     89         pa.x[i]=x;
     90         //
     91         pa.y[i]=y*cos(t)-z*sin(t);
     92         //
     93         pa.z[i]=y*sin(t)+z*cos(t);
     94     }
     95 }
     96 //
     97 void RotateY(PointArray pa,float t)
     98 {
     99     float x,y,z;
    100     for (int i = 0; i < pa.length; i++) {
    101         x=pa.x[i],y=pa.y[i],z=pa.z[i];
    102         //
    103         pa.x[i]=z*sin(t)+x*cos(t);
    104         pa.y[i]=y;
    105         pa.z[i]=z*cos(t)-x*sin(t);
    106     }
    107 }
    108 //
    109 void RotateZ(PointArray pa,float t)
    110 {
    111     float x,y,z;
    112     for (int i = 0; i < pa.length; i++) {
    113         x=pa.x[i],y=pa.y[i],z=pa.z[i];
    114         pa.x[i]=x*cos(t)-y*sin(t);
    115         pa.y[i]=x*sin(t)+y*cos(t);
    116         pa.z[i]=z;
    117     }
    118 }
    119 //透视投影
    120 void Perspective(PointArray pa,float ez,float n,float f)
    121 {
    122     float x,y,z;
    123     for (int i = 0; i < pa.length; i++) {
    124         x=pa.x[i],y=pa.y[i],z=pa.z[i];
    125         pa.x[i]=(ez-z)/(n-f)*x;
    126         pa.y[i]=(ez-z)/(n-f)*y;
    127         pa.z[i]=z;
    128     }
    129 }
    130 //
    131 static float yrot=45;
    132 //
    133 inline float fun(float x,float y)
    134 {
    135     //Matlab Peaks Function
    136     float z=3*(1-x)*(1-x)*exp(-x*x - (y+1)*(y+1))
    137             - 10*(x/5 - x*x*x - y*y*y*y*y)*exp(-x*x-y*y)
    138             - 1.0/3*exp(-(x+1)*(x+1) - y*y);
    139     return z*10;
    140 }
    141 //
    142 void display()
    143 {
    144     float a[12];
    145     PointArray ptsa,ptsb;
    146     float d=0.1,factor=50;
    147     float x,y,z1,z2,z3,z4;
    148     FILE* fp=fopen("main.ps","wb");
    149     fprintf(fp,"%%!PS-Adobe-3.0 EPSF-3.0
    %%%%BoundingBox: -250 -250 250 250
    /rgb {setrgbcolor} def
    /np {newpath} def
    /cp {closepath} def
    /mt {moveto} def
    /rmt {rmoveto} def
    /ll {lineto} def
    /rl {rlineto} def
    /st {stroke} def
    /lw {setlinewidth} def
    /line {np mt ll st} def
    /quad {np mt ll ll ll cp st} def
    0 0 1 rgb
    0.2 lw
    ");
    150     for(x=-3; x<3; x+=d) {
    151         for(y=-3; y<3; y+=d) {
    152             z1=fun(x,y);
    153             a[0]=x*factor,a[1]=z1,a[2]=y*factor;
    154             z2=fun(x+d,y);
    155             a[3]=(x+d)*factor,a[4]=z2,a[5]=y*factor;
    156             z3=fun(x+d,y+d);
    157             a[6]=(x+d)*factor,a[7]=z3,a[8]=(y+d)*factor;
    158             z4=fun(x,y+d);
    159             a[9]=x*factor,a[10]=z4,a[11]=(y+d)*factor;
    160             //
    161             ptsa=eval(a,Length(a));
    162             RotateY(ptsa,yrot);
    163             RotateX(ptsa,15*2*PI/360);
    164             //ptsb=RotateZ(ptsb,6);
    165             fileprint(fp,ptsa);
    166         }
    167     }
    168     fprintf(fp,"
    showpage
    %%%%EOF
    ");
    169     fclose(fp);
    170     yrot+=0.1;
    171 }
    172 int main()
    173 {
    174     display();
    175 }
    View Code

      

    4.结束语

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

      

  • 相关阅读:
    禁止微信内置浏览器调整字体大小
    常用EXE文件反编译工具【转】
    C++发送HTTP请求---亲测可行(转)
    Cesium简介 [转]
    WebGL可视化地球和地图引擎:Cesium.js
    HTML5 canvas图形库 RGraph【转】
    [GitHub开源]基于HTML5实现的轻量级Google Earth三维地图引擎,带你畅游世界 【转】
    OpenGL实现多层绘制(Layered Rendering) [转]
    深度剖析OpenGL ES中的多线程和多窗口渲染技术
    OOP几大原则【转】
  • 原文地址:https://www.cnblogs.com/wurui1994/p/6290969.html
Copyright © 2011-2022 走看看