有时使用大整数作为坐标会很方便。为了控制物理尺寸,我们可以调整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>
。标签是来自堆栈的show
n 或pop
ped。对于规则,类似地,
%...
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 页起)。