Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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.

share|improve this question
    
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? –  Who is crazy first Apr 23 at 6:56
    
Another bonus question: Does the rotation PostScript operator (I defined above) exist already in PSTricks? –  Who is crazy first Apr 23 at 8:44

2 Answers 2

up vote 4 down vote accepted
\documentclass[pstricks,border=12pt]{standalone}

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

\pscustom[fillstyle=eofill,fillcolor=red,linewidth=3pt]{%
  \code { /Arc /arc load def
          /arc { 0 0 moveto 1 0 rmoveto Arc } def } 
    % 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

share|improve this answer
    
Apparently it does not work for pscircle. –  Who is crazy first Apr 23 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 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. –  Who is crazy first Apr 26 at 12:35

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}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.