我们能否简化下面的转换步骤以节省更多击键?

我们能否简化下面的转换步骤以节省更多击键?

我想让眼睛所在的区域透明,其他区域不透明,并填充实心。不幸的是,psellipse(以及pscircle)在描边之前不会将当前点移动到其起点,我已经提出过疑问此处(点击)

因此,旋转的椭圆使得该moveto操作在调用之前和之后需要进行额外的变换。有关更多详细信息,请参阅以下代码。

\documentclass[pstricks,border=12pt]{standalone}

\begin{document}
\begin{pspicture}[showgrid=false,dimen=m](6,8)
\pscustom[fillstyle=eofill,fillcolor=red,linewidth=3pt]
{
    % head
    \psellipse(3,4)(3,4)
    % left eye
    \translate(1.5,4.5)
    \rotate{30}
    \moveto(1,0)
    \rotate{-30}
    \translate(-1.5,-4.5)
    \psellipse[rot=30](1.5,4.5)(1,1.5)
    % right eye
    \translate(4.5,4.5)
    \rotate{-30}
    \moveto(1,0)
    \rotate{30}
    \translate(-4.5,-4.5)
    \psellipse[rot=-30](4.5,4.5)(1,1.5)
}
\end{pspicture}
\end{document}

在此处输入图片描述

我的问题是,你能否简化转换步骤,例如,

    \translate(4.5,4.5)
    \rotate{-30}
    \moveto(1,0)
    \rotate{30}
    \translate(-4.5,-4.5)

成为一个可重复使用的操作符,以便我可以节省更多的击键?

我的努力

\documentclass[pstricks,border=12pt]{standalone}

\pstVerb
{   
    /PRE {dup cos exch sin} bind def
    /XXX {neg 3 -1 roll mul 3 1 roll mul add} bind def
    /YYY {exch 3 -1 roll mul 3 1 roll mul add} bind def
    /ROT {PRE 4 copy XXX 5 1 roll YYY} bind def
}

\begin{document}
\begin{pspicture}[showgrid=false,dimen=m](6,8)
\pscustom[fillstyle=eofill,fillcolor=red,linewidth=3pt]
{
    % head
    \psellipse(3,4)(3,4)
    % left eye
    \moveto(!1 0 30 ROT 4.5 add exch 1.5 add exch)
    \psellipse[rot=30](1.5,4.5)(1,1.5)
    % right eye
    \moveto(!1 0 -30 ROT 4.5 add exch 4.5 add exch)
    \psellipse[rot=-30](4.5,4.5)(1,1.5)
}
\end{pspicture}
\end{document}

但看上去并没有简单多少。

答案1

\documentclass[pstricks,border=12pt]{standalone}

\begin{document}
\begin{pspicture}[showgrid,dimen=m](6,8)

\pscustom[fillstyle=eofill,fillcolor=red,linewidth=3pt]{%
    % head
    \psellipse(3,4)(3,4)
    % eyes
    \psellipse[rot=30](1.5,4.5)(1,1.5)
    \psellipse[rot=-30](4.5,4.5)(1,1.5)
}
\end{pspicture}
\end{document}

在此处输入图片描述

答案2

Postscript 本身知道很多转换运算符,例如PostScript 语言参考第 8 章,“红皮书”,这是可用的 Postscript 运算符的非常全面的参考。

这些变换通常应用于当前矩阵,例如 的情况30 rotate,这就是\rotate{30}内部所做的\pscustom。变换也可以存储在矩阵中30 matrix rotate,然后使用transform或其他运算符应用于堆栈上的值:

GS>1 0 30 matrix rotate transform == ==
0.5
0.866025388

因此,你可以定义一个转换运算符/TRF,它可以完成所有的转换:

\documentclass[pstricks,border=12pt]{standalone}

\pstVerb {
  % X Y DX DY ANGLE on the stack
  /TRF {
    matrix rotate 3 1 roll matrix translate matrix concatmatrix transform
  } def
}

\begin{document}
\begin{pspicture}[showgrid=false,dimen=m](6,8)
\pscustom[fillstyle=eofill,fillcolor=red,linewidth=3pt]
{
    % head
    \psellipse(3,4)(3,4)
    % left eye
    \moveto(!1 0 1.5 4.5 30 TRF)
    \psellipse[rot=30](1.5,4.5)(1,1.5)
    % right eye
    \moveto(!1 0 4.5 4.5 -30 TRF)
    \psellipse[rot=-30](4.5,4.5)(1,1.5)
}
\end{pspicture}
\end{document}

相关内容