简单的二维图形绘制 - PostScript

3

能否告诉我一种简单的方法来画 graph(2+x, sin(x), cos(x+3)/3.....) 的PS格式图形?

例如,我想绘制 f(x) = 2+x,使用以下值:

Table of values: 
Value of X = -5 | -4 | -3 | -2 | -1 | -0 | 1 .....
Value of Y = -3 | -2 | -1 |  0 |  1 |  2 | 3 .....

如何绘制这个图表?使用画线命令、画多边形或使用曲线命令?您认为哪种方案最好?

我的回答在这里展示了一种绘制可微函数分段贝塞尔插值的方法。 - luser droog
你考虑过使用Metapost或Asymptote为你生成Postscript代码吗? - Charles Staats
1个回答

3

有几种不同的方法可以实现这个功能。如果您有一组坐标需要绘制,您可以将它们放入一个数组中,在迭代数组时绘制所有的点。

/XValues [ -5 -4 -3 -2 -1 0 1 ] def  % eg. XValues 0 get ==> -5
/YValues [ -3 -2 -1  0  1 2 3 ] def  %     YValues 0 get ==> -3

XValues 0 get YValues 0 get % X[0] Y[0]
moveto                      % move to first point
1 1 XValues length 1 sub {  % i    push integer i = 1 .. length(XValues)-1 on each iteration
    XValues                 % i XVal    push X array
    1 index                 % i XVal i  copy i from stack
    get                     % i x       get ith X value from array
    YValues                 % i x YVal
    2 index                 % i x YVal i  i is 1 position deeper now, so 2 index instead of 1
    get                     % i x y
    lineto                  % i    line to next point
    pop                     %      discard index variable
} for

当然,在Postscript中,默认情况下原点位于左下角,每英寸72个点。因此,这些值(-5、-4、-2等)甚至不会可见。所以你通常想要从将图形绘制的中心开始进行翻译。

/Center { 300 400 } def  % roughly the middle of US letter-size paper
Center translate

接下来,您需要缩放坐标系以使图形特征可见。缩放因子=期望大小/现有大小。

您可以扫描数据集以查找现有大小。

/Xmin 1000000 def  % really high
/Xmax -1000000 def % really low
XValues {                   % x    forall pushes each X value
    dup Xmin lt {           % x    lower than Xmin?
        dup /Xmin exch def  % x    set Xmin
    } if                    % x
    dup Xmax gt {           % x    higher than Xmax?
        /Xmax exch def      %      set Xmax
    }{                      % x    else (lower than Xmax)
        pop                 %      discard X value
    } ifelse
} forall
/Datasize Xmax Xmin sub def   % X size is (Xmax-Xmin)

6 72 mul DataSize div  % scalefactor                6*72/(Xmax-Xmin)
dup                    % scalefactor scalefactor    use same scaling for x and y
scale

但是,当你绘制线条时会遇到一个问题。你画的线条宽度也取决于当前坐标空间,所以如果你将空间放大了很多倍,你的线条将变得不可控制地宽。你可以在描述路径之后但在调用笔画之前将空间缩回到正常状态,或者在缩放同时修复线宽。
由于我们知道增加的线宽量(与缩放因子相同),我们可以反向调整linewidth图形参数。
1                       %                   push 1 for division
6 72 mul DataSize div   % 1 scalefactor     6*72/(Xmax-Xmin)
dup dup                 % 1 scalefactor scalefactor scalefactor
scale                   % 1 scalefactor
div                     % 1/scalefactor
currentlinewidth mul setlinewidth  %        adjust line width

现在,由于这是一个函数的图表,我们实际上不需要值表。我们可以通过评估函数来实时计算值。
/func { 3 add cos 3 div } def  % f(x) = cos(3+x)/3    define function y=f(x)

/Xini -5 def              % named loop control parameters
/Xfin 1 def
/Xstep 1 def
Xini dup dup func moveto  % moveto first point
Xstep add Xstep Xfin {    % x
    dup                   % x x
    func                  % x f(x)
    lineto                % line to next point
} for
stroke

最后,如果你能够对这个函数求导(创建一个函数,在每个点计算原始函数的斜率),那么你可以使用我在 TeX.SE 上的答案来绘制由许多曲线段组成的图形,而不是直线。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接