4

I want to make the regions bounded as eyes transparent and the other regions opaque with solid fill. Unfortunately, psellipse (as well as pscircle) does not move the current point to its starting point before stroking as already questioned by me here (click).

As a result, the rotated ellipses make the moveto operation need extra transformation before and after invoking it. See the following code for more detailed information.

\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}

enter image description here

My question is can you simplify the transformation steps, for example,

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

to be a reusable operator such that I can save more keystrokes?

My effort

\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}

But it does not seem to be simpler significantly.

2
  • Bonus question: Is there any advantage of letting pscircle and psellipse behave as their current implementation in which they do not move the current point to their starting point before stroking? In my opinion, this implementation just adds unnecessary complexity, what do you think? Apr 23, 2014 at 6:56
  • Another bonus question: Does the rotation PostScript operator (I defined above) exist already in PSTricks? Apr 23, 2014 at 8:44

2 Answers 2

6
\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}

enter image description here

3
  • Apparently it does not work for pscircle. Apr 23, 2014 at 15:28
  • 1
    @IamwhoIsayIam Right, for \pscircle you must use a different redefinition of arc, e.g. \code { /Arc /arc load def /arc { 0 0 moveto 1 0 rmoveto Arc } def }\psellipse(3,4)(3,4)\code{ /arc { 5 copy pop pop 3 -1 roll add exch moveto Arc } def }\pscircle(1.5,4.5){1}\pscircle(4.5,4.5){1}.
    – Christoph
    Apr 24, 2014 at 11:02
  • 1
    Your code here(click) does not produce the same result as the output shown there. I have updated my TeXLive many times since you uploaded the code. Apr 26, 2014 at 12:35
4
+300

Postscript itself knows a lot of transformation operators, see e.g. Chapter 8 of the PostScript Language Reference, the "red book", which is a very comprehensive reference for available Postscript operators.

These transformations are usually applied to the current matrix, like e.g. in the case of 30 rotate, which is what \rotate{30} does inside of \pscustom. The transformations can also be stored in a matrix with 30 matrix rotate and later applied with transform or other operators to values on the stack:

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

So, you can define a transformation operator /TRF, which does all your transformations:

\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}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .