diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/curve2e/curve2e.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/curve2e/curve2e.dtx | 749 |
1 files changed, 576 insertions, 173 deletions
diff --git a/Master/texmf-dist/source/latex/curve2e/curve2e.dtx b/Master/texmf-dist/source/latex/curve2e/curve2e.dtx index 7e5e7bae80f..55ef4c3f96b 100644 --- a/Master/texmf-dist/source/latex/curve2e/curve2e.dtx +++ b/Master/texmf-dist/source/latex/curve2e/curve2e.dtx @@ -57,7 +57,7 @@ and the derived files curve2e.sty and curve2e.pdf. %</driver> %<+package>\ProvidesPackage{curve2e}% %<*package> - [2015/06/19 v.1.50 Extension package for pict2e] + [2015/06/27 v.1.54 Extension package for pict2e] %</package> %<*driver> \documentclass{ltxdoc}\errorcontextlines=9 @@ -76,16 +76,28 @@ and the derived files curve2e.sty and curve2e.pdf. \renewcommand\marg[1]{\texttt{\{\meta{#1}\}}} \providecommand\oarg{} \renewcommand\oarg[1]{\texttt{[\meta{#1}]}} +\providecommand\aarg{} +\renewcommand*\aarg[1]{\texttt{<\meta{#1}>}} \providecommand\parg{} -\renewcommand\parg[1]{\texttt{(#1)}} +\renewcommand\parg[1]{\texttt{(\meta{#1})}} \makeatletter + \newcommand*\Pall[1][1.5]{\def\circdiam{#1}\@Pall} \def\@Pall(#1){\put(#1){\circle*{\circdiam}}} + \def\legenda(#1,#2)#3{\put(#1,#2){\setbox3333\hbox{$#3$}% \dimen3333\dimexpr\wd3333*\p@/\unitlength +3\p@\relax \edef\@tempA{\strip@pt\dimen3333}% \framebox(\@tempA,7){\box3333}}} -\def\Zbox(#1)[#2]#3{\put(#1){\makebox(0,0)[#2]{$#3$}}} + +\def\Zbox(#1){\bgroup\edef\@tempA{#1}\@Zbox} + +\newcommand*\@Zbox[2][]{\fboxrule\z@\fboxsep=0.75ex\relax +\setbox2575\hbox{\fbox{$\relax\rule[-0.5ex]{0pt}{2.5ex}#2\relax$}}\relax +\ifx\@tempB\empty +\put(\@tempA){\makebox(0,0){\box2575}}\else +\put(\@tempA){\makebox(0,0)[#1]{\box2575}}\fi\egroup\ignorespaces} + \begin{document} \maketitle \columnseprule=0.4pt @@ -97,7 +109,7 @@ and the derived files curve2e.sty and curve2e.pdf. %</driver> % \fi % -% \CheckSum{2756} +% \CheckSum{3078} % \begin{abstract} % This file documents the |curve2e| extension package to the recent % implementation of the |pict2e| bundle that has been described by Lamport @@ -242,7 +254,7 @@ and the derived files curve2e.sty and curve2e.pdf. % version fills up the interior of the curve with the currently specified color. %^^A % \item |\Curve| is a recursive macro that can draw an unlimited (reasonably -% low) number of connecter Bézier spline arcs with continuos tangents except +% low) number of connected Bézier spline arcs with continuos tangents except % for cusps; these arcs require only the specification of te tangent % direction at the interpolation nodes. It is possible to use a lower level % macro |\CbezierTo| that does the same but lets the user specify the control @@ -333,8 +345,8 @@ and the derived files curve2e.sty and curve2e.pdf. % be drawn with a thickness of 0.5\,pt. The command |\linethickness| redefines the % above internals but does not change the default width value; all these width % specifications apply to all lines, straight ones, curved ones, circles, ovals, -% vectors, dashed, et cetera. It's better to recall that |thinlines| and -% |thicklines| are declarations that do not take arguments; on the opposite the +% vectors, dashed, et cetera. It's better to recall that |\thinlines| and +% |\thicklines| are declarations that do not take arguments; on the opposite the % other two commands follow the standard syntax: % \begin{flushleft} % |\linethickness|\marg{dimensioned value}\\ @@ -353,7 +365,7 @@ and the derived files curve2e.sty and curve2e.pdf. % command |\segment(3,4)(28,19)| achieves the same result without the need of % using command |\put|. % The same applies to the vector commands |\Vector| and |\VECTOR|. Experience has -% shown that the commands intended to joint two specified coordinates are +% shown that the commands intended to join two specified coordinates are % particularly useful. %^^A % \item The |\polyline| command has been introduced: it accepts an unlimited @@ -361,8 +373,7 @@ and the derived files curve2e.sty and curve2e.pdf. % draws a sequence of connected segments that joins in order the specified % points; the syntax is: % \begin{flushleft} -%\cs{polyline}\texttt{[}\marg{optional join style}\texttt{]% -%(}\meta{$P_1$}\texttt{)(}\meta{$P_2$}\texttt{)...(}\meta{$P_n$}\texttt{)} +%\cs{polyline}\oarg{optional join style}\parg{$P_1$}\parg{$P_2$}\texttt{...}\parg{$P_n$} % \end{flushleft} % See figure~\ref{fig:polyline} where a regular pentagon is drawn; usage of polar % coordinates is also shown. @@ -397,7 +408,7 @@ and the derived files curve2e.sty and curve2e.pdf. %^^A % \item The new command |\Dashline| (alias: |\Dline| for backwards compatibility) % \begin{flushleft} -% |\Dashline(|\meta{first point}|)(|\meta{second point}|){|\meta{dash length}|}| +% |\Dashline|\parg{first point}\parg{second point}\marg{dash length} % \end{flushleft} % draws a dashed line containing as many dashes as possible, long as specified, % and separated by a gap exactly the same size; actually, in order to make an @@ -446,7 +457,7 @@ and the derived files curve2e.sty and curve2e.pdf. %\item Analogous to |\Dashline|, a new command |\Dotline| draws a dotted line with % the syntax: % \begin{flushleft} -% |\Dotline(|\meta{first point}|)(|\meta{end point}|){|\meta{dot gap}|}| +% |\Dotline|\parg{first point}\parg{end point}\marg{dot gap} % \end{flushleft} % See figures~\ref{fig:dashline} and~\ref{fig:dottedlines} for examples. %^^A @@ -482,11 +493,11 @@ and the derived files curve2e.sty and curve2e.pdf. % These trigonometric functions are used within the complex number macros; but if % the user wants to use them the syntax is the following: %\begin{flushleft} -% \texttt{\char92SinOf}\meta{angle}\texttt{to}\meta{control sequence} +% \cs{SinOf}\meta{angle}\texttt{to}\meta{control sequence} %\\ -% \texttt{\char92CosOf}\meta{angle}\texttt{to}\meta{control sequence} +% \cs{CosOf}\meta{angle}\texttt{to}\meta{control sequence} %\\ -% \texttt{\char92TanOf}\meta{angle}\texttt{to}\meta{control sequence} +% \cs{TanOf}\meta{angle}\texttt{to}\meta{control sequence} %\end{flushleft} % The \meta{control sequence} may then be used as a multiplying factor of a % length. @@ -494,12 +505,9 @@ and the derived files curve2e.sty and curve2e.pdf. % \item Arcs can be drawn as simple circular arcs, or with one or two arrows at % their ends (curved vectors); the syntax is: %\begin{flushleft} -% \texttt{\char92Arc(}\meta{center}\texttt{)(}\meta{starting point}\texttt{)}% -%\marg{angle}\\ -% \texttt{\char92VectorArc(}\meta{center}\texttt{)(}\meta{starting point}% -%\texttt{)}\marg{angle}\\ -% \texttt{\char92VectorARC(}\meta{center}\texttt{)(}\meta{starting point}% -%\texttt{)}\marg{angle}\\ +% \cs{Arc}\parg{center}\parg{starting point}\marg{angle}\\ +% \cs{VectorArc}\parg{center}\parg{starting point}\marg{angle}\\ +% \cs{VectorARC}\parg{center}\parg{starting point}\marg{angle}\\ %\end{flushleft} % If the angle is specified numerically it must be enclosed in braces, while if it % is specified with a control sequence the braces (curly brackets) are not @@ -543,11 +551,12 @@ and the derived files curve2e.sty and curve2e.pdf. % \meta{vector macro} means a macro the contains a comma separated pair of % fractional numbers; \meta{angle macro} means a macro that contains the angle % of a vector in sexagesimal degrees; \meta{argument} means a brace delimited -% numeric value, possibly a macro; \textit{macro} is a valid macro name, that +% numeric value, even a macro; \textit{macro} is a valid macro name, that % is a backslash followed by letters, or anything else that can receive a % definition. A `direction' of a vector is its versor; the angle of a vector -% is the angle between the vector and the positive $x$ axis, generally directly -% used in the Euler formula $ \vec{v} = Me^{\mathrm{j}\varphi}$. +% is the angle between the vector and the positive $x$ axis in counterclockwise +% direction, generally directly used in the Euler formula $ \vec{v} = +% Me^{\mathrm{j}\varphi}$. % % {\footnotesize\begin{itemize} % \item |\MakeVectorFrom|\meta{two arguments}|to|\meta{vector macro} @@ -579,12 +588,12 @@ and the derived files curve2e.sty and curve2e.pdf. % nodes. This macro is |\Curve| and must be followed by an ``unlimited'' % sequence of node-direction coordinates as a quadruple defined as %\[ -% \texttt{(}\meta{node coordinates}\texttt{)<}\meta{direction vector}\texttt{>} +% \parg{node coordinates}\aarg{direction vector} %\] % Possibly if a sudden change of direction has to be performed (cusp) another item % can be inserted after one of those quadruples in the form %\[ -% \texttt{...(...)<...>[}\meta{new direction vector}\texttt{](...)<...>...} +% \mbox{\dots\parg{...}\aarg{...}\oarg{new direction vector}\parg{...}\aarg{...}\dots} %\] % The |\Curve| macro does not (still) have facilities for cycling the path, % that is to close the path from the last specified node-direction to the first @@ -719,8 +728,7 @@ and the derived files curve2e.sty and curve2e.pdf. % \begin{thebibliography}{9} % \bibitem{pict2e} Gäßlein H., Niepraschk R., and Tkadlec J. % \emph{The \texttt{pict2e} -% package}, 2009, PDF document attached to the ``new'' \texttt{pict2e} bundle; the -% bundle may be downloaded from any CTAN archive or one of their mirrors. +% package}, 2014, PDF documentation of \texttt{pict2e} is part of any modern complete distribution of the \TeX\ system. In case of a basic or partial system installation, the package may be installed by means of the specific facilities of the distribution. It may be read by means of the line command \texttt{texdoc pict2e}. % \end{thebibliography} % } % @@ -809,7 +817,7 @@ and the derived files curve2e.sty and curve2e.pdf. % $x_1, y_1$ and likewise the second argument is $x_2, y_2$. Please remember that % the decimal separator is the decimal \emph{point}, while the \emph{comma} acts % as coordinate separator. This recommendation is particularly important for -% non-English speaking users, since in all other languages the comma +% non-English speaking users, since in all other languages the comma % must be used as the decimal separator. % % The |\line| macro is redefined by making use of a new division routine that @@ -968,7 +976,7 @@ and the derived files curve2e.sty and curve2e.pdf. %\label{fig:dashedlines} %\end{figure} % -% A simpler |\Dotline| macro can draw a dotted line between to given points; +% A simpler |\Dotline| macro can draw a dotted line between two given points; % the dots are rather small, therefore the inter dot distance is computed in % such a way as to have the first and the last dot at the exact position of % the dotted-line end-points; again the specified dot distance is nominal in @@ -1283,29 +1291,30 @@ and the derived files curve2e.sty and curve2e.pdf. % \subsection{Polylines} % We now define the polygonal line macro; its syntax is very simple % \begin{flushleft} -% \cs{polygonal}\texttt{(}$P_0$\texttt{)(}$P_1$\texttt{)(}$P_2$)% +% \cs{polygonal}\oarg{join}\texttt{(}$P_0$\texttt{)(}$P_1$\texttt{)(}$P_2$)% % \texttt{\dots(}$P_n$\texttt{)} % \end{flushleft} +% Remember: |\polyline| has been incorporated into |pict2e| 2009, but we +% redefine it so as to allow an optional argument to specify the line join type. +% % In order to write a recursive macro we need aliases for the parentheses; % actually we need only the left parenthesis, but some editors complain about % unmatched delimiters, so we define an alias also for the right parenthesis. % \begin{macrocode} \let\lp@r( \let\rp@r) % \end{macrocode} -% The first call to |\polyline| examines the first point coordinates and moves -% the drawing position to this point; afterwards it looks for the second point -% coordinates; they start with a left parenthesis; if this is found the -% coordinates should be there, but if the left parenthesis is missing (possibly -% preceded by spaces that are ignored by the |\@ifnextchar| macro) then a -% warning message is output together with the line number where the missing -% parenthesis causes the warning: beware, this line number might point to -% several lines further on along the source file! In any case it's necessary to -% insert a |\@killglue| command, because |\polyline| refers to absolute -% coordinates not necessarily is put in position through a |\put| command that -% provides to eliminate any spurious spaces preceding this command. -% -% Remember: |\polyline| has been incorporated into |pict2e| 2009, but we -% redefine it so as to allow an optional argument to specify the line join type. +% The first call to |\polyline|, besides setting the line joints, examines +% the first point coordinates and moves the drawing position to this point; +% afterwards it looks for the second point coordinates; they start with a +% left parenthesis; if this is found the coordinates should be there, but +% if the left parenthesis is missing (possibly preceded by spaces that are +% ignored by the |\@ifnextchar| macro) then a warning message is output +% together with the line number where the missing parenthesis causes the +% warning: beware, this line number might point to several lines further on +% along the source file! In any case it's necessary to insert a |\@killglue| +% command, because |\polyline| refers to absolute coordinates not necessarily +% is put in position through a |\put| command that provides to eliminate any +% spurious spaces preceding this command. % % In order to allow a specification for the joints of the various segments of % a polygonal line it is necessary to allow for an optional parameter; the default @@ -1397,7 +1406,7 @@ and the derived files curve2e.sty and curve2e.pdf. % 32-bit word contains the dimension in \emph{scaled points}, where 1\,pt % equals $2^{16}$\,sp. % -% Since the number of digits of the fractional part is constant (16) it is said +% Since the number of bits of the fractional part is constant (16) it is said % that the number representation is in \emph{fixed radix}. This is much % different form the scientific approach to fractional numbers where % a 32-bit word reserves 24 bits to the significant digits, one bit for the sign, @@ -1430,7 +1439,7 @@ and the derived files curve2e.sty and curve2e.pdf. % would require a lot of time for their execution; this is a serious problem % with package |pgfplots| with which it is possible to draw beautiful 2D and % 3D color diagrams, but at the expense of even dozens of seconds of computation -% time instead of microseconds. +% time instead of milliseconds. % % \subsection{The new division macro} % The most important macro in the whole package is the division @@ -1491,9 +1500,9 @@ and the derived files curve2e.sty and curve2e.pdf. % by 1\,pt = $1\times 2^{16}$, scales down the result by 16 bits, and if the total % length of the result is smaller than $2^{30}$, the result can be correctly % assigned to a dimension register. In any other case the extended features imply -% suitable error messages and the termination of the program. During the division -% and a scaling down by 16 bits, the result is not simply truncated, but it is -% rounded to the nearest integer (in scaled points). The first two operands +% suitable error messages but not the termination of the program. During the +% division and a scaling down by 16 bits, the result is not simply truncated, but +% it is rounded to the nearest integer (in scaled points). The first two operands % are lengths and the third is a macro. % % \begin{macrocode} @@ -1535,6 +1544,7 @@ and the derived files curve2e.sty and curve2e.pdf. \noexpand\egroup\noexpand\def\noexpand#3{% \strip@pt\dimexpr\@DimA*\@DimB/\p@\relax}}% \x\ignorespaces}% + \let\MultiplyFN\MultiplY \fi \fi % \end{macrocode} @@ -1585,7 +1595,7 @@ and the derived files curve2e.sty and curve2e.pdf. % converted to radians) is so small (about 0.017) that the sine and tangent % can be freely approximated with $y$ itself (the error being smaller than % approximately $10^{-6}$), while the cosine can be freely approximated with -% the formula $1-0.5y^2$ (the error being smaller than about $\cdot10^{-6}$). +% the formula $1-0.5y^2$ (the error being smaller than about $10^{-6}$). % % We keep using grouping so that internal variables are local to these groups % and do not mess up other things. @@ -1602,7 +1612,7 @@ and the derived files curve2e.sty and curve2e.pdf. % Computations are done with the help of counter |\I|, of the length |\@tdB|, % and the auxiliary control sequences |\Tan| and |\Cot| whose meaning is % transparent. The iterative process controlled by |\@whilenum| implements the -% (truncated) continued fraction expansion of the tangent function. +% (truncated) continued fraction expansion of the tangent function: % \[ % \tan x = \frac{1}{\displaystyle \frac{1\mathstrut}{\displaystyle x} % -\frac{1}{\displaystyle \frac{3\mathstrut}{\displaystyle x} @@ -1795,9 +1805,8 @@ and the derived files curve2e.sty and curve2e.pdf. % % The results obtainable with equation~\eqref{equ:tanfimezzi} are possibly % acceptable, but the square that must be computed in it tends to go in -% underflow if too many iterations are performed and the algorythim crashes; -% therefore it's virtually impossibile to get more than three correct digits -% after the decimal separator. +% underflow if too many iterations are performed and the algorithm crashes; +% therefore it's virtually impossibile to get an absolute error lower than 0.0005. % % It is probably better to refer to the Newton iterations for solving the % equation: @@ -1805,39 +1814,40 @@ and the derived files curve2e.sty and curve2e.pdf. % \tan\theta -\tan\theta_\infty= 0 %\end{equation} % in the unknown $\theta$ given the value $t=\tan\theta_\infty$; see -% figure~\ref{fig:tangenti}. -% -%\begin{figure}\centering\unitlength=0.007\textwidth -%\begin{picture}(100,60) +% figure~\ref{fig:tangenti}% +%\begin{figure}[!htb]\centering\unitlength=0.01\textwidth +%\begin{picture}(100,80) %\legenda(15,73){y=\tan\theta} -%\legenda(35,73){t=\tan\theta_\infty} -%\put(0,0){\vector(1,0){100}}\Zbox(100,1)[br]{\theta} -%\put(0,0){\vector(0,1){80}}\Zbox(1,80)[tl]{y} -%\Dashline(75,0)(75,80){2.5} -%\put(76,1){\makebox(0,0)[bl]{$\pi/2$}} +%\legenda(37,73){t=\tan\theta_\infty} +%\put(0,0){\vector(1,0){100}}\Zbox(100,0)[br]{\theta} +%\put(0,0){\vector(0,1){80}}\Zbox(0,80)[tl]{y} +%\Dashline(90,0)(90,80){2.5} +%\Zbox(90,0)[br]{\pi/2} +%\Pall[2](28.8,11)\Line(0,11)(80,11)%\Dashline(28.8,0)(28.8,11){2.5} +%\Zbox(0,11)[bl]{t}\Zbox(28.8,0)[br]{\theta_\infty} +% +%\Dashline(34,0)(34,11){1.5}\Zbox(34,0)[bl]{\theta_{i+1}} +% +%\Pall[2](47.5,21.83)\Dashline(47.5,0)(47.5,21.83){2.5} +%\Dashline(0,21.83)(47.5,21.83){2.5} +%\Zbox(0,20.83)[bl]{y_i}\Zbox(47.5,0)[bl]{\theta_{i}} +% +%\Pall[2](61.2,36.38)\Dashline(61.2,0)(61.2,36.38){2.5} +%\Dashline(0,36.38)(61.2,36.38){2.5} +%\Zbox(0,36.38)[bl]{y_{i-1}}\Zbox(61.2,0)[bl]{\theta_{i-1}} +% +%\Pall[2](72,61.55367)\Dashline(72,0)(72,61.55367){2.5} +%\Dashline(0,61.55367)(72,61.55367){2.5} +%\Zbox(0,61.55367)[bl]{y_{i-2}}\Zbox(72,0)[bl]{\theta_{i-2}} +% %\put(0,0){\linethickness{1pt} -%\Curve(0,0)<1,0.8>(24,20)<1,0.90>(51,49.5)<17,29,5>(60,70)<1,5>(62,80)<1,8>} -%\put(51,49.5){\circle*{2}} -%\Dashline(51,0)(51,49.5){2.5} -%\put(52,1){\makebox(0,0)[bl]{$\theta_{i-1}$}} -%\Dashline(0,49.5)(51,49.5){2.5} -%\put(1,51){\makebox(0,0)[bl]{$y_{i-1}$}} -%\put(0,20){\line(1,0){70}}\put(1,21){\makebox(0,0)[bl]{$t$}} -%\Line(34,20)(51,49.25) -%\Line(60.15,70)(51,20) -%\put(51,20){\circle*{2}}\put(60,70){\circle*{2}} -%\Dashline(60,0)(60,70){2.5} -%\put(61,1){\makebox(0,0)[bl]{$\theta_{i-2}$}} -%\Dashline(0,70)(60,70){2.5} -%\put(1,71){\makebox(0,0)[bl]{$y_{i-2}$}} -%\put(34,20){\circle*{2}}\put(34,29.5){\circle*{2}} -%\Dashline(34,0)(34,29.5){2.5} -%\Dashline(0,29.5)(34,29.5){2.5} -%\put(1,30.5){\makebox(0,0)[bl]{$y_i$}} -%\put(35,1){\makebox(0,0)[bl]{$\theta_{i}$}} -%\put(24,20){\circle*{2}} -%\Dashline(24,0)(24,20){2.5} -%\put(25,1){\makebox(0,0)[bl]{$\theta_\infty$}} +%\Curve%(0,0)<1,0.34907>(28.8,11)<1,0.45456>(47.5,21.83)<1,0.76479>% +%(61.2,36.38)<1,1.91499>(72,61.55367)<1,4.65428>(74.4,71.6)<1,6.14571> +%}% +% +%\Line(34,11)(47.5,21.83) +%\Line(61.2,36.38)(47.5,11) +%\Line(72,61.55367)(61.2,11) %\end{picture} %\caption{Newton's method of tangents}\label{fig:tangenti} %\end{figure} @@ -1859,18 +1869,28 @@ and the derived files curve2e.sty and curve2e.pdf. % already have the algorithms for computing both the tangent and the cosine; % such Newton iterative method does not set forth any problem, especially if we % use the properties of the trigonometric functions and we confine the -% computations to the first quadrant. +% computations to the first quadrant; possibly we limit the computations +% to the first octant and we resort to the cotangent when the tangent exceeds +% one; in this case we use the same algorithm, but we have to get the +% complementary angle; in order to make computations with positive numbers, +% we save the initial tangent sign and we restore it to the result. % \begin{macrocode} \def\ArcTanOf#1to#2{\bgroup +\countdef\Inverti 4444\Inverti=0 +\def\Segno{} \edef\@tF{#1}\@tdF=\@tF\p@ \@tdE=57.295778\p@ -\@tdD=\ifdim\@tdF>\z@ \@tdF\else -\@tdF\fi +\@tdD=\ifdim\@tdF<\z@ -\@tdF\def\Segno{-}\else\@tdF\fi +\ifdim\@tdD>\p@ +\Inverti=\@ne +\@tdD=\dimexpr\p@*\p@/\@tdD\relax +\fi \unless\ifdim\@tdD>0.02\p@ - \def\@tX{\strip@pt\dimexpr57.295778\@tdF\relax}% + \def\@tX{\strip@pt\dimexpr57.295778\@tdD\relax}% \else \edef\@tX{45}\relax - \countdef\I 2523 \I=8\relax + \countdef\I 2523 \I=9\relax \@whilenum\I>0\do{\TanOf\@tX to\@tG - \edef\@tG{\strip@pt\dimexpr\@tG\p@-\@tdF\relax}\relax + \edef\@tG{\strip@pt\dimexpr\@tG\p@-\@tdD\relax}\relax \MultiplY\@tG by57.295778to\@tG \CosOf\@tX to\@tH \MultiplY\@tH by\@tH to\@tH @@ -1878,7 +1898,10 @@ and the derived files curve2e.sty and curve2e.pdf. \edef\@tX{\strip@pt\dimexpr\@tX\p@ - \@tH\p@\relax}\relax \advance\I\m@ne}% \fi -\edef\x{\egroup\noexpand\edef\noexpand#2{\@tX}}\x\ignorespaces}% +\ifnum\Inverti=\@ne +\edef\@tX{\strip@pt\dimexpr90\p@-\@tX\p@\relax} +\fi +\edef\x{\egroup\noexpand\edef\noexpand#2{\Segno\@tX}}\x\ignorespaces}% % \end{macrocode} % % \subsection{Arcs and curves preliminary information} @@ -1938,7 +1961,7 @@ and the derived files curve2e.sty and curve2e.pdf. % roto-amplification operator that scales its operand and rotates it about % a pivot point; besides the usual conventional representation used by the % mathematicians where the ordered pair is enclosed in round parentheses -% (which is in perfect agreement with the standard code use by the |picture| +% (which is in perfect agreement with the standard code used by the |picture| % environment) there is the other conventional representation used by the % engineers that stress the roto-amplification nature of a complex number: %\[ @@ -2049,7 +2072,7 @@ and the derived files curve2e.sty and curve2e.pdf. \MakeVectorFrom\t@X\t@Y to#2\ignorespaces}% % \end{macrocode} % -% A cumulative macro uses the above ones for determining with one call both the +% A cumulative macro uses the above ones to determine with one call both the % magnitude and the direction of a complex number. The first argument is the % input complex number, the second its magnitude, and the third is again a % complex number normalized to unit magnitude (unless the input was the null @@ -2148,43 +2171,12 @@ and the derived files curve2e.sty and curve2e.pdf. \edef\x{\noexpand\egroup\noexpand\edef\noexpand#2{\ArcTan}}% \x\ignorespaces} % \end{macrocode} -%^^A \begin{tabular}{ll} -%^^A 0 & \ArcTanOf 0 to\Res \Res\\ -%^^A 0.01 & \ArcTanOf 0.01 to\Res \Res\\ -%^^A 0.02 & \ArcTanOf 0.02 to\Res \Res\\ -%^^A 0.04 & \ArcTanOf 0.04 to\Res \Res\\ -%^^A 0.05 & \ArcTanOf 0.05 to\Res \Res\\ -%^^A 0.06 & \ArcTanOf 0.06 to\Res \Res\\ -%^^A 0.09 & \ArcTanOf 0.09 to\Res \Res\\ -%^^A 0.1 & \ArcTanOf 0.1 to\Res \Res\\ -%^^A 0.2 & \ArcTanOf 0.2 to\Res \Res\\ -%^^A 0.4 & \ArcTanOf 0.4 to\Res \Res\\ -%^^A 0.5 & \ArcTanOf 0.5 to\Res \Res\\ -%^^A 0.6 & \ArcTanOf 0.6 to\Res \Res\\ -%^^A 0.8 & \ArcTanOf 0.8 to\Res \Res\\ -%^^A 0.707 & \ArcTanOf 0.707 to\Res \Res\\ -%^^A 1 & \ArcTanOf 1 to\Res \Res\\ -%^^A 2 & \ArcTanOf 2 to\Res \Res\\ -%^^A \end{tabular} -% -% \bigskip -% -%^^A \begin{tabular}{rl} -%^^A 0,0 & \ArgOfVect0,0to\Res \Res\\ -%^^A 1,0 & \ArgOfVect1,0to\Res \Res\\ -%^^A -1,0 & \ArgOfVect-1,0to\Res \Res\\ -%^^A 0,1 & \ArgOfVect0,1to\Res \Res\\ -%^^A 0,-1 & \ArgOfVect0,-1to\Res \Res\\ -%^^A 1,1 & \ArgOfVect1,1to\Res \Res\\ -%^^A 1,-1 & \ArgOfVect1,-1to\Res \Res\\ -% ^^A-1,1 & \ArgOfVect-1,1to\Res \Res\\ -% ^^A-1,-1 & \ArgOfVect-1,-1to\Res \Res\\ -%^^A \end{tabular} -% It is worth noting that the absolute error in these computations is lower -% than 0.0001°; pretty satisfactory since the typesetting engines work in -% fixed radix notation with 16 fractional binary digits, and an error on -% the fifth fractional decimal digit is almost the best it can be expected -% from this kind of arithmetics. +% +% It is worth noting that the absolute average error in these computations is +% much lower than 0.0001°; pretty satisfactory since the typesetting engines work +% in fixed radix notation with 16 fractional binary digits, and an error on +% the fourth or fifth fractional decimal digit is almost the best it can be +% expected from this kind of arithmetics. % % Sometimes it is necessary to scale a vector by an arbitrary real factor; this % implies scaling both the real and imaginary part of the input given vector. @@ -2312,7 +2304,7 @@ and the derived files curve2e.sty and curve2e.pdf. \CopyVect#1to\@Cent \GetCoord(\@pPun)\@pPunX\@pPunY % \end{macrocode} % From now on it's better to define a new macro that will be used also in the -% subsequent macros that trace arcs; here we already have the starting point +% subsequent macros that draw arcs; here we already have the starting point % coordinates and the angle to draw the arc, therefore we just call the new % macro, stroke the line and exit. % \begin{macrocode} @@ -2320,7 +2312,7 @@ and the derived files curve2e.sty and curve2e.pdf. \strokepath\ignorespaces}% % \end{macrocode} % And the new macro |\@@Arc| starts with moving the drawing point to the first -% point and does everything needed for tracing the requested arc, except +% point and does everything needed for drawing the requested arc, except % stroking it; I leave the \texttt{stroke} command to the completion of the % calling macro and nobody forbids to use the |\@@Arc| macro for other purposes. % \begin{macrocode} @@ -2604,31 +2596,87 @@ and the derived files curve2e.sty and curve2e.pdf. % straight arrow tip if this one is large in comparison to the arc radius. % % \subsection{General curves} +% The most used method to draw curved lines with computer programs is to +% connect several simple curved lines, general ``arcs'', one to another +% generally maintaining the same tangent at the junction. I the direction +% changes we are dealing with a cusp. +% +% The simple general arcs that are directly implemented in every program that +% display typeset documents, are those drawn with the parametri curves called +% \emph{Béźier splines}; given a sequence of points in the $x,y$ plane, say +% $P_0, P_1, P_2, p_3, \dots$ (represented as coordinate pairs, i.e. by complex +% numbers), the most common Bézier splines are the following ones: +% \begin{align} +% \mathcal{B}_1 &= P_0(1-t) + P_1t \label{equ:B-1} \\ +% \mathcal{B}_2 &= P_0(1-t)^2 + P_1 2(1-t)t + P_2t^2 \label{equ:B-2} \\ +% \mathcal{B}_3 &= P_0(1-t)^3 + P_1 3(1-t)^2t +P_2 3(1-t)t^2 +P_3t^3 +% \label{equ:B-3} +% \end{align} +% +% All these splines depend on parameter $t$; they have the property that for +% $t=0$ each line starts at the first point, while for $t=1$ they reach the +% last point; in each case the generic point $P$ on each curve takes off +% with a direction that points to the next point, while it reaches the +% destination point with a direction coming from the penultimate point; +% moreover, when $t$ varies from 0 to 1, the curve arc is completely +% contained within the convex hull formed by the polygon that has the +% spline points as vertices. Last but not least first order splines implement +% just straight lines and they are out of question for what concerns maxima, +% minima, inflection points and the like. Quadratic splines draw just +% parabolas, therefore they draw arcs that have the concavity just on one +% side of the path; therefore no inflection points. Cubic splines are +% extremely versatile and can draw lines with maxima, minima and inflection +% points. Virtually a multi-arc curve may be drawn by a set of cubic splines +% as well as a set of quadratic splines (fonts are a good example: Adobe +% Type~1 fonts have their contours described by cubic splines, while TrueType +% fonts have their contours described with quadratic splines; with a naked +% eye it is impossible to notice the difference). +% +% Each program that processes the file to be displayed is capable of drawing +% first order Bézier splines (segments) and third order Bézier splines, for +% no other reason, at least, because they have to draw vector fonts whose +% contours are described by Bézier splines; sometimes they have also the +% program commands to draw second order Bézier splines, but not always these +% machine code routines are available to the user for general use. For what +% concerns |pdftex|, |xetex| and |luatex|, they have the user commands for +% straight lines and cubic arcs. At least with |pdftex|, quadratic arcs must +% be simulated with a clever use of third order Bézier splines. +% +% Notice that \LaTeXe\ environment |picture| by itself is capable of drawing +% both cubic and quadratic Bézier splines as single arcs; but it resorts to +% ``poor man'' solutions. The |pict2e| package removes all the old limitations +% and implements the interface macros for sending the driver the +% necessary drawing information, including the transformation from +% typographical points (72.27\,pt/inch) to PostScript big points (72\,bp/inch). +% But for what concerns the quadratic spline it resorts to the clever use of a +% cubic spline. +% +% Therefore here we treat first the drawings that can be made with cubic +% splines; then we describe the approach to quadratic splines. +% +%\subsection{Cubic splines} % Now we define a macro for tracing a general, not necessarily circular, arc. % This macro resorts to a general triplet of macros with which it is possible % to draw almost anything. It traces a single Bézier spline from a first point % where the tangent direction is specified to a second point where again it is % specified the tangent direction. Actually this is a special (possibly useless) -% case where the general |\curve| macro could do the same or a better job. In -% any case\dots +% case where the general |\curve| macro of |pict2e| could do the same or a +% better job. In any case\dots % \begin{macrocode} \def\CurveBetween#1and#2WithDirs#3and#4{% \StartCurveAt#1WithDir{#3}\relax \CurveTo#2WithDir{#4}\CurveFinish\ignorespaces}% % \end{macrocode} -% For backwards compatibility the old command with lower case |and| is made -% to do the same as this macro |\CurveBetween| with capitalised |And|. % % Actually the above macro is a special case of concatenation of the triplet % formed by macros |\StartCurve|, |\CurveTo| and|\CurveFinish|; the second of % which can be repeated an arbitrary number of times. %In any case the directions specified with the direction arguments, both here % and with the more general macro|\Curve|, the angle between the indicated -% tangent and the arc chord should never exceed 90° in absolute value; -% strange error messages may be issued by the interpreter. Some control is -% exercised on these values, but some tests might fail if the angle derives -% from computations; this is a good place to use polar forms for the direction -% vectors. +% tangent and the arc chord may give raise to some little problems when they +% are very close to 90° in absolute value. Some control is exercised on these +% values, but some tests might fail if the angle derives from computations; +% this is a good place to use polar forms for the direction vectors. % %\begin{figure}\centering\unitlength=0.004\textwidth %\begin{picture}(220,120)(-50,-20) @@ -2708,7 +2756,8 @@ and the derived files curve2e.sty and curve2e.pdf. \pIIe@moveto{\@tempa\unitlength}{\@tempb\unitlength}% \GetCoord(#2)\@tempa\@tempb \CopyVect\@tempa,\@tempb to\@Dzero -\DirOfVect\@Dzero to\@Dzero} +\DirOfVect\@Dzero to\@Dzero +\ignorespaces} % \end{macrocode} % And this re-initializes the direction to create a cusp: % \begin{macrocode} @@ -2754,14 +2803,16 @@ and the derived files curve2e.sty and curve2e.pdf. % be therefore: %\begin{flushleft} %\cs{CbezierTo}\meta{end -% point}|WithDir|\meta{direction}|AndDist|\meta{$K_0$}|And|\meta{$K_1$} +% point}|WithDir|\meta{direction}|AndDists|\meta{$K_0$}|And|\meta{$K_1$} %\end{flushleft} % where \meta{end point} is a vector macro or a comma separated pair of values; % again \meta{direction} is another vector macro or a comma separated pair of % values, that not necessarily indicate a unit vector, since the macro provides % to normalise it to unity; \meta{$K_0$} and\meta{$K_1$} are the distances of % the control point from their respective node points; they must be positive -% integers or fractional numbers. +% integers or fractional numbers. If \meta{$K_1$} is a number must be enclosed +% in curly braces, while if it is a macro name (containing the desired fractional +% or integer value) there is no need for braces. % % This macro uses the input information to use the internal |pict2e| macro % |\pIIe@curveto| with the proper arguments, and to save the final direction @@ -2797,13 +2848,13 @@ and the derived files curve2e.sty and curve2e.pdf. % % An example of use is shown in figure~\ref{fig:Cbezier}; notice that the % tangents at the end points are the same for the black curve drawn with -% |\CurveBetween| and the four red curves drawn with |\CbezierBetween|; the +% |\CurveBetween| and the five red curves drawn with |\CbezierBetween|; the % five red curves differ only for the distance of their control point $C_0$ % from the starting point; the differences are remarkable and the topmost % curve even presents a slight inflection close to the end point. These % effects cannot be obtained with the ``smarter'' macro |\CurveBetween|. But -% certainly this simpler macro is more difficult to use because of the -% distances of the control point are sort of unpredictable and require a +% certainly this simpler macro is more difficult to use because the +% distances of the control point are difficult to estimate and require a % number of cut-and-try experiments. % %\begin{figure}[!tb] @@ -2849,12 +2900,80 @@ and the derived files curve2e.sty and curve2e.pdf. % along the arc. % % The strategy I devised consists in determining each control point as if it -% were the control point of a circular arc, precisely an arc of an -% osculating circle, a circle tangent to the curve at that node. The ambiguity +% were the control point of a circular arc, precisely an arc of an osculating +% circle, i.e. a circle tangent to the curve at that node. The ambiguity % of the stated problem may be solved by establishing that the chord of the % osculating circle has the same direction as the chord of the arc being drawn, % and that the curve chord is divided into two equal parts each of which should be % interpreted as half the chord of the osculating circle. +% This makes the algorithm a little rigid; sometimes the path drawn is very +% pleasant, while in other circumstances the determined curvatures are too +% large or too small. We therefore add some optional information that lets +% us have some control over the curvatures; the idea is based on the concept +% of \emph{tension}, similar but not identical to the one used in the drawing +% programs \MF\ and \MP. We add to the direction information, with which the +% control nodes of the osculating circle arcs are determined, a scaling factor +% that should be intuitively related to the tension of the arc: the smaller +% this number, the closer the arc resembles a straight line as a rope subjected +% to a high tension; value zero is allowed, while a value of 4 is close to +% ``infinity'' and turns a quarter circle into a line with an unusual loop; +% a value of 2 turns a quarter circle almost into a polygonal line +% with rounded corner. Therefore these tension factors should +% be used only for fine tuning the arcs, not as the first time a path is drawn. +% +% We devised a syntax for specifying direction and tensions: +%\begin{flushleft} +% \meta{direction\texttt{\upshape;}tension factors} +%\end{flushleft} +% where \emph{direction} contains a pair of fractional number that not +% necessarily refer to the components of a unit vector direction, but simply +% to a vector with the desired orientation; the information contained from +% the semicolon (included) to the rest of the specification is optional; if +% it is present, the \emph{tension factors} is simply a comma separated pair +% of fractional or integer numbers that represent respectively the tension +% at the starting or the ending node of a path arc. +% +% We therefor need a macro to extract the mandatory and optional parts: +% \begin{macrocode} +\def\@isTension#1;#2!!{\def\@tempA{#1}% +\def\@tempB{#2}\unless\ifx\@tempB\empty\strip@semicolon#2\fi} +\def\strip@semicolon#1;{\def\@tempB{#1}} +% \end{macrocode} +% By changing the tension values we can achieve different results: see +% figure~\ref{fig:tensions}. +%\begin{figure}[!htb]\centering +%\begin{minipage}{0.48\textwidth}\small +%\begin{verbatim} +%\raggedleft\unitlength=0.01\textwidth +%\begin{picture}(70,70) +%\put(0,0){\color{blue}\frame(70,70){}} +%\put(0,0){\color{red}\Curve(0,0)<1,1>(70,0)<1,-1>} +%\Curve(0,0)<1,1>(70,0)<1,-1;0,0> +%\Curve(0,0)<1,1>(70,0)<1,-1;0.2,0.2> +%\Curve(0,0)<1,1>(70,0)<1,-1;2,2> +%\Curve(0,0)<1,1>(70,0)<1,-1;4.5,4.5> +%\Curve(0,0)<1,1>(70,0)<1,-1;0,3> +%\Curve(0,0)<1,1>(70,0)<1,-1;3,0> +%\end{picture} +%\end{verbatim} +%\end{minipage} +%\hfill +%\begin{minipage}{0.46\textwidth} +%\raggedleft\unitlength=0.01\textwidth +%\begin{picture}(70,70) +%\put(0,0){\color{blue}\framebox(70,70){}} +%\put(0,0){\color{red}\Curve(0,0)<1,1>(70,0)<1,-1>} +%\Curve(0,0)<1,1>(70,0)<1,-1;0,0> +%\Curve(0,0)<1,1>(70,0)<1,-1;0.2,0.2> +%\Curve(0,0)<1,1>(70,0)<1,-1;2,2> +%\Curve(0,0)<1,1>(70,0)<1,-1;4.5,4.5> +%\Curve(0,0)<1,1>(70,0)<1,-1;0,3> +%\Curve(0,0)<1,1>(70,0)<1,-1;3,0> +%\end{picture} +%\end{minipage} +%\caption{The effects of tension factors}\label{fig:tensions} +%\end{figure} +% % % We use the formula we got for arcs~\eqref{equ:corda}, where the half chord is % indicated with $s$, and we derive the necessary distances: @@ -2869,7 +2988,10 @@ and the derived files curve2e.sty and curve2e.pdf. % chord and its direction: % \begin{macrocode} \def\CurveTo#1WithDir#2{% -\def\@Puno{#1}\def\@Duno{#2}\DirOfVect\@Duno to\@Duno +\def\@Tuno{1}\def\@Tzero{1}\relax +\edef\@Puno{#1}\@isTension#2;!!% +\expandafter\DirOfVect\@tempA to\@Duno +\bgroup\unless\ifx\@tempB\empty\GetCoord(\@tempB)\@Tzero\@Tuno\fi \DistanceAndDirOfVect\@Puno minus\@Pzero to\@Chord and\@DirChord % \end{macrocode} % Then we rotate everything about the starting point so as to bring the chord on @@ -2912,10 +3034,11 @@ and the derived files curve2e.sty and curve2e.pdf. \edef\@SinDzero{\ifdim\@DYpzero\p@<\z@ -\fi\@DYpzero}% \@tdA=\@semichord\p@ \@tdA=1.333333\@tdA \DividE\@tdA by\@SinDzero\p@ to \@KCzero - \@tdA=\dimexpr(\p@-\@CosDzero\p@) + \@tdA=\dimexpr(\p@-\@CosDzero\p@)\relax \DividE\@KCzero\@tdA by\@SinDzero\p@ to \@KCzero \fi \fi +\MultiplyFN\@KCzero by \@Tzero to \@KCzero \ScaleVect\@Dzero by\@KCzero to\@CPzero \AddVect\@Pzero and\@CPzero to\@CPzero % \end{macrocode} @@ -2940,22 +3063,23 @@ and the derived files curve2e.sty and curve2e.pdf. \edef\@SinDuno{\ifdim\@DYpuno\p@<\z@ -\fi\@DYpuno}% \@tdA=\@semichord\p@ \@tdA=-1.333333\@tdA \DividE\@tdA by \@SinDuno\p@ to \@KCuno - \@tdA=\dimexpr(\p@-\@CosDuno\p@) + \@tdA=\dimexpr(\p@-\@CosDuno\p@)\relax \DividE\@KCuno\@tdA by\@SinDuno\p@ to \@KCuno \fi \fi +\MultiplyFN\@KCuno by \@Tuno to \@KCuno \ScaleVect\@Duno by\@KCuno to\@CPuno \AddVect\@Puno and\@CPuno to\@CPuno % \end{macrocode} % Now we have the four points and we can instruct the internal \texttt{pict2e} -% macros to do the path tracing. +% macros to do the path drawing. % \begin{macrocode} \GetCoord(\@Puno)\@XPuno\@YPuno \GetCoord(\@CPzero)\@XCPzero\@YCPzero \GetCoord(\@CPuno)\@XCPuno\@YCPuno \pIIe@curveto{\@XCPzero\unitlength}{\@YCPzero\unitlength}% {\@XCPuno\unitlength}{\@YCPuno\unitlength}% - {\@XPuno\unitlength}{\@YPuno\unitlength}% + {\@XPuno\unitlength}{\@YPuno\unitlength}\egroup % \end{macrocode} % It does not have to stroke the curve because other Bézier splines might still % be added to the path. On the opposite it memorises the final point as the @@ -3005,7 +3129,7 @@ and the derived files curve2e.sty and curve2e.pdf. % As a concluding remark, please notice that the |\Curve| macro is certainly the % most comfortable to use, but it is sort of frozen in its possibilities. The % user may certainly use the |\StartCurve|, |\CurveTo|, |\ChangeDir|, and -% |\CurveFinish| or |FillCurve| for a more versatile set of drawing macros; +% |\CurveFinish| or |\FillCurve| for a more versatile set of drawing macros; % evidently nobody forbids to exploit the full power of the |\cbezier| original % macro for cubic splines; we made available macros |\CbezierTo| and the % isolated arc macro |\CbezierBetween| in order to use the general internal @@ -3015,24 +3139,20 @@ and the derived files curve2e.sty and curve2e.pdf. %\unitlength=0.01\textwidth %\begin{picture}(100,50)(0,-25) %\put(0,0){\VECTOR(0,0)(45,0)\VECTOR(0,-25)(0,25) -%\Zbox(45,1)[br]{x}\Zbox(1,25)[tl]{y} -%\Curve(0,0)<1,3.927>% -%(5,14.14)<1,2.776>% -%(10,20)<1,0>% -%(15,14.14)<1,-2.776>% -%(20,0)<1,-3.927>% -%(25,-14.14)<1,-2.776>% -%(30,-20)<1,0>% -%(35,-14.14)<1,2.776>% -%(40,0)<1,3.927>% +%\Zbox(45,0)[br]{x}\Zbox(0,26)[tl]{y} +%\Curve(0,0)<77:1>(10,20)<1,0;2,0.4>(30,-20)<1,0;0.4,0.4>(40,0)<77:1;0.4,2> %} -%\put(50,0){\VECTOR(0,0)(45,0)\VECTOR(0,-25)(0,25) -%\Zbox(45,1)[br]{x}\Zbox(1,25)[tl]{y} +%\put(55,0){\VECTOR(0,0)(45,0)\VECTOR(0,-25)(0,25) +%\Zbox(45,0)[br]{x}\Zbox(0,26)[tl]{y} %\CbezierBetween0,0And20,0WithDirs77:1And-77:1UsingDists28And{28} %\CbezierBetween20,0And40,0WithDirs-77:1And77:1UsingDists28And{28}} %\end{picture} -%\caption{A sequence of arcs; the left figure has been drawn with the \cs{Curve} command with a sequence of nine couples of point-direction arguments; the right figure has been drawn with two commands \cs{CbezierBetween} that include also the specification of the control points} -%\label{fig:sinewawe} +%\caption{A sequence of arcs; the left figure has been drawn with the +% \cs{Curve} command with a sequence of four couples of point-direction +% arguments; the right figure has been drawn with two commands +% \cs{CbezierBetween} that include also the specification of the control +% points} +%\label{fig:sinewave} %\end{figure} % % As it can be seen in figure~\ref{fig:sinewave} the two diagrams should @@ -3041,14 +3161,297 @@ and the derived files curve2e.sty and curve2e.pdf. % it is only possible to approximate it. It is evident that the approximation % obtained with full control on the control points requires less arcs and % it is more accurate than the approximation obtained with the recursive -% |\Curve| macro; this macro requires almost three times as many pieces of +% |\Curve| macro; this macro requires almost two times as many pieces of % information in order to minimise the effects of the lack of control on the % control points, and even with this added information the macro approaches % the sine wave with less accuracy. At the same time for many applications -% the |\Curve| recursive macro proves to be far much easier to use than with +% the |\Curve| recursive macro proves to be much easier to use than with % single arcs drawn with the |\CbezierBetween| macro. % -% I believe that the set of new macrosprovided by this package can really +% \subsection{Quadratic splines} +% We want to create a recursive macro with the same properties as the above +% described |\Curve| macro, but that uses quadratic splines; we call it +% |\Qurve| so that the initial macro name letter reminds us of the nature +% of the splines being used. For the rest they have an almost identical +% syntax; with quadratic spline it is not possible to specify the distance +% of the control points from the extrema, since quadratic spline have just +% one control point that must lay at the intersection of the two tangent +% directions therefore with quadratic splines the tangents at each point +% cannot have the optional part that starts with a semicolon. The syntax, therefore, is just: +%\begin{flushleft} +%\cs{Qurve}\parg{first point}\aarg{direction}...\parg{any point}\aarg{direction}...\parg{last point}\aarg{direction} +%\end{flushleft} +% As with |\Curve|, also with |\Qurve| there is no limitation on the number +% of points, except for the computer memory size; it is advisable not to use +% many arcs otherwise it might become very difficult to find errors. +% +% The first macros that set up the recursion are very similar to those we +% wrote for |\Curve|: +% \begin{macrocode} +\def\Qurve{\@ifstar{\let\fillstroke\fillpath\Qurve@}% +{\let\fillstroke\strokepath\Qurve@}} + +\def\Qurve@(#1)<#2>{% + \StartCurveAt#1WithDir{#2}% + \@ifnextchar\lp@r\@Qurve{% + \PackageWarning{curve2e}{% + Quadratic curve specifications must contain at least + two nodes!\Messagebreak + Please, control your Qurve specifications\MessageBreak}}}% +\def\@Qurve(#1)<#2>{\QurveTo#1WithDir{#2}% + \@ifnextchar\lp@r\@Qurve{% + \@ifnextchar[\@ChangeQDir\CurveEnd}}% +\def\@ChangeQDir[#1]{\ChangeDir<#1>\@Qurve}% +% \end{macrocode} +% Notice that in case of long paths it might be better to use the single +% macros |\StartCurveAt|, |\QurveTo|, |\ChangeDir| and |\CurveFinish| +% (or |\FillCurve|), with their respective syntax, in such a way that a long list +% of node-direction specifications passed to |\Qurve| may be split into +% shorter input lines in order to edit the input data in a more comfortable way. +% +% +% The macro that does everything is |\QurveTo|. it start with reading its +% arguments received through the calling macro |\@Qurve| +% \begin{macrocode} +\def\QurveTo#1WithDir#2{% +\edef\@Puno{#1}\DirOfVect#2to\@Duno\bgroup +\DistanceAndDirOfVect\@Puno minus\@Pzero to\@Chord and\@DirChord +% \end{macrocode} +% It verifies if |\@Dpzero| and |\@Dpuno|, the directions at the two extrema +% of the arc, are parallel or anti-parallel by taking their +% ``scalar'' product (|\@Dpzero| times |\@Dpuno*|); if the imaginary +% component of the scalar product vanishes the two directions are parallel; +% in this case we produce an error message, but we continue skipping this arc +% destination point; evidently the drawing will not be the desired one, but +% the job should not abort. +% \begin{macrocode} +\MultVect\@Dzero by*\@Duno to \@Scalar +\YpartOfVect\@Scalar to \@YScalar +\ifdim\@YScalar\p@=\z@ +\PackageWarning{curve2e}% + {Quadratic Bezier arcs cannot have their starting\MessageBreak + and ending directions parallel or antiparallel with\MessageBreak + each other. This arc is skipped and replaced with + a dotted line.\MessageBreak}% + \Dotline(\@Pzero)(\@Puno){2}\relax +\else +% \end{macrocode} +% Otherwise we rotate everything about the starting point so as to bring the +% chord on the real axis; we get also the components of the two directions that, +% we should remember, are unit vectors, not generic vectors, although the user +% can use the vector specifications that are more understandable to him/her: +% \begin{macrocode} +\MultVect\@Dzero by*\@DirChord to \@Dpzero +\MultVect\@Duno by*\@DirChord to \@Dpuno +\GetCoord(\@Dpzero)\@DXpzero\@DYpzero +\GetCoord(\@Dpuno)\@DXpuno\@DYpuno +% \end{macrocode} +% We check if the two directions point to the same half plane; this implies +% that these rotated directions point to different sides of the chord vector; +% all this is equivalent that the two direction Y components have opposite +% signs, and therefore their product is strictly negative, and that the two +% X components product is not negative. +% \begin{macrocode} +\MultiplyFN\@DXpzero by\@DXpuno to\@XXD +\MultiplyFN\@DYpzero by\@DYpuno to\@YYD +\unless\ifdim\@YYD\p@<\z@\ifdim\@XXD\p@<\z@ +\PackageWarning{curve2e}% + {Quadratic Bezier arcs cannot have inflection points\MessageBreak + Therefore the tangents to the starting and ending arc\MessageBreak + points cannot be directed to the same half plane.\MessageBreak + This arc is skipped and replaced by a dotted line\MessageBreak}% + \Dotline(\@Pzero)(\@Puno){2}\fi +\else +% \end{macrocode} +% +% After these tests we should be in a ``normal'' situation.We first copy +% the expanded input information into new macros that have more explicit +% names: macros stating wit `S' denote the sine of the direction angle, +% while those starting with `C' denote the cosine of that angle. We will +% use these expanded definitions as we know we are working with the actual +% values. These directions are those relative to the arc chord. +% \begin{macrocode} +\edef\@CDzero{\@DXpzero}\relax +\edef\@SDzero{\@DYpzero}\relax +\edef\@CDuno{\@DXpuno}\relax +\edef\@SDuno{\@DYpuno}\relax +% \end{macrocode} +% Suppose we write the parametric equations of a straight line that departs +% from the beginning of the chord with direction angle $\phi_0$ and the +% corresponding equation of the straight line departing from the end of the +% chord (of length $c$) with direction angle $\phi_1$. We have to find the +% coordinates of the intersection point of these two straight lines. +%\begin{subequations} +%\begin{align} +% t \cos\phi_0 - s \cos\phi_1 &= c\\ +% t \sin\phi_0 - s \sin\phi_1 &= 0 +%\end{align} +%\end{subequations} +% The parameters $t$ and $s$ are just the running parameters; we have +% to solve those simultaneous equations in the unknown variables $t$ and $s$; +% these values let us comupte the coordinates of the intersection point: +%\begin{subequations}\begin{align} +% X_C &=\dfrac{c\cos\phi_0\sin\phi_1}{\sin\phi_0\cos\phi_1 - \cos\phi_0\sin\phi_1} \\ +% Y_C &=\dfrac{c\sin\phi_0\sin\phi_1}{\sin\phi_0\cos\phi_1 - \cos\phi_0\sin\phi_1} +%\end{align}\end{subequations} +% +% Having performed the previous tests we are sure that the denominator is not +% vanishing (direction are not parallel or anti-parallel) and that it lays at +% the same side as the direction with angle $\phi_0$ with respect to the chord. +% The coding then goes on like this: +% \begin{macrocode} +\MultiplyFN\@SDzero by\@CDuno to\@tempA +\MultiplyFN\@SDuno by\@CDzero to\@tempB +\edef\@tempA{\strip@pt\dimexpr\@tempA\p@-\@tempB\p@}\relax +\@tdA=\@SDuno\p@ \@tdB=\@Chord\p@ \@tdC=\@tempA\p@ +\edef\@tempC{\strip@pt\dimexpr \@tdA*\@tdB/\@tdC}\relax +\MultiplyFN\@tempC by\@CDzero to \@XC +\MultiplyFN\@tempC by\@SDzero to \@YC +\ModOfVect\@XC,\@YC to\@KC +% \end{macrocode} +% We eventually computed the coordinates and the module of the intersection +% point vector taking into account the rotation of the real axis; getting +% back to the original coordinates before rotation we get: +% \begin{macrocode} +\ScaleVect\@Dzero by\@KC to\@CP +\AddVect\@Pzero and\@CP to\@CP +\GetCoord(\@Pzero)\@XPzero\@YPzero +\GetCoord(\@Puno)\@XPuno\@YPuno +\GetCoord(\@CP)\@XCP\@YCP +% \end{macrocode} +% We have now the coordinates of the two extrema point of the quadratic arc +% and of the control point. Keeping in mind that the symbols $P_0$, $P_1$ +% and $C$ denote geometrical points but also their coordinates as ordered +% pairs of real numbers (i.e. they are complex numbers) we have to determine +% the smart cubic arc nodes and control points; we should determine the +% values of $P_a$ and $P_b$ such that +%\[ +% P_0(1-t)^3 +3P_a(1-t)^2t +3P_b(1-t)t^2 +P_1t^3 +%\] +% is equivalent to +%\[ +% P_0(1-t)^2 + 2C(1-t)t + P_1t^2 +%\] +% It turns out that the solution is given by +%\begin{equation} +%P_a= C+(P_0-C)/3 \qquad \text{and}\qquad P_b = C+(P_1- C)/3 +%\label{equ:spline3} +%\end{equation} +% +% The transformations implied by equations~\eqref{equ:spline3} are performed +% by the following macros already available from the |pict2e| package; we +% use them here with the actual arguments used for this task: +% \begin{macrocode} +\@ovxx=\@XPzero\unitlength \@ovyy=\@YPzero\unitlength +\@ovdx=\@XCP\unitlength \@ovdy=\@YCP\unitlength +\@xdim=\@XPuno\unitlength \@ydim=\@YPuno\unitlength + \pIIe@bezier@QtoC\@ovxx\@ovdx\@ovro + \pIIe@bezier@QtoC\@ovyy\@ovdy\@ovri + \pIIe@bezier@QtoC\@xdim\@ovdx\@clnwd + \pIIe@bezier@QtoC\@ydim\@ovdy\@clnht + \pIIe@moveto\@ovxx\@ovyy +% \end{macrocode} +% +% We call the basic |pict2e| macro to draw a cubic spline and we finish +% the conditional statements with which we started these calculations; +% eventually we close the group we opened at the beginning and we copy +% the terminal node information (position and direction) into the +% 0-labelled macros that indicate the starting point of the next arc. +% \begin{macrocode} + \pIIe@curveto\@ovro\@ovri\@clnwd\@clnht\@xdim\@ydim +\fi\fi\egroup +\CopyVect\@Puno to\@Pzero +\CopyVect\@Duno to\@Dzero +\ignorespaces} +% \end{macrocode} +% +% An example of usage is shown at the left in figure~\ref{fig:quadratic-arcs}\footnote{The commands \cs{legenda}, \cs{Pall} and +% \cs{Zbox} are specifically defined in the preamble of this document; they must +% be used within a \texttt{picture} environment. \cs{legenda} draws a framed +% legend made up of a single (short) math formula; \cs{Pall} is just a shorthand +% to put a filled small circle at a specified position' \cs{Zbox} puts a +% symbol in math mode a little displaced in the proper direction relative to +% a specified position. They are just handy to label certain objects in a +% \texttt{picture} diagram, but they are not part of the \texttt{curve2e} +% package.}. +% created with the following code: +%\begin{verbatim} +%\begin{figure}[!htp] +%\unitlength=0.0045\textwidth +%\begin{picture}(100,100) +%\put(0,0){\framebox(100,100){}} +%\put(50,50){\Qurve(0,-50)<1,0>(50,0)<0,1>(0,50)<-1,0>% +%(-50,0)<0,-1>(0,-50)<1,0>\color{green}% +%\Qurve*(0,-50)<0,1>(50,0)<1,0>[-1,0](0,50)<0,1>[0,-1] +%(-50,0)<-1,0>[1,0](0,-50)<0,-1>} +%\Qurve(0,0)<1,4>(50,50)<1,0>(100,100)<1,4> +%\put(5,50){\Qurve(0,0)<1,1.5>(22.5,20)<1,0>(45,0)<1,-1.5>% +%(67.5,-20)<1,0>(90,0)<1,1.5>} +%\Zbox(0,0)[tl]{0,0}\Zbox(100,0)[tr]{100,0} +%\Zbox(100,100)[br]{100,100}\Zbox(0,100)[bl]{0,100} +%\end{picture} +%\end{figure} +%\end{verbatim} +% +%\begin{figure}[!tb] +%\unitlength=0.0045\textwidth +%\begin{picture}(100,100) +%\put(0,0){\framebox(100,100){}} +%\put(50,50){\Qurve(0,-50)<1,0>(50,0)<0,1>(0,50)<-1,0>(-50,0)<0,-1>(0,-50)<1,0>\color{green}% +%\Qurve*(0,-50)<0,1>(50,0)<1,0>[-1,0](0,50)<0,1>[0,-1](-50,0)<-1,0>[1,0](0,-50)<0,-1>} +%\Qurve(0,0)<1,4>(50,50)<1,0>(100,100)<1,4> +%\put(5,50){\Qurve(0,0)<1,1.5>(22.5,20)<1,0>(45,0)<1,-1.5>(67.5,-20)<1,0>(90,0)<1,1.5>} +%\Zbox(0,0)[tl]{0,0}\Zbox(100,0)[tr]{100,0} +%\Zbox(100,100)[br]{100,100}\Zbox(0,100)[bl]{0,100} +%\Pall[2](0,0)\Pall[2](100,0)\Pall[2](100,100)\Pall[2](0,100) +%\end{picture} +%\hfill +%\begin{picture}(100,100) +%\put(0,0){\framebox(100,100){}} +%\put(50,50){\Qurve(0,-50)<1,0>(50,0)<0,1>(0,50)<-1,0>(-50,0)<0,-1>(0,-50)<1,0> +%\Curve(0,-50)<1,0>(50,0)<0,1>(0,50)<-1,0>(-50,0)<0,-1>(0,-50)<1,0>} +%\Zbox(50,50)[t]{O}\Pall[2](50,50)\put(50,50){\Vector(45:50)}\Zbox(67,70)[tl]{R} +%\end{picture} +% +%\caption{\rule{0pt}{4ex}Several graphs drawn with quadratic Bézier splines} +%\label{fig:quadratic-arcs} +%\end{figure} +% +% Notice the green filled path: that result is not expected, but the filling +% operation is controlled by the inner workings of the typesetting program, +% where it fills what \emph{it} considers the interior of a path, not what +% \emph{we} think it is the interior of a path.Knowing this feature it is not +% difficult to fill the external lozenge with green, and then fill the internal +% path with white; the result would be to cover with white the external part of +% the interior path. Sort of odd way of getting the result, but this is not due +% to the quadratic splines but to the internal workings of |pdftex| and its +% companion typesetting engines, that consider ``interior'' the concave side of +% the closed path, not the convex one. +% +% Notice also that the inflexed line is made with two arcs that meet at the +% inflection point; the same is true for the line that resembles a sine wave. +% The cusps of the inner border of the green area are obtained with the usual +% optional argument already used also with the |\Curve| recursive macro. +% +% The ``circle'' inside the square frame is visibly different from a real +% circle, in spite of the fact that the maximum deviation from the true +% circle is just about 6\% relative to the radius; a quarter circle obtained +% with a single parabola is definitely a poor approximation of a real quarter +% circle; possibly by splitting each quarter circle in three or four partial +% arcs the approximation of a real quarter circle would be much better. On the +% right of figure~\ref{fig:quadratic-arcs} it is possible to compare a +% ``circle'' obtained with quadratic arcs with the the internal circle +% obtained with cubic arcs; the difference is easily seen even with a naked eye. +% +% With quadratic arcs we decided to avoid defining specific macros similar +% to |\CurveBetween| and |\CbezierBetween|; the first macro would not save +% any typing to the operator; furthermore it may be questionable if it was +% really useful even with cubic splines; the second macro with quadratic +% arcs is meaningless, since with quadratic arcs there is just one control +% point and there is no choice on its position. +% +% \section{Conclusion} +% I believe that the set of new macros provided by this package can really % help the user to draw his/her diagrams with more agility; it will be the % accumulated experience to decide if this is true. %\iffalse |