# [pstricks] tangential vector

Martin Chicoine martin.chicoine at umontreal.ca
Thu Apr 9 19:20:24 CEST 2009

> -----Message d'origine-----
> De : pstricks-bounces at tug.org [mailto:pstricks-bounces at tug.org] De la
> part de Doris Wagner
> Envoyé : 8 avril 2009 11:46
> À : Graphics PSTricks with
> Objet : [pstricks] tangential vector
>
> hi list,
>
> I have a graph which shows a trajectory (e.g. polynomial) of a
> physical object and I want to draw the tangent vector. the problem
> with \psplotTangent is that it goes in two directions from one point
> of the graph. is there a possibility to get only half of it?
>
> d

Here is a version that extends from -#2 to #3, with #1 being the x point and
#4 being the function:

\psplotTangent{#1}{#2}{#3}{#4}

-------------------------------

\documentclass{article}

\makeatletter
\def\psplotTangent at i#1#2#3#4{%
\begin at OpenObj%
%  \let\pst at linetype\pst at arrowtype%
\ifx\psk at Derive\@empty\ifPst at algebraic\psset{Derive=NOT at EMPTY}\fi\fi%%dr
0606
gsave % save current state
/F at pstplot \ifPst at algebraic (#4) tx at addDict begin AlgParser end cvx
\else { #4 } \fi def % define function
\ifx\psk at Derive\@empty\else
\ifx\psk at Derive\@NOTEMPTY\else%%dr 0606
/FDer at pstplot % do we have a derivation defined?
\ifPst at algebraic (\psk at Derive) tx at addDict begin AlgParser end cvx
\else { \psk at Derive } \fi def % define derivation
\fi%%dr 0606
\fi
/@parametric false def %%dr 0606
% first we calculate the origin
#1 dup /x ED /t ED tx at addDict begin mark F at pstplot end counttomark 1 gt
% test, if we have parametricplot
%%{ /y ED /x ED } % if yes, then we have 2 values
{ /y ED /x ED /@parametric true def } % if yes, then we have 2
values%%dr 0606
{ \ifPst at polarplot x \ifPst at algebraic RadtoDeg \fi PtoC /y ED /x ED
\else /y ED \fi } ifelse
cleartomark
\ifx\psk at Derive\@NOTEMPTY%%begin dr 0606
%% algebraic we can use the derivative machine
/FDer at pstplot (#4) @parametric { (t) } { (x) } ifelse
tx at Derive begin Derive end tx at addDict begin AlgParser end cvx def
\fi%%end dr 0606
x \pst at number\psxunit mul y \pst at number\psyunit mul
translate % define the temporary origin
% now we calculate the slope of the tangent
\ifx\psk at Derive\@empty% de we have a derivation defined?
#1 abs 1.0e-6 lt % no, we choose secant for the tangent
{ #1 0.0005 add dup /x ED /t ED tx at addDict begin mark F at pstplot end
counttomark 1 gt % test, if we have parametricplot
{ /y2 ED /x2 ED }  % we have 2 values
{ \ifPst at polarplot dup x \ifPst at algebraic RadtoDeg \fi
cos mul /x2 ED x \ifPst at algebraic RadtoDeg \fi sin mul \else /x2 x
def \fi /y2 ED } ifelse
cleartomark % delete the mark
#1 0.0005 sub dup /x ED /t ED tx at addDict begin mark F at pstplot end
counttomark 1 gt % test, if we have parametricplot
{ /y1 ED /x1 ED }
{ \ifPst at polarplot dup x \ifPst at algebraic RadtoDeg \fi
cos mul /x1 ED x \ifPst at algebraic RadtoDeg \fi sin mul \else /x1
x def \fi /y1 ED } ifelse
cleartomark
y2 y1 sub x2 x1 sub } % dy dx
{  % > 1.0e-06
#1 1.0005 mul dup /x ED /t ED tx at addDict begin mark F at pstplot end
counttomark 1 gt % test, if we have parametricplot
{ /y2 ED /x2 ED } % we have 2 values
{ \ifPst at polarplot dup x \ifPst at algebraic RadtoDeg \fi
cos mul /x2 ED x \ifPst at algebraic RadtoDeg \fi sin mul \else /x2
x def \fi /y2 ED } ifelse
cleartomark
#1 .9995 mul dup /x ED /t ED tx at addDict begin mark F at pstplot end
counttomark 1 gt % test, if we have parametricplot
{ /y1 ED /x1 ED } % we have 2 values
{ \ifPst at polarplot dup x \ifPst at algebraic RadtoDeg \fi
cos mul /x1 ED x \ifPst at algebraic RadtoDeg \fi sin mul \else /x1
x def \fi /y1 ED } ifelse
cleartomark
y2 y1 sub \pst at number\psyunit mul x2 x1 sub \pst at number\psxunit mul
} ifelse
atan %  atan(dy dx), we have the slope angle of the secant
\else % there is a derivation defined
#1 dup /x ED /t ED tx at addDict begin mark FDer at pstplot end counttomark 1
gt % test, if we have parametricplot
{ /y ED /x ED }
{ \ifPst at polarplot /Fphi ED % the value F'(phi)
tx at addDict begin F at pstplot end x \ifPst at algebraic RadtoDeg \fi
PtoC /y0 ED /x0 ED % the x y values
x \ifPst at algebraic RadtoDeg \fi sin Fphi mul x0 add /y ED
x \ifPst at algebraic RadtoDeg \fi cos Fphi mul y0 sub /x ED
\else /y ED /x 1 def \fi } ifelse
cleartomark
y \pst at number\psyunit mul x \pst at number\psxunit mul Atan \ifPST at Tnormal
%    y ATAN1  % we have the slope angle of the tangent. ATAN is defined int
the pstricks.pro, patch 6
\fi
rotate 					% rotate, depending to the
origin
[
\ifPST at Tnormal
0 0 % moveto
#2
y \pst at number\psyunit mul x \pst at number\psxunit mul Atan 90 add cos
div \pst at number\psxunit mul 0  % lineto
\else
-#2 \pst at number\psxunit mul 0 		% moveto
#3 \pst at number\psxunit mul 0 		% lineto
\fi
\pst at cp					% kill the currentpoint, if
any
false					% don't show the points
\tx at Line
%      ArrowA CP 4 2 roll ArrowB L          	% the line with arrows L is
defined in pstricks.pro
%     \pst at number\pslinewidth SLW		% set linewidth in pt
%     \@nameuse{psls@\pslinestyle}           	% linestyle
%     \pst at usecolor\pslinecolor			% linecolor
stroke					% stroke everything
\ifshowpoints 				% show the points?
\psk at dotsize
\@nameuse{psds@\psk at dotstyle}%
0 0 Dot
\fi
grestore					% restore old graphics state
}%
\use at pscode					% part of \end at OpenObj
\endgroup%					% part of \end at OpenObj
\ignorespaces%				% part of \end at OpenObj
}%
\makeatother

\begin{document}

\psset{algebraic}

\begin{psgraph}(0,0)(-3,0)(3,10){1\textwidth}{5.4cm}
\psplot{-3}{3}{x^2}
\psplotTangent[linecolor=red]{2}{1}{3}{x^2}
\end{psgraph}

\end{document}