如何改变 \psgrid 的刻度和标签的步长?

如何改变 \psgrid 的刻度和标签的步长?

有时使用大整数作为坐标会很方便。为了控制物理尺寸,我们可以调整unit缩放比例。

不幸的是,改为unit小尺寸会使在导航中非常有用的网格变得非常密集并且不再有用。

我曾尝试减小标签尺寸,但它仍然很密集。

\documentclass[pstricks,border=12pt]{standalone}
\psset{unit=1mm}
\addtopsstyle{gridstyle}
{
    gridlabels=3pt,
}
\begin{document}
\begin{pspicture}[showgrid](50,50)

\end{pspicture}
\end{document}

在此处输入图片描述

理想情况下,我们应该有一个控件来更改网格线和标签的步长。例如,只为 5 的倍数制作和放置网格线和标签。如何做到?可能吗?

笔记

不要建议我使用,\psaxes因为我不想pst-plot在需要上述要求时加载。

答案1

以下是对当前网格功能的一个非常基本的改编(并且具有不是已经过广泛测试)。 它将其扩展为添加gridstep为键值(默认值为 1)。

在此处输入图片描述

\documentclass[pstricks,border=12pt]{standalone}
\makeatletter
\define@key[psset]{pstricks}{gridstep}[1]{\def\psk@gridstep{/gridstep #1 def }}
\psset{gridstep=1}% Default grid step

\addto@pscode{
/StepGrid {  
  newpath 
  /a 4 string def 
  /b ED %               psk@gridlabels in pt
  /c ED %               { \pst@usecolor\psgridlabelcolor }
  /n ED %               psk@griddots
  cvi dup 1 lt { pop 1 } if 
  /s ED %               \psk@subgriddiv
  s div dup 0 eq { pop 1 } if 
  /dy ED s div dup 0 eq { pop 1 } if %  \pst@number\psyunit abs
  /dx ED dy div round dy mul %      \pst@number\psxunit abs
  /y0 ED dx div round dx mul 
  /x0 ED dy div round cvi 
  /y2 ED dx div round cvi 
  /x2 ED dy div round cvi 
  /y1 ED dx div round cvi 
  /x1 ED 
  /h y2 y1 sub 0 gt { 1 } { -1 } ifelse def 
  /w x2 x1 sub 0 gt { 1 } { -1 } ifelse def 
  b 0 gt { 
    /z1 b 4 div CLW 2 div add def
%    /Helvetica findfont b scalefont setfont 
    /b b .95 mul CLW 2 div add def } if 
  systemdict /setstrokeadjust known 
    { true setstrokeadjust /t { } def }
    { /t { transform 0.25 sub round 0.25 add exch 0.25 sub round 0.25 add
       exch itransform } bind def } ifelse 
  gsave n 0 gt { 1 setlinecap [ 0 dy n div ] dy n div 2 div setdash } { 2 setlinecap } ifelse 
  /i x1 def 
  /f y1 dy mul n 0 gt { dy n div 2 div h mul sub } if def 
  /g y2 dy mul n 0 gt { dy n div 2 div h mul add } if def 
  x2 x1 sub w mul 1 add dup 1000 gt { pop 1000 } if 
  { i dx mul dup y0 moveto 
    b 0 gt 
      { gsave c i a cvs dup stringwidth pop 
        /z2 ED w 0 gt {z1} {z1 z2 add neg} ifelse 
    h 0 gt {b neg}{z1} ifelse 
        rmoveto %
        i gridstep mod 0 eq { show } { pop } ifelse %show 
        grestore } if 
    dup t f moveto 
    i gridstep mod 0 eq { g t L stroke } if %g t L stroke 
    /i i w add def 
  } repeat 
  grestore 
  gsave 
  n 0 gt
  % DG/SR modification begin - Nov. 7, 1997 - Patch 1
  %{ 1 setlinecap [ 0 dx n div ] dy n div 2 div setdash }
    { 1 setlinecap [ 0 dx n div ] dx n div 2 div setdash }
  % DG/SR modification end
    { 2 setlinecap } ifelse 
  /i y1 def 
  /f x1 dx mul n 0 gt { dx n div 2 div w mul sub } if def 
  /g x2 dx mul n 0 gt { dx n div 2 div w mul add } if def 
  y2 y1 sub h mul 1 add dup 1000 gt { pop 1000 } if 
  { newpath i dy mul dup x0 exch moveto 
    b 0 gt { gsave c i a cvs dup stringwidth pop 
      /z2 ED 
      w 0 gt {z1 z2 add neg} {z1} ifelse 
      h 0 gt {z1} {b neg} ifelse 
      rmoveto %
      i gridstep mod 0 eq { show } { pop } ifelse %show 
      grestore } if 
    dup f exch t moveto 
    i gridstep mod 0 eq {g exch t L stroke } if %g exch t L stroke 
    /i i h add def 
  } repeat 
  grestore 
} def
}
\def\tx@Grid{\psk@gridstep StepGrid }
\makeatother

\psset{unit=1mm}
\addtopsstyle{gridstyle}
{
    gridlabels=3pt,
    gridstep=5
}


\begin{document}
\begin{pspicture}[showgrid](50,50)

\end{pspicture}
\end{document}

让我们看看这里发生了什么...

原始\psgrid宏(在pstricks.tex) 设置了一组参数并调用\tx@Grid,定义为Grid。为了完整起见,下面是层次结构的视图\psgrid

\def\psgrid{\pst@object{psgrid}}
\def\psgrid@i{\@ifnextchar({\psgrid@ii}{\expandafter\psgrid@iv\pic@coor}}
\def\psgrid@ii(#1){\@ifnextchar({\psgrid@iii(#1)}{\psgrid@iv(0,0)(0,0)(#1)}}
\def\psgrid@iii(#1)(#2){\@ifnextchar({\psgrid@iv(#1)(#2)}{\psgrid@iv(#1)(#1)(#2)}}
\def\psgrid@iv(#1)(#2)(#3){%
  \begin@SpecialObj%
    \pst@getcoor{#1}\pst@tempA%  hv 1.11
    \pst@getcoor{#2}\pst@tempB%  hv 1.11
    \pst@@getcoor{#3}%
    \ifnum\psk@subgriddiv>1\relax
      \addto@pscode{
        gsave
        \tx@setStrokeTransparency
        \psk@subgridwidth SLW 
        \pst@usecolor\pssubgridcolor
        \pst@tempB \pst@coor \pst@tempA                 % hv 1.11
%        \pst@number\psxunit \pst@number\psyunit        % hv 1.11
        \pst@number\psxunit abs \pst@number\psyunit abs % hv 1.11
        \psk@subgriddiv\space \psk@subgriddots\space
        {} 0 
        \psk@gridfont findfont 0 scalefont setfont      % hv 1.16
    \tx@Grid 
    grestore
      }%
    \fi%
    \addto@pscode{
      gsave
      \tx@setStrokeTransparency
      \psk@gridwidth SLW 
      \pst@usecolor\psgridcolor
      \pst@tempB \pst@coor \pst@tempA                 % hv 1.11
      \pst@number\psxunit abs \pst@number\psyunit abs % hv 1.11
%      \pst@number\psxunit \pst@number\psyunit        % hv 1.11
      1 \psk@griddots\space { \pst@usecolor\psgridlabelcolor }
      \psk@gridlabels 
      \psk@gridfont findfont \psk@gridlabels scalefont setfont  % hv 1.16
       \tx@Grid 
      grestore
    }%
  \end@SpecialObj}

注意它实际上调用了\tx@Grid两次。一次用于子网格,一次用于常规网格。从 的定义中\tx@Grid应该清楚,实际网格不是在 TeX 中排版的,而是在 Postscript 中排版的。因此,从pstricks.pro,这里是(Postscript)的定义Grid

/Grid { 
  newpath 
  /a 4 string def 
  /b ED %               psk@gridlabels in pt
  /c ED %               { \pst@usecolor\psgridlabelcolor }
  /n ED %               psk@griddots
  cvi dup 1 lt { pop 1 } if 
  /s ED %               \psk@subgriddiv
  s div dup 0 eq { pop 1 } if 
  /dy ED s div dup 0 eq { pop 1 } if %  \pst@number\psyunit abs
  /dx ED dy div round dy mul %      \pst@number\psxunit abs
  /y0 ED dx div round dx mul 
  /x0 ED dy div round cvi 
  /y2 ED dx div round cvi 
  /x2 ED dy div round cvi 
  /y1 ED dx div round cvi 
  /x1 ED 
  /h y2 y1 sub 0 gt { 1 } { -1 } ifelse def 
  /w x2 x1 sub 0 gt { 1 } { -1 } ifelse def 
  b 0 gt { 
    /z1 b 4 div CLW 2 div add def
%    /Helvetica findfont b scalefont setfont 
    /b b .95 mul CLW 2 div add def } if 
  systemdict /setstrokeadjust known 
    { true setstrokeadjust /t { } def }
    { /t { transform 0.25 sub round 0.25 add exch 0.25 sub round 0.25 add
       exch itransform } bind def } ifelse 
  gsave n 0 gt { 1 setlinecap [ 0 dy n div ] dy n div 2 div setdash } { 2 setlinecap } ifelse 
  /i x1 def 
  /f y1 dy mul n 0 gt { dy n div 2 div h mul sub } if def 
  /g y2 dy mul n 0 gt { dy n div 2 div h mul add } if def 
  x2 x1 sub w mul 1 add dup 1000 gt { pop 1000 } if 
  { i dx mul dup y0 moveto 
    b 0 gt 
      { gsave c i a cvs dup stringwidth pop 
        /z2 ED w 0 gt {z1} {z1 z2 add neg} ifelse 
    h 0 gt {b neg}{z1} ifelse 
        rmoveto show grestore } if 
    dup t f moveto 
    g t L stroke 
    /i i w add def 
  } repeat 
  grestore 
  gsave 
  n 0 gt
  % DG/SR modification begin - Nov. 7, 1997 - Patch 1
  %{ 1 setlinecap [ 0 dx n div ] dy n div 2 div setdash }
    { 1 setlinecap [ 0 dx n div ] dx n div 2 div setdash }
  % DG/SR modification end
    { 2 setlinecap } ifelse 
  /i y1 def 
  /f x1 dx mul n 0 gt { dx n div 2 div w mul sub } if def 
  /g x2 dx mul n 0 gt { dx n div 2 div w mul add } if def 
  y2 y1 sub h mul 1 add dup 1000 gt { pop 1000 } if 
  { newpath i dy mul dup x0 exch moveto 
    b 0 gt { gsave c i a cvs dup stringwidth pop 
      /z2 ED 
      w 0 gt {z1 z2 add neg} {z1} ifelse 
      h 0 gt {z1} {b neg} ifelse 
      rmoveto show grestore } if 
    dup f exch t moveto 
    g exch t L stroke 
    /i i h add def 
  } repeat 
  grestore 
} def

的定义中有两个循环Grid(用块表示{...} repeat)。第一个循环设置垂直网格组件(规则和标签),而第二个循环设置水平网格组件。使用指令设置行L stroke,而使用显示字符串show。原始 MWE 中的定义StepGrid仅仅是关于是否show/stroke网格组件的条件,如果(使用伪代码表示)“当前要显示的项目”MOD gridstep= 0。更详细地说,

%...
rmoveto show grestore } if 
%...

更新Grid

%...
rmoveto %
i gridstep mod 0 eq { show } { pop } ifelse %show 
grestore } if 
%...

在 中StepGrid,其中i是当前迭代,gridstep是使用 设置的网格步长gridstep=<value>。​​标签是来自堆栈的shown 或popped。对于规则,类似地,

%...
g t L stroke 
%...

更新Grid

%...
i gridstep mod 0 eq { g t L stroke } if %g t L stroke 
%...

在 中StepGrid。最终,(和子公司)的正式定义\psgrid保持不变。只有 LaTeX 端的 Postscript 网格调用函数的定义\tx@Grid更新为现在插入网格步骤\psk@gridstep,并调用新StepGrid函数。


对于那些对 Postscript 语言更详细的内容感兴趣的人,可以考虑阅读Postscript 语言参考(特别是第8.2 操作员详细信息,第 524 页起)。

相关内容