[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