[pstricks] elliptic arc: proposition of code

Denis Girou Denis.Girou at idris.fr
Thu May 15 17:45:28 CEST 2003


>>>>> "Vincent.Guirardel" == vin gui <vin.gui at laposte.net> writes:

    Vincent.Guirardel> Therefore, I looked into the code of \psarc, and 
    Vincent.Guirardel> I adapted it to the case of an elliptic arc.

  Thanks for you work and contribution.  Nevertheless, in the process of
udating and repackaging the documentation, to help me, Timothy sent me
recently some of his old archive files, that I did not know before, in their
state of 1994. Inside them, there were elliptic arcs with arrows. I will add
this code in the "pstricks.tex" next patch, in the general update that I plan
for this summer, with the new documentation and some old waiting patches.
But you can use this code independently in the meantime.

  P.S. * You could see that the results are very closed to yours.
Nevertheless, testing it a little, I found at least one case with a wrong
result ( \psellipticarc[arrowscale=5]{<->}(3,0.5){0}{180} ). I will look at it
one day.
       * Otherwise, don't expect too much: there are very few new things like
this one! Mainly a new extended version of the \PSTtoEPS macro.

\documentclass{article}

\usepackage{pstricks}

\makeatletter

% Code from "pstricks.tex" 0.94 beta (TvZ)
\def\psellipticarcn{\def\pst at par{}\pst at object{psellipticarcn}}
\def\psellipticarcn at i{\let\if at psarcn\iftrue\psellipticarc at ii}
\def\psellipticarc{\def\pst at par{}\pst at object{psellipticarc}}
\def\psellipticarc at i{\let\if at psarcn\iffalse\psellipticarc at ii}
\let\if at psarcn\iffalse
\def\psellipticarc at ii{\pst at getarrows\psellipticarc at iii}
\def\psellipticarc at iii(#1){%
  \@ifnextchar({\psellipticarc at iv(#1)}{\psellipticarc at iv(0,0)(#1)}}
\def\psellipticarc at iv(#1)(#2)#3#4{%
  \begin at OpenObj
    \pst at getcoor{#1}\pst at tempa
    \pst at getcoor{#2}\pst at tempb
    \pst at getangle{#3}\pst at tempc
    \pst at getangle{#4}\pst at tempd
    \addto at pscode{\psellipticarc at definearg \psellipticarc at draw}%
    \showpointsfalse
  \end at OpenObj}
\def\psellipticarc at definearg{%
  \pst at tempa /y ED /x ED  % Origin
  \pst at tempb              % radii. Now adjust:
  \ifdim\psk at dimen\p@=\z@\else
    \psk at dimen CLW mul dup 3 1 roll
    sub 3 1 roll sub exch
  \fi
  /ry ED /rx ED
  /angleA
    \pst at tempc dup \psk at arcsepA \tx at ArcAdjust
    \if at psarcn sub \else add \fi
  def
  /angleB
    \pst at tempd dup \psk at arcsepB \tx at ArcAdjust
    \if at psarcn add \else sub \fi
  def
  \ifshowpoints\psellipticarc at showpoints\fi
  \ifx\psk at arrowA\@empty
    \ifnum\psk at liftpen=2
      angleA cos rx mul x add
      angleA sin ry mul y add
      moveto
    \fi
  \fi}
\def\psellipticarc at draw{%
  0 0 1
  angleA
  \ifx\psk at arrowA\@empty\else
    { ArrowA CP }
    { \if at psarcn sub \else add \fi }
    \tx at EllipticArcArrow
  \fi
  angleB
  \ifx\psk at arrowB\@empty\else
    { ArrowB }
    { \if at psarcn add \else sub \fi }
    \tx at EllipticArcArrow
  \fi
  /mtrx CM def
  x y T
  rx ry scale
  \if at psarcn arcn \else arc \fi
  mtrx setmatrix}
\def\psellipticarc at showpoints{%
  gsave
    /mtrx CM def
    x y T
    rx ry scale
    0 0 moveto
    0 0 1 \pst at tempc \pst at tempd
    \ifcase\psarc at type arc \or arcn \fi
    closepath
    mtrx setmatrix
    CLW 2 div SLW
    [ \psk at dash\space ] 0 setdash stroke
  grestore }
\pst at def{ArcAdjust}<%
  57.2958 mul exch
  dup sin rx mul dup mul exch
  cos ry mul dup mul
  add sqrt div>
\pst at def{EllipticArcArrow}<%
  /d ED      % add/sub
  /b ED      % arrow procedure
  /a1 ED     % angle
  gsave
    newpath
    0 -1000 moveto
    clip                  % Set clippath far from arrow.
    newpath
    0 1 0 0 b             % Draw arrow to determine length.
  grestore
  % Length of arrow is on top of stack. Next 3 numbers are junk.
  a1 exch \tx at ArcAdjust   % Angle by which to adjust for arrow length.
  a1 exch d /a2 ED        % Angular position of base of arrow.
  pop pop pop
  a2 cos rx mul x add
  a2 sin ry mul y add
  a1 cos rx mul x add
  a1 sin ry mul y add
  % Now arrow tip coor and base coor are on stack.
  b pop pop pop pop       % Draw arrow, and discard coordinates.
  a2 dup CLW 8 div \tx at ArcAdjust neg d>  % Adjust angle to give overlap.

\makeatother

\pagestyle{empty}

\begin{document}

\psset{subgriddiv=0}

\begin{pspicture}(5,5)\psgrid
  \psellipticarc[linewidth=0.1]{<->}(2,3)(1.5,1){0}{180}
  \psellipticarc[linecolor=red](4,2)(0.5,1.5){30}{220}
\end{pspicture}
\hfill
\begin{pspicture}(5,5)\psgrid
  \psellipticarcn[linewidth=0.1,arrows=<->](2,4)(1.5,1){0}{180}
  \psellipticarcn[showpoints=true,linecolor=red](4,2)(0.5,1.5){220}{140}
\end{pspicture}

\vspace{1cm}
\begin{pspicture}(6,4)\psgrid
  \psellipticarc[arrows=<->,arrowsize=10pt,linewidth=2pt,linecolor=blue]
                (3,2)(3,1){40}{300}
\end{pspicture}

\end{document}


D.G.



More information about the PSTricks mailing list