diff options
author | Karl Berry <karl@freefriends.org> | 2015-06-19 22:33:34 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2015-06-19 22:33:34 +0000 |
commit | fe3f79b0e5e6765e703a39b086c37f8ce3a33740 (patch) | |
tree | 846c798ba65ef30ae99d46464e226a7ca8865b47 /Master/texmf-dist/source/latex/curve2e | |
parent | e283bedf2d8ede94bd11f584ac25064c393fd9d4 (diff) |
curve2e (19jun15)
git-svn-id: svn://tug.org/texlive/trunk@37619 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/curve2e')
-rw-r--r-- | Master/texmf-dist/source/latex/curve2e/curve2e.dtx | 1858 |
1 files changed, 1271 insertions, 587 deletions
diff --git a/Master/texmf-dist/source/latex/curve2e/curve2e.dtx b/Master/texmf-dist/source/latex/curve2e/curve2e.dtx index 3af8caafb3e..7e5e7bae80f 100644 --- a/Master/texmf-dist/source/latex/curve2e/curve2e.dtx +++ b/Master/texmf-dist/source/latex/curve2e/curve2e.dtx @@ -9,7 +9,6 @@ The curve2e package for LaTeX and XeLATeX Copyright (C) 2010 Claudio Beccari All rights reserved - License information appended \endpreamble @@ -58,23 +57,38 @@ and the derived files curve2e.sty and curve2e.pdf. %</driver> %<+package>\ProvidesPackage{curve2e}% %<*package> - [2015/06/06 v.1.42 Extension package for pict2e] + [2015/06/19 v.1.50 Extension package for pict2e] %</package> %<*driver> \documentclass{ltxdoc}\errorcontextlines=9 \hfuzz 10pt -\usepackage{multicol,amsmath} \usepackage[utf8]{inputenc} \usepackage{lmodern,textcomp} \usepackage{mflogo} +\usepackage{multicol,amsmath,trace} \usepackage{curve2e} \GetFileInfo{curve2e.dtx} \title{The extension package \textsf{curve2e}} \author{Claudio Beccari} \date{Version number \fileversion; last revised \filedate.} \providecommand*\diff{\mathop{}\!\mathrm{d}} +\renewcommand\meta[1]{{\normalfont\textlangle\textit{#1}\textrangle}} +\renewcommand\marg[1]{\texttt{\{\meta{#1}\}}} +\providecommand\oarg{} +\renewcommand\oarg[1]{\texttt{[\meta{#1}]}} +\providecommand\parg{} +\renewcommand\parg[1]{\texttt{(#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$}}} \begin{document} - \maketitle +\maketitle +\columnseprule=0.4pt \begin{multicols}{2} \tableofcontents \end{multicols} @@ -83,7 +97,7 @@ and the derived files curve2e.sty and curve2e.pdf. %</driver> % \fi % -% \CheckSum{2484} +% \CheckSum{2756} % \begin{abstract} % This file documents the |curve2e| extension package to the recent % implementation of the |pict2e| bundle that has been described by Lamport @@ -92,11 +106,7 @@ and the derived files curve2e.sty and curve2e.pdf. % Please take notice that in April 2011 a new updated version of the package % |pict2e| has been released that incorporates some of the commands defined in % this package; apparently there are no conflicts, but only the advanced features -% of |curve2e| remain available for extending the above package. Moreover -% the |xetex.def| driver was introduced so that certain commands previously -% defined in this extension not only become unnecessary, but also would produce -% errors when the program is used under XeLaTeX. Therefore these commands were -% either eliminated or corrected. +% of |curve2e| remain available for extending the above package. % % This extension redefines a couple of commands and introduces some more drawing % facilities that allow to draw circular arcs and arbitrary curves with the @@ -105,6 +115,7 @@ and the derived files curve2e.sty and curve2e.pdf. % Please cite the original author and the chain of contributors. % \end{abstract} % +% % \section{Package \texttt{pict2e} and this extension \texttt{curve2e}} % Package \texttt{pict2e} was announced in issue 15 of \texttt{latexnews} % around December 2003; it was declared that the new package would replace the @@ -116,125 +127,187 @@ and the derived files curve2e.sty and curve2e.pdf. % documented in the second edition of his \LaTeX\ handbook, that is a \LaTeX\ % package that contained the macros capable of removing all the limitations % contained in the standard commands of the original \texttt{picture} -% environment; specifically: +% environment; specifically what follows. % \begin{enumerate} -% \item the line and vector slopes were limited to the ratios of relatively +% \item The line and vector slopes were limited to the ratios of relative % prime one-digit integers of magnitude not exceeding 6 for lines and 4 for -% vectors; -% \item filled and unfilled full circles were limited by the necessarily +% vectors. +%^^A +% \item Filled and unfilled full circles were limited by the necessarily % limited number of specific glyphs contained in the special \LaTeX\ -% \texttt{picture} fonts; -% \item quarter circles were also limited in their radii for the same reason; -% \item ovals (rectangles with rounded corners) could not be too small because +% \texttt{picture} fonts. +%^^A +% \item Quarter circles were also limited in their radii for the same reason. +%^^A +% \item Ovals (rectangles with rounded corners) could not be too small because % of the unavailability of small radius quarter circles, nor could be too % large, in the sense that after a certain radius the rounded corners remained % the same and would not increase proportionally to the oval size. -% \item vector arrows had only one possible shape and matched the limited -% number of vector slopes; -% \item for circles and inclined lines and vectors just two possible thicknesses +%^^A +% \item Vector arrows had only one possible shape and matched the limited +% number of vector slopes. +%^^A +% \item For circles and inclined lines and vectors just two possible thicknesses % were available. % \end{enumerate} % -% The package \texttt{pict2e} removes most if not all the above limitations: +% The package \texttt{pict2e} removes most if not all the above limitations. % \begin{enumerate} -% \item line and vector slopes are virtually unlimited; the only remaining +% \item Line and vector slopes are virtually unlimited; the only remaining % limitation is that the direction coefficients must be three-digit integer % numbers; they need not be relatively prime; with the 2009 upgrade even this % limitation was removed and now slope coefficients can be any fractional number % whose magnitude does not exceed 16\,384, the maximum dimension in points that -% \TeX\ can handle; -% \item filled and unfilled circles can be of any size; -% \item ovals can be designed with any specified corner curvature and there is +% \TeX\ can handle. +%^^A +% \item Filled and unfilled circles can be of any size. +%^^A +% \item Ovals can be designed with any specified corner curvature and there is % virtually no limitation to such curvatures; of course corner radii should not -% exceed half the lower value between the base and the height of the oval; -% \item there are two shapes for the arrow tips; the triangular one traditional +% exceed half the lower value between the base and the height of the oval. +%^^A +% \item There are two shapes for the arrow tips; the triangular one traditional % with \LaTeX\ vectors, or the arrow tip with PostScript style. -% \item the |\linethickness| command changes the thickness of all lines, straight, +%^^A +% \item The |\linethickness| command changes the thickness of all lines, straight, % curved, vertical, horizontal, arrow tipped, et cetera. % \end{enumerate} % -% This specific extension adds the following features +% This specific extension adds the following features. % \begin{enumerate} -% \item commands for setting the line terminations are introduced; the user can +%\item Most if not all coordinate pairs and slope pairs are treated as \emph{ordered pairs}, that is \emph{complex numbers}; in practice the user +% does not notice any difference from what he/she was used to, but all the +% mathematical treatment to be applied to these entities is coded as complex +% number operations, since complex numbers may be viewed non only as ordered +% pairs, but also as vectors or roto-amplification operators. +%^^A +% \item Commands for setting the line terminations are introduced; the user can % chose between square or rounded caps; the default is set to rounded caps (now -% available also with |pict2e|); -% \item commands for specifying the way two lines or curves join to one nanother; +% available also with |pict2e|). +%^^A +% \item Commands for specifying the way two lines or curves join to one another. % ^^A -% \item the |\line| macro is redefined so as to allow integer and fractional +% \item The |\line| macro is redefined so as to allow integer and fractional % direction coefficients, but maintaining the same syntax as in the original -% \texttt{picture} environment (now available also with |pict2e|); +% \texttt{picture} environment (now available also with |pict2e|). % ^^A -% \item a new macro |\Line| was defined so as to avoid the need to specify the +% \item A new macro |\Line| was defined so as to avoid the need to specify the % horizontal projection of inclined lines (now available also with |pict2e|); -% this conflicts with |pict2e| 2009 version; therefore its name is changed to -% |\LIne| and supposedly it will not be used very often, if ever used; +% this macro name now conflicts with |pict2e| 2009 version; therefore its name +% is changed to |\LIne| and supposedly it will not be used very often, if ever, +% by the end user (but it is used within this package macros). % ^^A -% \item a new macro |\LINE| was defined in order to join two points specified with +% \item A new macro |\LINE| was defined in order to join two points specified with % their coordinates; this is now the normal behavior of the |\Line| macro of -% |pict2e| so that |\LINE| is now renamed |\segment|; of course there is no need -% to use the |\put| command with this line specification; +% |pict2e| so that |\LINE| is now renamed |\segment|; there is no need +% to use the |\put| command with this line specification. +% ^^A +% \item A new macro |\DLine| is defined in order to draw dashed lines joining any +% two given points; the dash length and gap (equal to one another) get +% specified through one of the macro arguments. % ^^A -% \item a new macro |\DLine| is defined in order to draw dashed lines joining any -% two given points; the dash length and gap (equal to one another) must be -% specified; +% \item A new macro |\Dotline| is defined in order to draw dotted straight +% lines as a sequence of equally spaced dots, where the gap can be specified +% by the user; such straight line may have any inclination, as well as the +% above dashed lines. % ^^A -% \item similar macros are redefined for vectors; |\vector| redefines the +% \item Similar macros are redefined for vectors; |\vector| redefines the % original macro but with the vector slope limitations removed; |\Vector| gets -% specified with its two horizontal and vertical components; |\VECTOR| -% joins two specified points (without using the |\put| command) with the arrow -% pointing to the second point; -% \item a new macro |\polyline| for drawing polygonal lines is defined that +% specified with its two horizontal and vertical components in analogy with +% |\LIne|; |\VECTOR| joins two specified points (without using the |\put| +% command) with the arrow pointing to the second point. +%^^A +% \item A new macro |\polyline| for drawing polygonal lines is defined that % accepts from two vertices up to an arbitrary (reasonably limited) number of -% them (available now also in |pict2e|); here if is redefined so as to allow -% an optional specification of the way segments fo the polyline are join to -% one another.; -% \item a new macro |\Arc| is defined in order to draw an arc with arbitrary -% radius and arbitrary angle amplitude; this amplitude is specified in -% sexagesimal degrees, not in radians; the same functionality is now achieved with -% the |\arc| macro of |pict2e|, which provides also the strar version |\arc*| that -% fills up the interior of the generated circular arc. It must be noticed that -% the syntax is slighltly different, so that it's reasonable that both commands, -% in spite of producing identical arcs, might be more comfortable with this or -% that syntax. -% \item two new macros are defined in order to draw circular arcs with one -% arrow at one or both ends; -% \item a new macro |\Curve| is defined so as to draw arbitrary curved lines -% by means of third order Bézier splines; the |\Curve| macro requires only the -% curve nodes and the direction of the tangents at each node. +% them (available now also in |pict2e|); here it is redefined so as to allow +% an optional specification of the way segments for the polyline are joined to +% one another. +%^^A +% \item A new macro |\Arc| is defined in order to draw an arc with arbitrary +% radius and arbitrary aperture (angle amplitude); this amplitude is specified in +% sexagesimal degrees, not in radians; a similar functionality is now achieved +% with the |\arc| macro of |pict2e|, which provides also the starred version +% |\arc*| that fills up the interior of the generated circular arc. It must be +% noticed that the syntax is slightly different, so that it's reasonable that +% these commands, in spite of producing identical arcs, might be more comfortable +% with this or that syntax. +%^^A +% \item Two new macros |\VectorArc| and |\VectorARC| are defined in order to +% draw circular arcs with an +% arrow at one or both ends. +%^^A +% \item A new macro |\Curve| is defined so as to draw arbitrary curved lines +% by means of cubic Bézier splines; the |\Curve| macro requires only the +% curve nodes and the directions of the tangents at each node.The starred +% 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 +% 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 +% points of each arc; it is more difficult to use but it is more performant. +%^^A +% \item Last but not least, all these commands accept polar coordinates or +% cartesian ones at the choice of the user who may use for each object the +% formalism he/she prefers. Also the |put| and |\multiput| commands have been +% redefined so as to accept the cartesian or the polar coordinates. +%^^A +% \item The basic macros used within the cumulative |\Curve| macro can be +% used individually in order to draw any curve, one cubic arc at the time; +% but they are intended for internal use, even if it is not prohibited to use +% them; by themselves such arcs are not different form those used by |Curve|, +% but the final command, |\FillCurve|, should be used in place of +% |\CurveFinish|, so as to fill up the closed path with the locally +% specified color; see figure~\ref{fig:colored-curve}. It is much more +% convenient to use the starred version of |\Curve| macro. % \end{enumerate} % +% The |pict2e| package already defines macros such as |\moveto|, +% |\lineto|, |\curveto|, |\closepath|, |\fillpath|, and |\strokepath|; of +% course these macros can be used by the end user, and sometimes they perform +% better than the macros defined in this package, because the user has a better +% control on the position of the Bézier control points, while here the control +% points are sort of rigid. It would be very useful to resort to the |hobby| +% package, but its macros are conforming with those of the |tikz| and |pgf| +% packages, not with |curve2e|; an interface should be created in order to +% deal with the |hobby| package, but this has not yet been done. +% % In order to make the necessary calculations many macros have been defined so % as to use complex number arithmetics to manipulate point coordinates, -% directions (directional versors), rotations and the like. The trigonometric -% functions have also been defined in a way that the author believes to be -% more efficient than that implied by the \texttt{trig} package; in any case -% the macro names are sufficiently different to accommodate both definitions -% in the same \LaTeX\ run. +% directions (unit vectors, also known as `versors'), rotations and the like. +% The trigonometric functions have also been defined in a way that the author +% believes to be more efficient than those defined by the \texttt{trig} package; +% in any case the macro names are sufficiently different to accommodate both +% definition sets in the same \LaTeX\ run. % % Many aspects of this extension could be fine tuned for better performance; % many new commands could be defined in order to further extend this extension. % If the new service macros are accepted by other \TeX\ and \LaTeX\ programmers, -% this beta version could become the start for a real extension of the +% this version could become the start for a real extension of the % \texttt{pict2e} package or even become a part of it. Actually some macros -% have already been included in the \texttt{pict2e} package. Actually the -% \verb|\Curve| algorithm might be redefined so as to use the macros introduced -% in the \texttt{hobby} package, that implements for the typesetting engines -% the same functionalities that John Hobby wrote for \MF\ and \MP\ programs. +% have already been included in the \texttt{pict2e} package. The |\Curve| +% algorithm, as I said before, might be redefined so as to use the macros +% introduced in the \texttt{hobby} package, that implements for the |tikz| and +% |pgf| packages the same functionalities that John Hobby implemented for the +% \MF\ and \MP\ programs. % -% For this reason I suppose that every enhancement should be submitted to -% Gäßlein and Niepraschk who are the prime maintainers of \texttt{pict2e}; -% they only can decide whether or not to incorporate new macros in their package. +% For these reasons I suppose that every enhancement should be submitted to +% Gäßlein, Niepraschk, and Tkadlec who are the prime maintainers of +% \texttt{pict2e}; they are the only ones who can decide whether or not to +% incorporate new macros in their package. % % \section{Summary of modifications and new commands} % This package \texttt{curve2e} extends the power of \texttt{pict2e} with the % following modifications and the following new commands. % \begin{enumerate} % \item This package |curve2e| calls directly the \LaTeX\ packages |color| and -% |pict2e| to whom it passes any possible option that the latter can receive; +% |pict2e| to which it passes any possible option that the latter can receive; % actually the only options that make sense are those concerning the arrow tips, % either \LaTeX\ or PostScript styled, because it is assumed that if you use this % package you are not interested in using the original \LaTeX\ commands. See the % |pict2e| documentation in order to use the correct options |pict2e| can receive. +%^^A % \item The user is offered new commands in order to control the line terminators % and the line joins; specifically: % \begin{itemize} @@ -247,11 +320,12 @@ and the derived files curve2e.sty and curve2e.pdf. % All the above commands should respect the intended range; but since they act at % the PostScript or PDF level, not at \TeX\ level, it might be necessary to issue % the necessary command in order to restore the previous terminator or join. +%^^A % \item The commands |\linethickness|, |\thicklines|, |\thinlines| together with % |\defaultlinethickness| always redefine the internal |\@wholewidth| and % |\@halfwidth| so that the latter always refer to a full width and to a half of % it in this way: if you issue the command |\defaultlinewidth{2pt}| all thin -% lines will be drawn with a thickeness of 1\,pt while if a drawing command +% lines will be drawn with a thickness of 1\,pt while if a drawing command % directly refers to the internal value |\@wholewidth|, its line will be drawn % with a thickness of 2\,pt. % If one issues the declaration |\thinlines| all lines will be drawn with a 1\,pt @@ -268,47 +342,50 @@ and the derived files curve2e.sty and curve2e.pdf. % \end{flushleft} % where \meta{dimensioned value} means a length specification complete of its % units or a dimensional expression. +%^^A % \item Straight lines and vectors are redefined in such a way that fractional % slope coefficients may be specified; the zero length line does not produce % errors and is ignored; the zero length vectors draw only the arrow tips. +%^^A % \item New line and vector macros are defined that avoid the necessity of -% specifying the horizontal component |\put(3,4){\LIne(25,15)}| specifies a +% specifying the horizontal component; |\put(3,4){\LIne(25,15)}| specifies a % segment that starts at point $(3,4)$ and goes to point $(3+25,4+15)$; the % command |\segment(3,4)(28,19)| achieves the same result without the need of -% the using command |\put|. +% 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 % particularly useful. +%^^A % \item The |\polyline| command has been introduced: it accepts an unlimited % list of point coordinates enclosed within round parentheses; the command -% draws a sequence of connected segments that joins in sequence the specified +% draws a sequence of connected segments that joins in order the specified % points; the syntax is: % \begin{flushleft} -% \cs{polyline[}\marg{optional join style}\texttt{](}\meta{$P_1$}\texttt{)(}% -% \meta{$P_2$}\texttt{)...(}\meta{$P_n$}\texttt{)} +%\cs{polyline}\texttt{[}\marg{optional join style}\texttt{]% +%(}\meta{$P_1$}\texttt{)(}\meta{$P_2$}\texttt{)...(}\meta{$P_n$}\texttt{)} % \end{flushleft} -% See figure~\ref{fig:polyline} where a pentagon is designed.. +% See figure~\ref{fig:polyline} where a regular pentagon is drawn; usage of polar +% coordinates is also shown. % % \begin{figure}[!ht] % \begin{minipage}{.48\linewidth} % \begin{verbatim} % \unitlength=.5mm -% \begin{picture}(40,32)(-20,0) -% \polyline(0,0)(19.0211,13,8197)(11.7557,36.1803)% -% (-11.7557,36.1803)(-19.0211,13,8197)(0,0) +% \begin{picture}(40,32)(-20,-20) +% \polyline(90:20)(162:20)(234:20)(306:20)(378:20)(90:20) % \end{picture} % \end{verbatim} % \end{minipage} % \hfill % \begin{minipage}{.48\linewidth}\raggedleft % \unitlength=.5mm -% \begin{picture}(40,32)(-20,0) -% \polyline(0,0)(19.0211,13,8197)(11.7557,36.1803)% -% (-11.7557,36.1803)(-19.0211,13,8197)(0,0) +% \begin{picture}(40,32)(-20,-20) +% \polyline(90:20)(162:20)(234:20)(306:20)(378:20)(90:20) % \end{picture}\hspace*{2em} % \end{minipage} % \caption{Polygonal line obtained by means of the \texttt{\string\polyline} -% command} \label{fig:polyline} +% command; coordinates are in polar form.} +% \label{fig:polyline} % \end{figure} % % Although you can draw polygons with |\polyline|, as it was done in @@ -317,9 +394,10 @@ and the derived files curve2e.sty and curve2e.pdf. % last specified coordinate to the first one with a straight line, therefore % closing the path. |pict2e| defines also the starred command that fills up % the inside of the generated polygon. -% \item The new command +%^^A +% \item The new command |\Dashline| (alias: |\Dline| for backwards compatibility) % \begin{flushleft} -% |\Dline(|\textit{first point}|)(|\textit{second point}|)(|\textit{dash length}|)| +% |\Dashline(|\meta{first point}|)(|\meta{second point}|){|\meta{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 @@ -333,59 +411,70 @@ and the derived files curve2e.sty and curve2e.pdf. % \begin{figure}[!ht] % \begin{minipage}{.48\textwidth} % \begin{verbatim} -% \unitlength.5mm +% \unitlength=1mm % \begin{picture}(40,40) % \put(0,0){\GraphGrid(40,40)} -% \Dline(0,0)(40,10){4} +% \Dashline(0,0)(40,10){4} % \put(0,0){\circle*{2}} -% \Dline(40,10)(0,25){4} +% \Dashline(40,10)(0,25){4} % \put(40,10){\circle*{2}} -% \Dline(0,25)(20,40){4} +% \Dashline(0,25)(20,40){4} % \put(0,25){\circle*{2}} % \put(20,40){\circle*{2}} +% \Dotline(0,0)(40,40){2} % \end{picture} % \end{verbatim} % \end{minipage} % \hfill % \begin{minipage}{.48\textwidth}\centering -% \unitlength.5mm +% \unitlength=1mm % \begin{picture}(40,40) % \put(0,0){\GraphGrid(40,40)} -% \Dline(0,0)(40,10){4} +% \Dashline(0,0)(40,10){4} % \put(0,0){\circle*{2}} -% \Dline(40,10)(0,25){4} +% \Dashline(40,10)(0,25){4} % \put(40,10){\circle*{2}} -% \Dline(0,25)(20,40){4} +% \Dashline(0,25)(20,40){4} % \put(0,25){\circle*{2}} % \put(20,40){\circle*{2}} +% \Dotline(0,0)(40,40){2} % \end{picture} % \end{minipage} % \caption{Dashed lines and graph grid}\label{fig:dashline} % \end{figure} -% \item |\GraphGrid| is a command that draws a red grid over the drawing area -% with lines separated |10\unitlength|s; it is described only with a comma +%^^A +%\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}|}| +% \end{flushleft} +% See figures~\ref{fig:dashline} and~\ref{fig:dottedlines} for examples. +%^^A +% \item |\GraphGrid| is a command that draws a red grid under the drawing +% with lines separated |10\unitlength|s apart; it is described only with a comma % separated couple of numbers, representing the base and the height of the grid, % see figure~\ref{fig:dashline}; it's better to specify multiples of ten and -% the grid can be placed anywhere in the drawing plane by means of |\put|, -% whose coordinates are multiples of 10; nevertheless the grid line distance is -% rounded to the nearest multiple of 10, while the point coordinates specified -% to |\put| are not rounded at all; therefore some care should be used to place -% the working grid in the drawing plane. This grid is intended as an aid in -% drawing; even if you sketch your drawing on millimetre paper, the drawing grid -% turns out to be very useful; one must only delete or comment out the command -% when the drawing is finished. +% the grid can be placed anywhere in the drawing canvas by means of |\put|, +% whose cartesian coordinates are multiples of 10; nevertheless the grid line +% distance is rounded to the nearest multiple of 10, while the point coordinates +% specified to |\put| are not rounded at all; therefore some care should be used +% to place the working grid in the drawing canvas. This grid is intended as an +% aid while drawing; even if you sketch your drawing on millimetre paper, the +% drawing grid turns out to be very useful; one must only delete or comment out +% the command when the drawing is finished. +%^^A % \item New trigonometric function macros have been implemented; possibly they % are not better than the corresponding macros of the |trig| package, but they % are supposed to be more accurate at least they were intended to be so. The % other difference is that angles are specified in sexagesimal degrees -% ($360^\circ$ to one revolution), so that reduction to the fundamental quadrant -% is supposed to be more accurate; the tangent of odd multiples of $90^\circ$ +% (360° to one revolution), so that reduction to the fundamental quadrant +% is supposed to be more accurate; the tangent of odd multiples of 90° % are approximated with a ``\TeX\ infinity'', that is the signed value % 16383.99999. This will possibly produce computational errors in the % subsequent calculations, but at least it does not stop the tangent % computation. In order to avoid overflows or underflows in the computation % of small angles (reduced to the first quadrant), the sine and the tangent -% of angles smaller than $1^\circ$ are approximated by the first term of the +% of angles smaller than 1° are approximated by the first term of the % McLaurin series, while for the cosine the approximation is given by the first % two terms of the McLaurin series. In both cases theoretical errors are smaller % than what \TeX\ arithmetics can handle. @@ -399,13 +488,18 @@ and the derived files curve2e.sty and curve2e.pdf. %\\ % \texttt{\char92TanOf}\meta{angle}\texttt{to}\meta{control sequence} %\end{flushleft} -% The \meta{control sequence} may then be used as a multiplying factor of a length. +% The \meta{control sequence} may then be used as a multiplying factor of a +% length. +%^^A % \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}\\ +% \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}\\ %\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 @@ -440,6 +534,7 @@ and the derived files curve2e.sty and curve2e.pdf. % \end{minipage} % \caption{Arcs and curved vectors}\label{fig:arcs} % \end{figure} +%^^A % \item A multitude of commands have been defined in order to manage complex % numbers; actually complex numbers are represented as a comma separated pair of % fractional numbers. They are used to address to specific points in the drawing @@ -460,7 +555,7 @@ and the derived files curve2e.sty and curve2e.pdf. % \item |\ModOfVect|\meta{vector}|to|\meta{macro} % \item |\DirOfvect|\meta{vector}|to|\meta{versor macro} % \item |\ModAndDirOfVect|\meta{vector}|to|\meta{1st macro}|and|\meta{2nd macro} -% \item |\DistanceAndDirOfVect|\meta{first vector}|minus|\meta{second vector}|to|\meta{1st macro}|and|\meta{2nd macro} +% \item |\DistanceAndDirOfVect|\meta{1st vector}|minus|\meta{2nd vector}|to|\meta{1st macro}|and|\meta{2nd macro} % \item |\XpartOfVect|\meta{vector}|to|\meta{macro} % \item |\YpartOfVect|\meta{vector}|to|\meta{macro} % \item |\DirFromAngle|\meta{angle}|to|\meta{versor macro} @@ -473,9 +568,9 @@ and the derived files curve2e.sty and curve2e.pdf. % \item |\MultVect|\meta{first vector}|by*|\meta{second vector}|to|\meta{vector macro} % \item |\DivVect|\meta{first vector}|by|\meta{second vector}|to|\meta{vector macro} % \end{itemize}} -% +%^^A % \item General curves can be drawn with the |pict2e| macro |\curve| but it -% requires the specification of the Bézier third order spline control points; +% requires the specification of the third-order Bézier-spline control points; % sometimes it's better to be very specific with the control points and there % is no other means to do a decent graph; sometimes the curves to be drawn % are not so tricky and a general set of macros can be defined so as to compute @@ -500,15 +595,15 @@ and the derived files curve2e.sty and curve2e.pdf. % can be done with other programs, as for example with \MF\ or the |pgf/tikz| % package and environment. See figure~\ref{fig:curve} for an example. % \end{enumerate} -% \begin{figure} +% \begin{figure}[htb] % \begin{minipage}{.48\textwidth} % \begin{verbatim} -% \unitlength=8mm +% \unitlength=8mm\relax % \begin{picture}(5,5) % \put(0,0){\framebox(5,5){}}\thicklines\roundcap % \Curve(2.5,0)<1,1>(5,3.5)<0,1>% -% (2.5,3.5)<-.5,-1.2>[-.5,1.2]% -% (0,3.5)<0,-1>(2.5,0)<1,-1> +% (4,5)<-1,0>(2.5,3.5)<-.5,-1.2>[-.5,1.2]% +% (1,5)<-1,0>(0,3.5)<0,-1>(2.5,0)<1,-1> % \end{picture} % \end{verbatim} % \end{minipage} @@ -517,29 +612,61 @@ and the derived files curve2e.sty and curve2e.pdf. % \unitlength=8mm\relax % \begin{picture}(5,5) % \put(0,0.5){\put(0,0){\framebox(5,5){}}\thicklines\roundcap -% \Curve(2.5,0)<1,1>(5,3.5)<0,1>(2.5,3.5)<-0.5,-1.2>[-0.5,1.2](0,3.5)<0,-1>(2.5,0)<1,-1>} +% \Curve(2.5,0)<1,1>(5,3.5)<0,1>(4,5)<-1,0>(2.5,3.5)<-0.5,-1.2>[-0.5,1.2](1,5)<-1,0>(0,3.5)<0,-1>(2.5,0)<1,-1>} % \end{picture} % \end{minipage} % \caption{A heart shaped curve with cusps drawn with \texttt{\string\Curve}} % \label{fig:curve} + +%\vspace*{2\baselineskip} +% +% \begin{minipage}{.48\textwidth} +% \begin{verbatim} +% \unitlength=8mm\relax +% \begin{picture}(5,5) +% \put(0,0){\framebox(5,5){}}\thicklines\roundcap +% \color{green}\relax +% \Curve*(2.5,0)<1,1>(5,3.5)<0,1>% +% (4,5)<-1,0>(2.5,3.5)<-.5,-1.2>[-.5,1.2]% +% (1,5)<-1,0>(0,3.5)<0,-1>(2.5,0)<1,-1> +% \end{picture} +% \end{verbatim} +% \end{minipage} +% \hfill +% \begin{minipage}{.48\textwidth}\raggedleft\relax +% \unitlength=8mm\relax +% \begin{picture}(5,5) +% \put(0,0.5){\put(0,0){\framebox(5,5){}}\thicklines\roundcap +% \color{green}\relax +% \Curve*(2.5,0)<1,1>(5,3.5)<0,1>(4,5)<-1,0>(2.5,3.5)<-0.5,-1.2>[-0.5,1.2](1,5)<-1,0>(0,3.5)<0,-1>(2.5,0)<1,-1>} +% \end{picture} +% \end{minipage} +%\caption{Coloring the inside of a closeded path drawn with \texttt{\string\Curve*}} +%\label{fig:colored-curve} + % \end{figure} % -% In spite of the relative simplicity of the macros contained in this package, the -% described macros, as well as the original macros included in the |pict2e| package, -% allow to produce fine drawings that were inconceivable of with the original \LaTeX\ -% picture environment. Leslie Lamport himself announced an extension to his -% environment when \LaTeXe\ was first issued in 1994; in the |latexnews| news letter -% of December 2003; the first implementation appeared; the first version of this -% package was issued in 2006. It was time to have a better drawing environment; this -% package is a simple attempt to follow the initial path while extending the drawing -% facilities; but Till Tantau's |pgf| package has gone much farther. +% With the starred version of |\Curve|, instead of stroking the contour, +% the macro fills up the contour with the selected current color, +% figure~\ref{fig:colored-curve}. +% +% In spite of the relative simplicity of the macros contained in this package, +% the described macros, as well as the original ones included in the |pict2e| +% package, allow to produce fine drawings that were unconceivable with the +% original \LaTeX\ picture environment. Leslie Lamport himself announced an +% extension to his environment when \LaTeXe\ was first issued in 1994; in the +% |latexnews| news letter of December 2003; the first implementation announced; +% the first version of this package was issued in 2006. It was time to have a +% better drawing environment; this package is a simple attempt to follow the +% initial path while extending the drawing facilities; but Till Tantau's |pgf| +% package has gone much farther. % % \section{Remark} % There are other packages in the \textsc{ctan} archives that deal with tracing % curves of various kinds. |PSTricks| and |tikz/pgf| are the most powerful ones. -% But there are also the package |curves| that is intended to draw almost +% But there is also the package |curves| that is intended to draw almost % anything by using little dots or other symbols partially superimposed to one -% another. It used only quadratic Bézier curves and the curve tracing is eased +% another. It uses only quadratic Bézier curves and the curve tracing is eased % by specifying only the curve nodes, without specifying the control nodes; % with a suitable option to the package call it is possible to reduce the % memory usage by using short straight segments drawn with the PostScript @@ -551,6 +678,23 @@ and the derived files curve2e.sty and curve2e.pdf. % exactly are the Bézier splines, it appears that |ebezier| should be used only % for dvi output without recourse to PostScript machinery. % +% The |picture| package extends the performance of the |picture| environment +% (extended with \texttt{pict2e}) by accepting coordinates and lengths in real +% absolute dimensions, not only as multiples of |\unitlength|; it provides +% commands to extend that functionality to other packages. In certain +% circumstances it is very useful. +% +% Package \texttt{xpicture} builds over the |picture| \LaTeX\ environment so +% as to allow to draw the usual curves that are part of an introductory +% analytic geometry course; lines, circles, parabolas, ellipses, hyperbolas, and +% polynomials; the syntax is very comfortable; for all these curves it uses +% the quadratic Bézier splines. +% +% Package |hobby| extends the cubic Bézier spline handling with the algorithms +% John Hobby created for \MF\ and \MP. But by now this package interfaces very +% well with |tikz|; it has not (yet) been adapted to the common |picture| +% environment, even extended with |pict2e|, and, why not, with |curve2e|. +% % \section{Acknowledgements} % I wish to express my deepest thanks to Michel Goosens who spotted some errors % and very kindly submitted them to me so that I was able to correct them. @@ -585,12 +729,15 @@ and the derived files curve2e.sty and curve2e.pdf. % The necessary preliminary code has already been introduced. Here we require % the \texttt{color} package and the \texttt{pict2e} one; for the latter one we % make sure that a sufficiently recent version is used. +%\iffalse +%<*package> +%\fi % \begin{macrocode} \RequirePackage{color} \RequirePackageWithOptions{pict2e}[2014/01/01] % \end{macrocode} % -% The next macros are just for debugging. With the \texttt{tracing} package it +% The next macros are just for debugging. With the \texttt{trace} package it % would probably be better to define other macros, but this is not for the % users, but for the developers. % \begin{macrocode} @@ -612,6 +759,7 @@ and the derived files curve2e.sty and curve2e.pdf. \ifx\undefined\defaultlinewidth \newdimen\defaultlinewidth \fi % \end{macrocode} % +% \subsection{Line thickness macros} % It is better to define a macro for setting a different value for the line and % curve thicknesses; the `|\defaultlinewidth| should contain the % equivalent of |\@wholewidth|, that is the thickness of thick lines; thin lines @@ -635,20 +783,21 @@ and the derived files curve2e.sty and curve2e.pdf. % these spaces introduce picture deformities often difficult to spot and % eliminate. % -% \subsubsection{Improved line and vector macros} +% \subsection{Improved line and vector macros} % The new macro |\LIne| allows to draw an arbitrary inclination line as if it % was a polygonal with just two vertices. This line should be set by means of a % |\put| command so that its starting point is always at a relative 0,0 -% coordinate point. The two arguments define the horizontal and the -% vertical component respectively. +% coordinate point inside the box created with |\put|. The two arguments +% define the horizontal and the vertical component respectively. % \begin{macrocode} -\def\LIne(#1,#2){\moveto(0,0) - \pIIe@lineto{#1\unitlength}{#2\unitlength}\strokepath}% +\def\LIne(#1){{\GetCoord(#1)\@tX\@tY + \moveto(0,0) + \pIIe@lineto{\@tX\unitlength}{\@tY\unitlength}\strokepath}\ignorespaces}% % \end{macrocode} % % A similar macro |\segment| operates between two explicit points with absolute % coordinates, instead of relative to the position specified by a |\put| -% command; it resorts to the |\polyline| macro that is to be defined in a while. +% command; it resorts to the |\polyline| macro that shall be defined in a while. % The |\@killglue| command might be unnecessary, but it does not harm; it % eliminates any explicit or implicit spacing that might precede this command. % \begin{macrocode} @@ -660,8 +809,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 the ISO regulations allow the decimal point -% only for English speaking countries, while in all other countries 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 @@ -715,35 +863,59 @@ and the derived files curve2e.sty and curve2e.pdf. % \end{macrocode} % The new definition of the command |\line|, besides the ease with which is % readable, does not do different things from the definition of |pict2e| 2009, but -% it did preform in a better way whith the 2004 version that was limited to +% it did preform in a better way with the 2004 version that was limited to % integer direction coefficients up to 999 in magnitude. % -% Another useful line-type macro creates a dashed line between two given points -% with a dash length that must be specified; actually the specified dash length -% is a desired dash length; the actual length is computed by integer division -% between the distance of the given points and the desired dash length; this -% integer is tested in order to see if it's odd; if it's not, it is increased by -% one. Then the actual dash length is obtained by dividing the above distance by -% this odd number. -% Another vector is created from $P_1-P_0$ by dividing it by the magic odd number; -% then it is multiplied by two in order to have the increment from one dash to the -% next, and finally the number of patterns is obtained by integer dividing the -% magic odd number by 2 and increasing it by 1. A simple |\multiput| completes the -% job, but in order to use the various vectors and numbers within a group and to -% throw the result outside the group while restoring all the intermediate counters -% and registers, a service macro is created with an expanded definition and then -% this service macro is executed. -% \begin{macrocode} -\ifx\Dline\undefined -\def\Dline(#1,#2)(#3,#4)#5{% -\begingroup - \countdef\NumA254\countdef\NumB252\relax - \MakeVectorFrom{#1}{#2}to\V@ttA - \MakeVectorFrom{#3}{#4}to\V@ttB +% \subsection{Dashed and dotted lines} +% Dashed and dotted lines are very useful in technical drawings; here we +% introduce four macros that help drawing them in the proper way; besides +% the obvious difference between the use of dashes or dots, they may refer +% in a different way to the end points that must be specified to the various +% macros. +% +% The coordinates of the first point $P_1$, where le line starts, are always +% referred to the origin of the coordinate axes; the end point $P_2$ +% coordinates with the first macro type are referred to the origin of the +% axes, while with the second macro type they are referred to $P_1$; both +% macro types have their usefulness and figures~\ref{fig:dashedlines} +% and~\ref{fig:dottedlines} show how to use these macro types. +% +% We distinguish these macro types with an asterisk; the unstarred version is +% the first macro type, while the starred one refers to the second macro type. +% +% The above mentioned macros create dashed lines between two given +% points, with a dash length that must be specified, or dotted lines, with a +% dot gap that can be specified; actually the specified dash length or dot gap +% is a desired one; the actual length or gap is computed by integer division +% between the distance of the given points and the desired dash length or dot +% gap; when dashes are involved,this integer is tested in order to see if it +% is an odd number; if it's not, it is increased by one. Then the actual +% dash length or dot gap is obtained by dividing the above distance by this +% number. +% +% Another vector $P_2-P_1$ is created by dividing it by this number; +% then, when dashes are involved, it is multiplied by two in order to have +% the increment from one dash to the next; finally the number of patterns +% is obtained by integer division of this number by 2 and increasing it by 1. +% A simple |\multiput| completes the job, but in order to use the various +% vectors and numbers within a group and to throw the result outside the group +% while restoring all the intermediate counters and registers, a service macro +% is created with an expanded definition and then this service macro is executed. +% Figure~\ref{fig:dashedlines} shows the effect of the slight changing +% of the dash length in order to maintain approximately the same dash-space +% pattern along the line, irrespective o the line length. +% \begin{macrocode} +\ifx\Dashline\undefined +\def\Dashline{\@ifstar{\Dashline@@}{\Dashline@}} +\def\Dashline@(#1)(#2)#3{% +\bgroup + \countdef\NumA3254\countdef\NumB3252\relax + \GetCoord(#1)\@tA\@tB \MakeVectorFrom\@tA\@tB to\V@ttA + \GetCoord(#2)\@tA\@tB \MakeVectorFrom\@tA\@tB to\V@ttB \SubVect\V@ttA from\V@ttB to\V@ttC \ModOfVect\V@ttC to\DlineMod - \DividE\DlineMod\p@ by#5\p@ to\NumD - \NumA\expandafter\Integer\NumD?? + \DivideFN\DlineMod by#3 to\NumD + \NumA\expandafter\Integer\NumD.?? \ifodd\NumA\else\advance\NumA\@ne\fi \NumB=\NumA \divide\NumB\tw@ \DividE\DlineMod\p@ by\NumA\p@ to\D@shMod @@ -751,23 +923,206 @@ and the derived files curve2e.sty and curve2e.pdf. \MultVect\V@ttC by\@tempa,0 to\V@ttB \MultVect\V@ttB by 2,0 to\V@ttC \advance\NumB\@ne - \edef\@mpt{\noexpand\endgroup - \noexpand\multiput(\V@ttA)(\V@ttC){\number\NumB}{\noexpand\LIne(\V@ttB)}}% + \edef\@mpt{\noexpand\egroup + \noexpand\multiput(\V@ttA)(\V@ttC){\number\NumB}% + {\noexpand\LIne(\V@ttB)}}% \@mpt\ignorespaces}% +\let\Dline\Dashline + +\def\Dashline@@(#1)(#2)#3{\put(#1){\Dashline@(0,0)(#2){#3}}} \fi % \end{macrocode} % +%\begin{figure}\unitlength=0.007\textwidth +%\begin{minipage}{0.55\textwidth} +%\begin{verbatim} +%\begin{picture}(40,30) +%\put(0,0){\GraphGrid(40,30)} +%\Dashline(0,0)(40,10){2}\Dashline(0,0)(40,20){2} +%\Dashline(0,0)(40,30){2}\Dashline(0,0)(30,30){2} +%\Dashline(0,0)(20,30){2}\Dashline(0,0)(10,30){2} +%{\color{red}\Dashline*(40,0)(108:30){2} +%\Dashline*(40,0)(126:30){2} +%\Dashline*(40,0)(144:30){2} +%\Dashline*(40,0)(162:30){2}} +%\end{picture} +%\end{verbatim} +%\end{minipage} +%\hfill +%\begin{minipage}{0.4\textwidth}\raggedleft +%\begin{picture}(40,30) +%\put(0,0){\GraphGrid(40,30)} +%\Dashline(0,0)(40,10){2} +%\Dashline(0,0)(40,20){2} +%\Dashline(0,0)(40,30){2} +%\Dashline(0,0)(30,30){2} +%\Dashline(0,0)(20,30){2} +%\Dashline(0,0)(10,30){2} +%{\color{red}\Dashline*(40,0)(108:30){2} +%\Dashline*(40,0)(126:30){2} +%\Dashline*(40,0)(144:30){2} +%\Dashline*(40,0)(162:30){2}}% +%\end{picture} +%\end{minipage} +%\caption{Different length dashed lines with the same nominal dash length} +%\label{fig:dashedlines} +%\end{figure} +% +% A simpler |\Dotline| macro can draw a dotted line between to 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 +% the sense that it is recalculated in such a way that the first and last +% dots coincide with the line end points. The syntax is as follows: +%\begin{flushleft} +%\cs{Dotline}\texttt{(}\meta{start point}\texttt{)(}\meta{end point}\texttt{)\{}\meta{dot distance}\texttt{\}} +%\end{flushleft} +% \begin{macrocode} +\ifx\Dotline\undefined +\def\Dotline{\@ifstar{\Dotline@@}{\Dotline@}} +\def\Dotline@(#1)(#2)#3{% +\bgroup + \countdef\NumA 3254\relax \countdef\NumB 3255\relax + \GetCoord(#1)\@tA\@tB \MakeVectorFrom\@tA\@tB to\V@ttA + \GetCoord(#2)\@tA\@tB \MakeVectorFrom\@tA\@tB to\V@ttB + \SubVect\V@ttA from\V@ttB to\V@ttC + \ModOfVect\V@ttC to\DotlineMod + \DivideFN\DotlineMod by#3 to\NumD + \NumA=\expandafter\Integer\NumD.?? + \DivVect\V@ttC by\NumA,0 to\V@ttB + \advance\NumA\@ne + \edef\@mpt{\noexpand\egroup + \noexpand\multiput(\V@ttA)(\V@ttB){\number\NumA}% + {\noexpand\makebox(0,0){\noexpand\circle*{0.5}}}}% + \@mpt\ignorespaces}% + +\def\Dotline@@(#1)(#2)#3{\put(#1){\Dotline@(0,0)(#2){#3}}} +\fi +% \end{macrocode} +% +%\begin{figure}[htb]\unitlength=0.007\textwidth +%\begin{minipage}{0.55\textwidth} +%\begin{verbatim} +%\begin{picture}(40,30) +%\put(0,0){\GraphGrid(40,30)} +%\Dotline(0,0)(40,10){1.5}\Dotline(0,0)(40,20){1.5} +%\Dotline(0,0)(40,30){1.5}\Dotline(0,0)(30,30){1.5} +%\Dotline(0,0)(20,30){1.5}\Dotline(0,0)(10,30){1.5} +%{\color{red}\Dotline*(40,0)(108:30){1.5} +%\Dotline*(40,0)(126:30){1.5} +%\Dotline*(40,0)(144:30){1.5} +%\Dotline*(40,0)(162:30){1.5}}% +%\end{picture} +%\end{verbatim} +%\end{minipage} +%\hfill +%\begin{minipage}{0.4\textwidth}\raggedleft +%\begin{picture}(40,30) +%\put(0,0){\GraphGrid(40,30)} +%\Dotline(0,0)(40,10){1.5} +%\Dotline(0,0)(40,20){1.5} +%\Dotline(0,0)(40,30){1.5} +%\Dotline(0,0)(30,30){1.5} +%\Dotline(0,0)(20,30){1.5} +%\Dotline(0,0)(10,30){1.5} +%{\color{red}% +%\Dotline*(40,0)(108:30){1.5} +%\Dotline*(40,0)(126:30){1.5} +%\Dotline*(40,0)(144:30){1.5} +%\Dotline*(40,0)(162:30){1.5}}% +%\end{picture} +%\end{minipage} +%\caption{Different length dotted lines with the same nominal dot gap} +%\label{fig:dottedlines} +%\end{figure} +% +% Notice that vectors as complex numbers in their cartesian and polar forms +% always represent a point position referred to the origin of the axes; this is +% why in figures~\ref{fig:dashedlines} and~\ref{fig:dottedlines} the dashed +% and dotted line that depart from the lower right corner of the graph grid, +% and that use polar coordinates, have to be put at the proper position with +% the starred version of the commands that take care of the relative +% specification made with the polar coordinates. +% +% \subsection{Coordinate handling} % The new macro |\GetCoord| splits a vector (or complex number) specification -% into its components: +% into its components; in particular it distinguishes the polar from the +% cartesian form of the coordinates. The latter have the usual syntax +% \meta{x\texttt{,}y}, while the former have the syntax +% \meta{angle\texttt{:}radius}. The |\put| command is redefined to accept +% the same syntax; the whole work is done by |\SplitNod@| +% and its subsidiaries. % \begin{macrocode} \def\GetCoord(#1)#2#3{% \expandafter\SplitNod@\expandafter(#1)#2#3\ignorespaces} % \end{macrocode} -% But the macro that does the real work is |\SplitNod@|: +% But the macro that detects the form of the coordinates is |\isnot@polar|, +% that examines the parameter syntax in order to see if it contains a colon; +% if it does the coordinates are in polar form, otherwise they are in cartesian +% form: % \begin{macrocode} -\def\SplitNod@(#1,#2)#3#4{\edef#3{#1}\edef#4{#2}}% -% \end{macrocode} +\def\isnot@polar#1:#2!!{\def\@tempOne{#2}\ifx\@tempOne\empty +\expandafter\@firstoftwo\else +\expandafter\@secondoftwo\fi +{\SplitNod@@}{\SplitPolar@@}} + +\def\SplitNod@(#1)#2#3{\isnot@polar#1:!!(#1)#2#3}% +\def\SplitNod@@(#1,#2)#3#4{\edef#3{#1}\edef#4{#2}}% +\def\SplitPolar@@(#1:#2)#3#4{\DirFromAngle#1to\@DirA +\ScaleVect\@DirA by#2to\@DirA +\expandafter\SplitNod@@\expandafter(\@DirA)#3#4} + +\let\originalput\put +\def\put(#1){\bgroup\GetCoord(#1)\@tX\@tY +\edef\x{\noexpand\egroup\noexpand\originalput(\@tX,\@tY)}\x} + +\let\originalmultiput\multiput +\let\original@multiput\@multiput + +\long\def\@multiput(#1)#2#3{\bgroup\GetCoord(#1)\@mptX\@mptY +\edef\x{\noexpand\egroup\noexpand\original@multiput(\@mptX,\@mptY)}% +\x{#2}{#3}\ignorespaces} + +\gdef\multiput(#1)#2{\bgroup\GetCoord(#1)\@mptX\@mptY +\edef\x{\noexpand\egroup\noexpand\originalmultiput(\@mptX,\@mptY)}\x(}%) +% \end{macrocode} +% Examples of using polar and cartesian coordinates are shown in +% figure~\ref{fig:polar}. +% +%\begin{figure}[htb]\unitlength=0.01\textwidth +%\begin{minipage}{0.55\textwidth} +%\begin{verbatim} +%\begin{picture}(40,30) +%\put(0,0){\GraphGrid(40,30)} +%\put(40,0){\circle*{1.5}} +% \put(41,0){\makebox(0,0)[bl]{40,0}} +%\put(90:30){\circle*{1.5}} +% \put(90:31){\makebox(0,0)[bl]{90:30}} +%\put(60:30){\circle*{1.5}} +% \put(60:31){\makebox(0,0)[bl]{60:30}} +%\put(30,30){\circle*{1.5}} +% \put(30.7,30.7){\makebox(0,0)[bl]{30,30}} +%\multiput(0,0)(30:10){5}% +% {\makebox(0,0){\rule{1.5mm}{1.5mm}}} +%\end{picture} +%\end{verbatim} +%\end{minipage} +%\hfill +%\begin{minipage}{0.4\textwidth} +%\begin{picture}(40,30) +%\put(0,0){\GraphGrid(40,30)} +%\put(40,0){\circle*{1.5}}\put(41,0){\makebox(0,0)[bl]{40,0}} +%\put(90:30){\circle*{1.5}}\put(90:31){\makebox(0,0)[bl]{90:30}} +%\put(60:30){\circle*{1.5}}\put(60:31){\makebox(0,0)[bl]{60:30}} +%\put(30,30){\circle*{1.5}}\put(30.7,30.7){\makebox(0,0)[bl]{30,30}} +%\multiput(0,0)(30:10){5}{\makebox(0,0){\rule{1.5mm}{1.5mm}}} +%\end{picture} +%\end{minipage} +%\caption{Use of cartesian and polar coordinates} +%\label{fig:polar} +%\end{figure} % +% \subsection{Vectors} % The redefinitions and the new definitions for vectors are a little more % complicated than with segments, because each vector is drawn as a filled % contour; the original \texttt{pict2e} 2004 macro checks if the slopes are @@ -780,10 +1135,10 @@ and the derived files curve2e.sty and curve2e.pdf. % contours that are eventually filled by the principal macro; each contour % macro draws the vector with a \LaTeX\ or a PostScript arrow whose parameters % are specified by default or may be taken from the parameters taken from the -%\texttt{PSTricks} package if this one is loaded before \texttt{pict2e}; in any +%|PSTricks| package if this one is loaded before |pict2e|; in any % case we did not change the contour drawing macros because if they are % modified the same modification is passed on to the arrows drawn with the -% \texttt{curve2e} package redefinitions. +% |curve2e| package redefinitions. % % Because of these features the redefinitions and the new macros are different % from those used for straight lines. @@ -876,15 +1231,17 @@ and the derived files curve2e.sty and curve2e.pdf. % vertical vector components. If the horizontal component is zero, the actual % length% must be specified as the vertical component. % \begin{macrocode} -\def\Vector(#1,#2){% -\ifdim#1\p@=\z@\vector(#1,#2){#2} +\def\Vector(#1){{% +\GetCoord(#1)\@tX\@tY +\ifdim\@tX\p@=\z@\vector(\@tX,\@tY){\@tY} \else -\vector(#1,#2){#1}\fi} +\vector(\@tX,\@tY){\@tX}\fi}} % \end{macrocode} % % On the opposite the next macro specifies a vector by means of the coordinates % of its end points; the first point is where the vector starts, and the second -% point is the arrow tip side. We need the difference of these two coordinates, because % it represents the actual vector. +% point is the arrow tip side. We need the difference of these two coordinates, +% because it represents the actual vector. % \begin{macrocode} \def\VECTOR(#1)(#2){\begingroup \SubVect#1from#2to\@tempa @@ -923,7 +1280,7 @@ and the derived files curve2e.sty and curve2e.pdf. % macros.}\label{fig:vectors} % \end{figure} % -% \subsubsection{Polylines} +% \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$)% @@ -943,13 +1300,12 @@ and the derived files curve2e.sty and curve2e.pdf. % 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. +% 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 allow the line join -% specification. +% redefine it so as to allow an optional argument to specify the line join type. % % 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 @@ -966,7 +1322,7 @@ and the derived files curve2e.sty and curve2e.pdf. \ignorespaces}} % \end{macrocode} -% But if there is a second or further point coordinate the recursive macro +% But if there is a second or further point coordinate, the recursive macro % |\p@lyline| is called; it works on the next point and checks for a further % point; if such a point exists it calls itself, otherwise it terminates the % polygonal line by stroking it. @@ -976,7 +1332,7 @@ and the derived files curve2e.sty and curve2e.pdf. \@ifnextchar\lp@r{\p@lyline}{\strokepath\ignorespaces}} % \end{macrocode} % -% \subsubsection{The red service grid} +% \subsection{The red service grid} % The next command is very useful for debugging while editing one's drawings; % it draws a red grid with square meshes that are ten drawing units apart; % there is no graduation along the grid, since it is supposed to be a debugging @@ -986,13 +1342,13 @@ and the derived files curve2e.sty and curve2e.pdf. % the readings become cumbersome. The |\RoundUp| macro provides to increase the % grid dimensions to integer multiples of ten. % \begin{macrocode} -\def\GraphGrid(#1,#2){\begingroup\textcolor{red}{\linethickness{.1\p@}% +\def\GraphGrid(#1,#2){\bgroup\textcolor{red}{\linethickness{.1\p@}% \RoundUp#1modulo10to\@GridWd \RoundUp#2modulo10to\@GridHt \@tempcnta=\@GridWd \divide\@tempcnta10\relax \advance\@tempcnta\@ne \multiput(0,0)(10,0){\@tempcnta}{\line(0,1){\@GridHt}}% \@tempcnta=\@GridHt \divide\@tempcnta10\advance\@tempcnta\@ne \multiput(0,0)(0,10){\@tempcnta}{\line(1,0){\@GridWd}}\thinlines}% -\endgroup\ignorespaces} +\egroup\ignorespaces} % \end{macrocode} % Rounding up is useful because also the grid margins fall on coordinates % multiples of 10. It resorts to the |\Integer| macro that will be described in @@ -1007,20 +1363,80 @@ and the derived files curve2e.sty and curve2e.pdf. % \end{macrocode} % The |\Integer| macro takes a possibly fractional number whose decimal % separator, if present, \textit{must} be the decimal point and uses the point -% as an argument delimiter If one has the doubt that the number being passed +% as an argument delimiter. If one has the doubt that the number being passed % to |\Integer| might be an integer, he/she should call the macro with a -% further point; -% if the argument is truly integer this point works as the delimiter of the -% integer part; if the argument being passed is fractional this extra point -% gets discarded as well as the fractional part of the number. +% further point; if the argument is truly integer this point works as the +% delimiter of the integer part; if the argument being passed is fractional +% this extra point gets discarded as well as the fractional part of the number. % \begin{macrocode} \def\Integer#1.#2??{#1}% % \end{macrocode} % +% \section{Math operations on fixed radix operands} +% This is not the place to complain about the fact that all programs of the +% \TeX\ system use only integer arithmetics; LuaTeX can do floating point +% arithmetics through the Lua language that it partially incorporates. But +% this |curve2e| package is supposed to work also with pdfTeX and XeTeX. +% Therefore the Lua language should not be used. +% +% The only possibility to fake fractional arithmetics is to use fractional +% numbers as multipliers of the unit length |\p@| that is 1\,pt long; +% calculations are performed on lengths, and eventually their value, +% extracted from the length registers with the |\the| command is stripped +% off the ``pt'' component. The \LaTeX\ kernel macro does this in one step. +% At the same time the dimensional expressions made available by the |e-TeX| +% extension to all the \TeX\ system engines, allows to perform all operations +% directly on suitable length registers. +% +% The drawback of working with \TeX\ arithmetics for dimensions is that they +% are saved in binary form in computer words of 32 bits; the sixteen less +% significant bits are reserved for the fractional part; the two more +% significant bits are reserved for the sign and the type of dimension. +% There remain in total 30 bits available for the entire number; just to +% simplify this representation the \TeX\-book explains that the computer +% 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 +% 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, +% and a signed exponent of 2 that has 7 significant bits and represents the +% number of binary digits that is necessary to move the binary fractional +% sign to the right or to the left in order to remain with a number greater +% or equal to 1, but lower than 2; this way of coding numbers is called +% \emph{floating point} representation (of course special numbers, such as +% zero, require special codes); \TeX\ fixed radix representation may code +% numbers with absolute value not exceeding ($2^{30}-1$)\,sp =1073741823\,sp +% =16383.99998\,pt; a floating point 32-bit number cannot exceed in magnitude +% the value of approximately $1.8446744\times 10^{19}$; with fixed radix +% numbers it is possible to evaluate the absolute value of the imprecision +% of the results by summing the absolute imprecision of the terms of +% summation and subtraction; with floating point numbers it is possible to +% estimate the relative imprecision by summing the relative imprecisions of +% the terms of multiplication and division. +% +% Working with fixed radix numbers one must keep in mind that 16 fractional +% binary digits are more or less equivalent to 5 decimal fractional +% digits; and that 16383,99998\,pt are a little less than six meters (5,75832\,m). +% These limits appear completely sufficient to do most computations necessary +% for typography, but when we pretend to make computations of mathematical +% functions with such a poor ``calculator'', we must expect poorly approximated +% results. Nevertheless using the proper iterative algorithms the results are +% not too bad, but certainly it is necessary to accept the situation. +% +% Then why not using the |fp| package that allows to do computations in \TeX\ +% with the floating point representation of numbers? Simply because the results +% 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. +% % \subsection{The new division macro} -% Now comes one of the most important macros in the whole package: the division +% The most important macro in the whole package is the division % macro; it takes two lengths as input values and computes their fractional % ratio into a control sequence. +% % It must take care of the signs, so that it examines the operand signs and % determines the result sign separately conserving this computed sign in the % macro |\segno|; this done, we are sure that both operands are or are @@ -1028,29 +1444,30 @@ and the derived files curve2e.sty and curve2e.pdf. % quotient; should the denominator be zero it outputs % ``infinity'' (|\maxdimen| in points), that is the maximum allowable length % measured in points that \TeX\ can deal with. +% % Since the result is assigned a value, the calling statement must pass as the % third argument either a control sequence or an active character. Of course the % first operand is the dividend, the second the divisor and the third the % quotient. % % Since |curve2e| is supposed to be an extension of |pict2e| and this macro -%package already contains a division macro, we do not define any other division -% macro; nevertheless, since the macro in |pict2e| may not be so efficient as it -% might be if the |e-tex| extensions of the interpreter program were available, -% here we check and eventually provide a more efficient macro. The latter exploits -% the scaling mechanism embedded in |pdftex| since 2007, if the extended mode is -% enabled, that is used to scale a dimension by a fraction: $L\times N/D$, where -% $L$ is a dimension, and $N$ and $D$ are the numerator an denominator of the -% scaling factor; these might be integers, but it's better they represent the -% numbers of scaled points another two dimensions correspond to, in the philosophy -% that floating point numbers are represented by the measures of lengths in -% points. -% -% Therefore first we test if the macro is already defined: +% package already contains a division macro, we might not define any other +% division macro; nevertheless, since the macro in |pict2e| may not be so +% efficient as it might be if the |e-tex| extensions of the interpreter program +% were available, here we check and eventually provide a more efficient macro. +% The latter exploits the scaling mechanism embedded in |pdftex| since 2007, +% when the extended mode is enabled; it is used to scale a dimension by a +% fraction: $L\times N/D$, where $L$ is a dimension, and $N$ and $D$ are the +% numerator an denominator of the scaling factor; these might be integers, but +% it's better they are both represented by dimension registers, that contain +% two lengths expressed in the same units, possibly the fractional scaling +% factor numerator and denominator that `scale'' the unit length |\p@|. +% +% Therefore first we test if the extended mode exists and/or is enabled: % \begin{macrocode} \ifdefined\dimexpr % \end{macrocode} -% then we test if the extended mode exists and/or is enabled: +% then we test if the macro is already defined: % \begin{macrocode} \unless\ifdefined\DividE % \end{macrocode} @@ -1059,13 +1476,13 @@ and the derived files curve2e.sty and curve2e.pdf. % old and/or it is a recent version, but it was compiled without activating the % extended mode, the macro |\dimexpr| is undefined. % -% The macro, creates a group where the names of two counters and a +% The macro |\DividE|, creates a group where the names of two counters and a % dimensional register are defined; the numbers of these integer and dimension % registers are expressly above the value 255, because one of the extensions is % the possibility of using a virtually unlimited number of registers; moreover % even if these registers were used within other macros, their use within a group -% does not damage the other macros; we just have to use a dirty trick to throw -% the result beyond the end-group command. +% does not damage the other macros; we just have to use a Knuthian dirty trick +% to throw the result beyond the end-group command. % % The efficiency of this macro is contained in the extended command |\dimexpr|; % both the |\@DimA| and |\Num| registers are program words of 32\,bits; the result @@ -1074,22 +1491,23 @@ 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 end the termination of the program. During the division -% 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. +% 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 +% are lengths and the third is a macro. % % \begin{macrocode} \def\DividE#1by#2to#3{\bgroup - \countdef\Num2254\relax \countdef\Den2252\relax - \dimendef\@DimA 2254 - \Num=\p@ \@DimA=#2\relax \Den=\@DimA - \ifnum\Den=\z@ + \dimendef\Num2254\relax \dimendef\Den2252\relax + \dimendef\@DimA 2250 + \Num=\p@ \Den=#2\relax + \ifdim\Den=\z@ \edef\x{\noexpand\endgroup\noexpand\def\noexpand#3{\strip@pt\maxdimen}}% \else \@DimA=#1\relax - \@DimA=\dimexpr\@DimA*\Num/\Den\relax - \edef\x{\noexpand\egroup\noexpand\def\noexpand#3{\strip@pt\@DimA}}% + \edef\x{% + \noexpand\egroup\noexpand\def\noexpand#3{% + \strip@pt\dimexpr\@DimA*\Num/\Den\relax}}% \fi \x\ignorespaces}% \fi @@ -1099,22 +1517,23 @@ and the derived files curve2e.sty and curve2e.pdf. % not dimensions, and produce a macro that contains the fractional result. % \begin{macrocode} \unless\ifdefined\DivideFN - \def\DivideFN#1by#2to#3{\DividE#1\p@ by#2\p@ to#3}% + \def\DivideFN#1by#2to#3{\DividE#1\p@ by#2\p@ to{#3}}% \fi % \end{macrocode} % % We do the same in order to multiply two integer o fractional numbers held % in the first two arguments and the third argument is a definable token that % will hold the result of multiplication in the form of a fractional number, -% possibly with a non null fractional part; a null fractional part is -% eliminated by \verb|strip@pt|. +% possibly with a non null fractional part; a null fractional part is +% eliminated by \verb|\strip@pt|. % \begin{macrocode} \unless\ifdefined\MultiplY \def\MultiplY#1by#2to#3{\bgroup \dimendef\@DimA 2254 \dimendef\@DimB2255 \@DimA=#1\p@\relax \@DimB=#2\p@\relax - \@DimA=\dimexpr\@DimA*\@DimB/\p@\relax - \edef\x{\noexpand\egroup\noexpand\def\noexpand#3{\strip@pt\@DimA}}% + \edef\x{% + \noexpand\egroup\noexpand\def\noexpand#3{% + \strip@pt\dimexpr\@DimA*\@DimB/\p@\relax}}% \x\ignorespaces}% \fi \fi @@ -1126,16 +1545,17 @@ and the derived files curve2e.sty and curve2e.pdf. % assigned to the control sequence. % \begin{macrocode} \unless\ifdefined\Numero - \def\Numero#1#2{\dimen3254#2\relax - \edef#1{\strip@pt\dimen3254}\ignorespaces}% + \def\Numero#1#2{\bgroup\dimen3254=#2\relax + \edef\x{\noexpand\egroup\noexpand\edef\noexpand#1{% + \strip@pt\dimen3254}}\x\ignorespaces}% \fi % \end{macrocode} % The \verb|\ifdefined| primitive command is provided by the e-\TeX\ extension % of the typesetting engine; the test does not create any hash table entry; % it is a different way than the \verb|\ifx\csname ....\endcsname| test, -% because the latter first possibly creates a macro with meaning \verb|relax| +% because the latter first possibly creates a macro meaning \verb|\relax| % then executes the test; therefore an undefined macro name is always defined -% to mean \verb|\relax|. +% to mean |\relax|. % % \subsection{Trigonometric functions} % We now start with trigonometric functions. We define the macros |\SinOf|, @@ -1160,12 +1580,12 @@ and the derived files curve2e.sty and curve2e.pdf. % in proximity of the value zero (and the other values that might involve high % tangent or cotangent values) and in that case we prefer to approximate the % small angle function value with its first or second order truncation of the -% McLaurin series; in facts for angles whose magnitude is smaller than $1^\circ$ +% McLaurin series; in facts for angles whose magnitude is smaller than 1° % the magnitude of the independent variable $y=2x$ (the angle in degrees -% converted to radians) is so small (less than 0.017) that the sine and tangent +% 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 $4\cdot10^{-9}$). +% the formula $1-0.5y^2$ (the error being smaller than about $\cdot10^{-6}$). % % We keep using grouping so that internal variables are local to these groups % and do not mess up other things. @@ -1178,6 +1598,7 @@ and the derived files curve2e.sty and curve2e.pdf. \def\g@tTanCotanFrom#1to#2and#3{% \DividE 114.591559\p@ by#1to\X@ \@tdB=\X@\p@ % \end{macrocode} +% % 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 @@ -1197,15 +1618,14 @@ and the derived files curve2e.sty and curve2e.pdf. \@tdC=\Tan\p@ \@tdD=\I\@tdB \advance\@tdD-\@tdC \DividE\p@ by\@tdD to\Tan \advance\I-2\relax}% -\def#2{\Tan}\DividE\p@ by\Tan\p@ to\Cot \def#3{\Cot}% -\ignorespaces}% +\def#2{\Tan}\DividE\p@ by\Tan\p@ to\Cot \def#3{\Cot}\ignorespaces}% % \end{macrocode} % % Now that we have the macro for computing the tangent and cotangent of the % half angle, we can compute the real trigonometric functions we are interested % in. The sine value is computed after reducing the sine argument to the % interval $0^\circ< \theta<180^\circ$; actually special values such as -% $0^\circ$, $90^\circ$, $180^\circ$, et cetera, are taken care separately, so +% 0°, 90°, 180°, et cetera, are taken care separately, so % that CPU time is saved for these special cases. The sine sign is taken care % separately according to the quadrant of the sine argument. % @@ -1303,8 +1723,8 @@ and the derived files curve2e.sty and curve2e.pdf. % % For the tangent computation we behave in a similar way, except that we % consider the fundamental interval as $0^\circ<\theta<90^\circ$; for the odd -% multiples of $90^\circ$ we assign the result a \TeX\ infinity value, that is -% the maximum a dimension can be. +% multiples of 90° we assign the result a \TeX\ infinity value, i.e. |\maxdimen|, +% the maximum dimension \TeX\ can handle. % \begin{macrocode} \def\TanOf#1to#2{\bgroup% \@tdA=#1\p@% @@ -1340,6 +1760,127 @@ and the derived files curve2e.sty and curve2e.pdf. \endTanOf}% % \end{macrocode} % +% As of today the anomaly (angle) of a complex number may not be necessary, but +% it might become useful in the future; therefore with macro \verb|\ArgOfVect| +% we calculate the four quadrant arctangent (in degrees) of the given vector +% taking into account the sings of the vector components. For the principal +% value of the arctangent we would like to use the continued fraction: +%\begin{equation} +%\arctan x = \cfrac{x}{1+ \cfrac{x^2}{3-x^2 + \cfrac{(3x)^2}{5-3x^2 + +% \cfrac{(5x)^2}{7-5x^2 + \cfrac{(7x)^2}{9-7x^2 + \ddots}}}}} +%\label{equ:arctan-fraz-cont} +%\end{equation} +% but after some testing we had to give up due to the slow convergence of +% continued fraction~\eqref{equ:arctan-fraz-cont}, strictly connected with +% the slow convergence of the McLaurin series from which it is derived. +% +% Waiting for a faster convergence continued fraction, we examined the +% parametric formula and its inverse: +%\begin{subequations} +%\begin{align} +%\tan\theta &= \frac{2\tan(\theta/2))}{1 - \tan^2(\theta/2)}\\ +%\tan(\theta/2) &= \frac{\sqrt{\tan^2\theta +1}-1}{\tan\theta} +%\label{equ:tanfimezzi} +%\end{align} +%\end{subequations} +% If we count the times we use the above formula we can arrive at a point +% where we have to compute the arctangent of a very small value, where the +% arctangent and its argument are approximately equal, so that the angle value +% in radians is equal to its tangent; at that point we multiply by $2^n$, +% where $n$ is the number of bisections, and transform the radians in degrees. +% The procedure is pretty good, even if is is very rudimental and based on an +% approximation; the fixed radix computation of the typesetting engine does +% not help, but we get pretty decent results, although we loose some accuracy +% that hopefully would not harm further computations. +% +% 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. +% +% It is probably better to refer to the Newton iterations for solving the +% equation: +%\begin{equation} +% \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) +%\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$}} +%\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$}} +%\end{picture} +%\caption{Newton's method of tangents}\label{fig:tangenti} +%\end{figure} +% +% The iterative algorithm with Newton method implies the recurrence +%\begin{subequations}\begin{align} +%y'_{i-1} &= \frac{\diff\tan(\theta_{i-1})}{\diff\theta} +% = \frac{1}{\cos^2\theta_{i-1}}\\ +%\theta_i &= \theta_{i-1} - \frac{\tan \theta_{i-1} - t}{y'_{i-1}} +% =\theta_{i-1} - \cos^2 \theta_{i-1}(\tan \theta_{i-1} - t) +%\label{equ:iterazione} +%\end{align} +%\end{subequations} +% +% The algorithm starts with an initial value $\theta_0$; at each iteration +% for $i=1, 2, 3,\dots$ a new value of $\theta_i$ is computed from the data +% of the previous iteration $i-1$. When for a certain $i$, $\tan\theta_i$ +% is sufficiently close to $t$, the iterations may be stopped; since we +% 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. +% \begin{macrocode} +\def\ArcTanOf#1to#2{\bgroup +\edef\@tF{#1}\@tdF=\@tF\p@ \@tdE=57.295778\p@ +\@tdD=\ifdim\@tdF>\z@ \@tdF\else -\@tdF\fi +\unless\ifdim\@tdD>0.02\p@ + \def\@tX{\strip@pt\dimexpr57.295778\@tdF\relax}% +\else + \edef\@tX{45}\relax + \countdef\I 2523 \I=8\relax + \@whilenum\I>0\do{\TanOf\@tX to\@tG + \edef\@tG{\strip@pt\dimexpr\@tG\p@-\@tdF\relax}\relax + \MultiplY\@tG by57.295778to\@tG + \CosOf\@tX to\@tH + \MultiplY\@tH by\@tH to\@tH + \MultiplY\@tH by\@tG to \@tH + \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}% +% \end{macrocode} +% % \subsection{Arcs and curves preliminary information} % We would like to define now a macro for drawing circular arcs of any radius % and any angular aperture; the macro should require the arc center, the @@ -1348,16 +1889,36 @@ and the derived files curve2e.sty and curve2e.pdf. % nevertheless if |\put| is used, it may displace the arc into another position. % The command should have the following syntax: % \begin{flushleft}\ttfamily -% \cs{Arc}(\meta{{\rmfamily center}})(\meta{{\rmfamily starting -% point}}){\marg{{\rmfamily angle}}} +% \cs{Arc}(\meta{center})(\meta{starting point})\marg{angle} % \end{flushleft} % which is totally equivalent to: % \begin{flushleft}\ttfamily -% \string\put(\meta{\rmfamily center})\string{\string\Arc(0,0)(\meta{\rmfamily starting -% point})\marg{\rmfamily angle}\string} +% \cs{put}(\meta{center})\marg{\upshape\cs{Arc}(0,0)(\meta{starting point})\marg{angle}} % \end{flushleft} -% If the \meta{angle} is positive the arc runs counterclockwise from the -% starting point; clockwise if it's negative. +% If the \meta{angle}, i.e. the arc angular aperture, is positive the arc +% runs counterclockwise from the starting point; clockwise if it's negative. +% Notice that since the \meta{starting point} is relative to the \meta{center} +% point, its polar coordinates are very convenient, since they become +% \parg{\meta{start angle}:\meta{radius}}, where the +% \meta{start angle} is relative to the arc center. Therefore you can think +% about a syntax such as this one: +%\begin{flushleft} +%\cs{Arc}\parg{\meta{center}}\parg{\meta{start angle}:\meta{radius}}\marg{angle} +%\end{flushleft} +% +% The difference between the |pict2e| |\arc| definition consists in a very +% different syntax: +%\begin{flushleft} +%\cs{arc}\texttt{[}\meta{start angle}\texttt{,}\meta{end angle}\texttt{]}\marg{radius} +%\end{flushleft} +% and the center is assumed to be at the coordinate established with a +% required |\put| command; moreover the difference in specifying angles +% is that \meta{end angle} equals the sum of \meta{start angle} and +% \meta{angle}. With the definition of this |curve2e| package +% use of a |\put| command is not prohibited, but it may be used for fine +% tuning the arc position by means of a simple displacement; moreover the +% \meta{starting point} may be specified with polar coordinates (that are +% relative to the arc center). % % It's necessary to determine the end point and the control points of the % Bézier spline(s) that make up the circular arc. @@ -1367,13 +1928,37 @@ and the derived files curve2e.sty and curve2e.pdf. % pivoting point appears to be non relocatable. % It is therefore necessary to resort to low level \TeX\ commands and the % defined trigonometric functions and a set of macros that operate on complex -% numbers used as vector scale-rotate operators. +% numbers used as vector roto-amplification operators. % % \subsection{Complex number macros} -% We need therefore macros for summing, subtracting, multiplying, dividing -% complex numbers, for determining they directions (unit vectors); a unit vector +% In this package \emph{complex number} is a vague phrase; it may be used +% in the mathematical sense of an ordered pair of real numbers; it can be +% viewed as a vector joining the origin of the coordinate axes to the +% coordinates indicated by the ordered pair; it can be interpreted as a +% 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| +% environment) there is the other conventional representation used by the +% engineers that stress the roto-amplification nature of a complex number: +%\[ +%(x, y) = x + \mathrm{j}y =M \mathrm{e}^{\mathrm{j}\theta} +%\] +% Even the imaginary unit is indicated with $\mathrm{i}$ by the mathematicians +% and with $\mathrm{j}$ by the engineers. In spite of these differences, +% these objects, the \emph{complex numbers}, are used without any problem by +% both mathematicians and engineers. +% +%The important point is that these objects can be summed, subtracted, +% multiplied, divided, raised to any power (integer, fractional, positive +% or negative), be the argument of transcendental functions according to +% rules that are agreed upon by everybody. We do not need all these properties, but we need some and we must create the suitable macros for doing some of +% these operations. +% +% In facts wee need macros for summing, subtracting, multiplying, dividing +% complex numbers, for determining their directions (unit vectors); a unit vector % is the complex number divided by its magnitude so that the result is the -% Cartesian form of the Euler's formula +% cartesian or polar form of the Euler's formula % \[ % \mathrm{e}^{\mathrm{j}\phi} = \cos\phi+\mathrm{j}\sin\phi % \] @@ -1416,29 +2001,38 @@ and the derived files curve2e.sty and curve2e.pdf. \def\ModOfVect#1to#2{\GetCoord(#1)\t@X\t@Y \@tempdima=\t@X\p@ \ifdim\@tempdima<\z@ \@tempdima=-\@tempdima\fi \@tempdimb=\t@Y\p@ \ifdim\@tempdimb<\z@ \@tempdimb=-\@tempdimb\fi -\ifdim\@tempdima>\@tempdimb - \DividE\@tempdimb by\@tempdima to\@T - \@tempdimc=\@tempdima +\ifdim\@tempdima=\z@ + \ifdim\@tempdimb=\z@ + \def\@T{0}\@tempdimc=\z@ + \else + \def\@T{0}\@tempdimc=\@tempdimb + \fi \else - \DividE\@tempdima by\@tempdimb to\@T - \@tempdimc=\@tempdimb + \ifdim\@tempdima>\@tempdimb + \DividE\@tempdimb by\@tempdima to\@T + \@tempdimc=\@tempdima + \else + \DividE\@tempdima by\@tempdimb to\@T + \@tempdimc=\@tempdimb + \fi \fi -\ifdim\@T\p@=\z@ -\else - \@tempdima=\@T\p@ \@tempdima=\@T\@tempdima - \advance\@tempdima\p@% - \@tempdimb=\p@% - \@tempcnta=5\relax - \@whilenum\@tempcnta>\z@\do{\DividE\@tempdima by\@tempdimb to\@T - \advance\@tempdimb \@T\p@ \@tempdimb=.5\@tempdimb - \advance\@tempcnta\m@ne}% - \@tempdimc=\@T\@tempdimc +\unless\ifdim\@tempdimc=\z@ + \unless\ifdim\@T\p@=\z@ + \@tempdima=\@T\p@ \@tempdima=\@T\@tempdima + \advance\@tempdima\p@% + \@tempdimb=\p@% + \@tempcnta=5\relax + \@whilenum\@tempcnta>\z@\do{\DividE\@tempdima by\@tempdimb to\@T + \advance\@tempdimb \@T\p@ \@tempdimb=.5\@tempdimb + \advance\@tempcnta\m@ne}% + \@tempdimc=\@T\@tempdimc + \fi \fi \Numero#2\@tempdimc \ignorespaces}% % \end{macrocode} % As a byproduct of the computation the control sequence |\@tempdimc| contains -% the vector or complex number magnitude multiplied by the length of one point. +% a length the value in points of which is the computed root. % % Since the macro for determining the magnitude of a vector is available, we % can now normalize the vector to its magnitude, therefore getting the Cartesian @@ -1500,124 +2094,16 @@ and the derived files curve2e.sty and curve2e.pdf. \MakeVectorFrom\t@X\t@Y to#2\ignorespaces}% % \end{macrocode} % -% As of today the anomaly (angle) of a complex number may not be necessary, but -% it might become useful in the future; therefore with macro \verb|\ArgOfVect| -% we calculate the four quadrant arctangent (in degrees) of the given vector -% taking into account the sings of the vector components. For the principal -% value of the arctangent we would like to use the continued fraction: -%\begin{equation} -%\arctan x = \cfrac{x}{1+ \cfrac{x^2}{3-x^2 + \cfrac{(3x)^2}{5-3x^2 + -% \cfrac{(5x)^2}{7-5x^2 + \cfrac{(7x)^2}{9-7x^2 + \ddots}}}}} -%\label{equ:arctan-fraz-cont} -%\end{equation} -% but after some testing we had to give up due to the slow convergence of -% continued fraction~\eqref{equ:arctan-fraz-cont}, strictly connected with -% the slow convergence of the McLaurin series from which it is derived. -% -% Waiting for a faster convergence continued fraction, we examined the -% parametric formula and its inverse: -%\begin{equation} -%\begin{subequations} -%\begin{aligned} -%\tan\theta &= \frac{2\tan(\theta/2))}{1 - \tan^2(\theta/2)}\\ -%\tan(\theta/2) &= \frac{\sqrt{\tan^2\theta +1}-1}{\tan\theta} -%\label{equ:tanfimezzi} -%\end{aligned} -%\end{subequations} -%\end{equation} -% If we count the times we use the above formula we can arrive at a point -% where we have to compute the arctangent of a very small value, where the -% arctangent and it argument are approximately equal, so that the angle value -% in radians is equal to its tangent; at that point we multiply by $2^n$, -% where $n$ is the number of bisections and transform the radians in degrees. -% The procedure is pretty good, even if is is very rudimental and based on an -% approximation; the fixed radix computation of the typesetting engine does -% not help, but we get pretty decent results, although we loose some accuracy -% that hopefully would not harm further computations. -% -% 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 algorthim crashes; -% therefore it's virtually impossibile to get more than three correct digits -% after the decimal separator. -% -% It is probably better to refer to the Newton iterations for solving the -% equation: -%\begin{equation} -% \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,70) -%\put(10,63){\framebox(18,7){$y=\tan\theta$}} -%\put(30,63){\framebox(20,7){$t=\tan\theta_\infty$}} -%\put(0,0){\vector(1,0){100}}\put(100,3){\makebox(0,0)[br]{$\theta$}} -%\put(0,0){\vector(0,1){70}}\put(3,70){\makebox(0,0)[tl]{$y$}} -%\multiput(75,0)(0,5){14}{\line(0,1){2.5}}\put(77,2){\makebox(0,0)[bl]{$\pi/2$}} -%{\linethickness{1pt}\cbezier(0,0)(5,5)(55,40)(60,70)} -%\put(51,50){\circle*{2}} -%\multiput(51,0)(0,5){10}{\line(0,1){2.5}}\put(54,3){\makebox(0,0)[bl]{$\theta_{i-1}$}} -%\multiput(0,50)(5,0){10}{\line(1,0){2.5}}\put(3,53){\makebox(0,0)[bl]{$y_{i-1}$}} -%\put(0,20){\line(1,0){70}}\put(3,23){\makebox(0,0)[bl]{$t$}} -%\Line(34,20)(51,50) -%\put(34,20){\circle*{2}} -%\multiput(34,0)(0,5){4}{% -% \line(0,1){2.5}}\put(36,3){\makebox(0,0)[bl]{$\theta_{i}$}} -%\put(24,20){\circle*{2}} -%\multiput(24,0)(0,5){4}{\line(0,1){2.5}}\put(21,3){\makebox(0,0)[br]{$\theta_\infty$}} -%\end{picture} -%\caption{Newton method}\label{fig:tangenti} -%\end{figure} -% -% The iterative algorithm with Newton method implies the recurrence -%\begin{equation}\begin{subequations}\begin{aligned} -%y'_{i-1} &= \frac{\diff\tan(\theta_{i-1})}{\diff\theta} -% = \frac{1}{\cos^2\theta_{i-1}}\\ -%\theta_i &= \theta_{i-1} - y'_{i-1}(\tan \theta_{i-1} - t) -% =\theta_{i-1} - \cos^2 \theta_{i-1}(\tan \theta_{i-1} - t) -%\end{aligned} -%\label{equ:iterazione} -%\end{subequations}\end{equation} -% -% The algorithm starts with an initial value $\theta_0$, at each iteration -% for $i=1, 2, 3,\dots$ a new value of $\theta_i$ is computed from the data -% of the previous iteration $i-1$. When for a certain $i$, $\tan\theta_i$ -% is sufficiently close to $t$, the iterations may be stopped; since we -% already have the algorithms for computing both the tangent and the cosine; -% such Newton iterative method dos not pose any problems, especially if we -% use the properties of the trigonometric functions and we confine the -% computations to the first quadrant. -% \begin{macrocode} -\def\ArcTanOf#1to#2{\bgroup -\edef\@tF{#1}\@tdF=\@tF\p@ -\@tdE=57.295779\p@ -\ifdim\@tdF=\z@\def\@tX{0}\else -\edef\@tXX{1}% -\MultiplY57.295779by\@tXX to \@tX -\countdef\I 2323 \I=7\relax -\@whilenum\I>0\do{\TanOf\@tX to\@tG -\CosOf\@tX to \@tH -\edef\@tG{\strip@pt\dimexpr\@tG\p@-\@tdF\relax}% -\MultiplY\@tH by\@tH to\@tH -\MultiplY\@tH by\@tG to \@tH -\edef\@tXX{\strip@pt\dimexpr\@tXX\p@ - \@tH\p@\relax}% -\MultiplY57.295779by\@tXX to\@tX -\advance\I\m@ne}\fi -\edef\x{\egroup\noexpand\edef\noexpand#2{\@tX}}\x}% -% \end{macrocode} -% -% Now we have the algorithm to compute the arctangent of a number; and +% Since we have the algorithm to compute the arctangent of a number, % it should be relatively easy to compute the angle of a complex number. -% We have to pay attention that the algorithm to compute the arctangent +% We just have to pay attention that the algorithm to compute the arctangent % does not care about the quadrant where the complex number lays in, and -% it yields the principal value of the arctan in the domain $\pi/2 < -% \theta \leq \pi/2$. with complex numbers we have just a sign change in -% their angle when the lay in the first or the fourth quadrants; while +% it yields the principal value of the arctan in the domain $-\pi/2 < +% \theta \leq \pi/2$. With complex numbers we have just a sign change in +% their angle when they lay in the first or the fourth quadrants; while % for the third and second quadrants we have to reflect the complex number % to its opposite and in the result we have to add a ``flat angle'', that -% is 180°, since we are working in degrees. Even if mathematically it +% is 180° since we are working in degrees. Even if mathematically it % is undefined we decided to assign a null angle to a null complex number; % possibly a warning message would be helpful, but for drawing purposes % we think that the problem is irrelevant. @@ -1662,16 +2148,27 @@ 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 1 & \ArcTanOf 1 to\Res \Res\\ -%^^A 2 & \ArcTanOf 2 to\Res \Res\\ -%^^A 0.5 & \ArcTanOf 0.5 to\Res \Res\\ -%^^A 0.707 & \ArcTanOf 0.707 to\Res \Res\\ -%^^A \end{tabular} -%^^A -%^^A\bigskip -%^^A +%^^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\\ @@ -1684,9 +2181,9 @@ and the derived files curve2e.sty and curve2e.pdf. % ^^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.001°, that is 0.000017\,rad; pretty satisfactory since the typesetting -% engines work in fixed radix notation with 16 fractional binary digits, and -% an error on the fifth fractional digit is almost the best it can be expected +% 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. % % Sometimes it is necessary to scale a vector by an arbitrary real factor; this @@ -1777,7 +2274,7 @@ and the derived files curve2e.sty and curve2e.pdf. % \begin{macrocode} \def\Arc(#1)(#2)#3{\begingroup \@tdA=#3\p@ -\ifdim\@tdA=\z@\else +\unless\ifdim\@tdA=\z@ \@Arc(#1)(#2)% \fi \endgroup\ignorespaces}% @@ -1854,12 +2351,62 @@ and the derived files curve2e.sty and curve2e.pdf. % Here we need the extrema of the arc and the coordinates of the control points % of the Bézier cubic spline that traces the arc. The control points lay on the % perpendicular to the vectors that join the arc center to the starting -% and end points respectively. Their distance $K$ from the adjacent nodes is -% determined with the formula -% \[ +% and end points respectively. +% +%\begin{figure}\centering\unitlength=0.007\textwidth +%\begin{picture}(100,90)(-50,-50) +%\put(-50,0){\vector(1,0){100}}\put(50,1){\makebox(0,0)[br]{$x$}} +%\put(20,-1){\makebox(0,0)[t]{$s$}} +%\put(0,0){\circle*{2}}\put(-1,-1){\makebox(0,0)[tr]{$M$}} +%\legenda(12,-45){s=\overline{MP_2}=R\sin\theta} +%\put(0,-50){\vector(0,1){90}} +%\put(1,40){\makebox(0,0)[tl]{$y$}} +%\put(0,-40){\circle*{2}}\put(1,-41){\makebox(0,0)[lt]{$C$}} +%\Line(0,-40)(-40,0)\Line(0,-40)(40,0) +%\put(-41,1){\makebox(0,0)[br]{$P_1$}}\put(-40,0){\circle*{2}} +%\put(41,1){\makebox(0,0)[bl]{$P_2$}}\put(40,0){\circle*{2}} +%\put(0,0){\linethickness{1pt}\Arc(0,-40)(40,0){90}} +%\Line(-40,0)(-20,20)\put(-20,20){\circle*{2}} +%\put(-20,21.5){\makebox(0,0)[b]{$C_1$}} +%\Line(40,0)(20,20)\put(20,20){\circle*{2}} +%\put(20,21.5){\makebox(0,0)[b]{$C_2$}} +%\put(0,-40){\put(0,56.5685){\circle*{2}}\put(1,58){\makebox(0,0)[bl]{$P$}}} +%\VectorARC(0,-40)(15,-25){45}\put(10,-18){\makebox(0,0)[c]{$\theta$}} +%\VectorARC(40,0)(20,0){-45}\put(19,5){\makebox(0,0)[r]{$\theta$}} +%\VectorARC(-40,0)(-20,0){45}\put(-19,5){\makebox(0,0)[l]{$\theta$}} +%\put(-20,-18){\makebox(0,0)[bl]{$R$}} +%\put(-32,13){\makebox(0,0)[bl]{$K$}} +%\put(32,13){\makebox(0,0)[br]{$K$}} +%\end{picture} +%\caption{Nodes and control points for an arc to be approximated with a cubic Bézier spline} +%\label{fig:arcspline} +%\end{figure} +% +% With reference to figure~\ref{fig:arcspline}, +% the points $P_1$ and $P_2$ are the arc end-points; $C_1$ and $C_2$ are the +% Bézier-spline control-points; $P$ is the arc mid-point, that should be +% distant from the center of the arc the same as $P_1$ and $P_2$. Choosing a +% convenient orientation of the arc relative to the coordinate axes, the +% coordinates of these five points are: +%\begin{align*} +%P_1 &= (-R\sin\theta, 0)\\ +%P_2 &= (R\sin\theta, 0)\\ +%C_1 &= (-R\sin\theta+K\cos\theta, K\sin\theta)\\ +%C_2 &= (R\sin\theta-K\cos\theta, K\sin\theta)\\ +%P &= (0, R(1-\cos\theta)) +%\end{align*} +% The Bézier cubic spline interpolating the end and mid points is given by +% the parametric equation: +%\begin{equation*} +%P= P_1(1-t)^3 + C_1 3(1-t)^2t + C_2 3(1-t)t^2 + P_2t^3 +%\end{equation*} +% where the mid point is obtained for $t=0.5$; the four coefficients then become $1/8, 3/8, 3/8, 1/8$ and the only unknown remains $K$. Solving for $K$ we obtain the formula +% \begin{equation}\label{equ:corda} % K= \frac{4}{3}\,\frac{1-\cos\theta}{\sin\theta}R -% \] -% where $\theta$ is half the arc aperture and $R$ is its radius. +%= \frac{4}{3}\,\frac{1-\cos\theta}{\sin^2\theta}s +% \end{equation} +% where $\theta$ is half the arc aperture, $R$ is its radius, and $s$ is +% half the arc chord. % \begin{macrocode} \ifdim\@tdA>\z@ \DirFromAngle\@gradi to\@Dir \if\Segno-\ConjVect\@Dir to\@Dir \fi @@ -1902,10 +2449,11 @@ and the derived files curve2e.sty and curve2e.pdf. % |\VerctorArc| draws an arrow at the ending point of the arc; the second macro % |\VectorARC| draws arrows at both ends; the arrows have the same shape as % those for vectors; actually they are drawn by putting a vector of zero -% length at the proper arc end(s), therefore they are styled as traditional \LaTeX\ -% or PostScript arrows according to the option of the \texttt{pict2e} package. +% length at the proper arc end(s), therefore they are styled as traditional +% \LaTeX\ or PostScript arrows according to the specific option to the +% \texttt{pict2e} package. % -% But the specific drawing done here shortens the arc so as not to overlap on +% But the arc drawing done here shortens it so as not to overlap on % the arrow(s); the only arrow (or both ones) are also lightly tilted in order to % avoid the impression of a corner where the arc enters the arrow tip. % @@ -1915,11 +2463,11 @@ and the derived files curve2e.sty and curve2e.pdf. % length as an angular quantity, i.e. the arc amplitude that must be subtracted % from the total arc to be drawn; (c) the direction of the arrow should be % corresponding to the tangent to the arc at the point where the arrow tip is -% attached;(d) tilting the arrow tip by half its angular amplitude; (e) +% attached; (d) tilting the arrow tip by half its angular amplitude; (e) % determining the resulting position and direction of the arrow tip so as to -% draw a zero length vector; (f) possibly repeating the same procedure for the +% draw a zero length vector; (f\/) possibly repeating the same procedure for the % other end of the arc; (g) shortening the total arc angular amplitude by the -% amount of the arrow tip(s) already set, and (h) then drawing the final circular +% amount of the arrow tip(s) already set, and finally (h) drawing the circular % arc that joins the starting point to the final arrow or one arrow to the other % one. % @@ -2011,33 +2559,33 @@ and the derived files curve2e.sty and curve2e.pdf. \@tdE=\pIIe@FAW\@wholewidth \@tdE=0.8\@tdE \DividE\@tdE by \@Raggio\unitlength to\DeltaGradi \@tdD=\DeltaGradi\p@ \@tdD=57.29578\@tdD \Numero\DeltaGradi\@tdD -\@tdD=\ifx\Segno--\fi\@gradi\p@ \Numero\@tempa\@tdD +\@tdD=\if\Segno--\fi\@gradi\p@ \Numero\@tempa\@tdD \DirFromAngle\@tempa to\@Dir \MultVect\@V by\@Dir to\@sPun% corrects the end point -\edef\@tempA{\ifx\Segno-\m@ne\else\@ne\fi}% +\edef\@tempA{\if\Segno--\fi1}% \MultVect\@sPun by 0,\@tempA to\@vPun \DirOfVect\@vPun to\@Dir \AddVect\@sPun and #1 to \@sPun \GetCoord(\@sPun)\@tdX\@tdY -\@tdD\ifx\Segno--\fi\DeltaGradi\p@ +\@tdD\if\Segno--\fi\DeltaGradi\p@ \@tdD=.5\@tdD \Numero\@tempB\@tdD \DirFromAngle\@tempB to\@Dird \MultVect\@Dir by*\@Dird to\@Dir \GetCoord(\@Dir)\@xnum\@ynum -\put(\@tdX,\@tdY){\vector(\@xnum,\@ynum){0}}% arrow tip at the end point +\put(\@tdX,\@tdY){\vector(\@xnum,\@ynum){0}}% end point arrowt ip \@tdE =\DeltaGradi\p@ \advance\@tdA -2\@tdE \Numero\@gradi\@tdA \CopyVect#1to\@Cent \GetCoord(\@pPun)\@pPunX\@pPunY \SubVect\@Cent from\@pPun to \@V -\edef\@tempa{\ifx\Segno-\else-\fi\@ne}% +\edef\@tempa{\if\Segno-\else-\fi\@ne}% \MultVect\@V by0,\@tempa to\@vPun -\@tdE\ifx\Segno--\fi\DeltaGradi\p@ +\@tdE\if\Segno--\fi\DeltaGradi\p@ \Numero\@tempB{0.5\@tdE}% \DirFromAngle\@tempB to\@Dird \MultVect\@vPun by\@Dird to\@vPun% corrects the starting point \DirOfVect\@vPun to\@Dir\GetCoord(\@Dir)\@xnum\@ynum -\put(\@pPunX,\@pPunY){\vector(\@xnum,\@ynum){0}}% arrow tip at the starting point -\edef\@tempa{\ifx\Segno--\fi\DeltaGradi}% +\put(\@pPunX,\@pPunY){\vector(\@xnum,\@ynum){0}}% starting point arrow tip +\edef\@tempa{\if\Segno--\fi\DeltaGradi}% \DirFromAngle\@tempa to \@Dir \SubVect\@Cent from\@pPun to\@V \MultVect\@V by\@Dir to\@V @@ -2056,7 +2604,7 @@ 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} -% Now we define a macro for tracing a general, not necessarily circular arc. +% 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 @@ -2066,12 +2614,58 @@ and the derived files curve2e.sty and curve2e.pdf. % \begin{macrocode} \def\CurveBetween#1and#2WithDirs#3and#4{% \StartCurveAt#1WithDir{#3}\relax -\CurveTo#2WithDir{#4}\CurveFinish}% +\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. +% +%\begin{figure}\centering\unitlength=0.004\textwidth +%\begin{picture}(220,120)(-50,-20) +%\put(0,60){\Line(-50,0)(50,0) +%\CurveBetween-50,0and50,0WithDirs15:1and{-15:1} +%\CurveBetween-50,0and50,0WithDirs30:1and{-30:1} +%\CurveBetween-50,0and50,0WithDirs45:1and{-45:1} +%\CurveBetween-50,0and50,0WithDirs60:1and{-60:1} +%\CurveBetween-50,0and50,0WithDirs75:1and{-75:1} +%\CurveBetween-50,0and50,0WithDirs90:1and{-90:1}} +%\put(120,60){% +%\Line(-50,0)(50,0) +%\CurveBetween-50,0and50,0WithDirs15:1and{15:1} +%\CurveBetween-50,0and50,0WithDirs30:1and{30:1} +%\CurveBetween-50,0and50,0WithDirs45:1and{45:1} +%\CurveBetween-50,0and50,0WithDirs60:1and{60:1} +%\CurveBetween-50,0and50,0WithDirs75:1and{75:1} +%\CurveBetween-50,0and50,0WithDirs90:1and{90:1}} +%\put(0,0){% +%\Line(-50,0)(50,0) +%\CurveBetween-50,0and50,0WithDirs45:1and{-15:1} +%\CurveBetween-50,0and50,0WithDirs45:1and{-30:1} +%\CurveBetween-50,0and50,0WithDirs45:1and{-45:1} +%\CurveBetween-50,0and50,0WithDirs45:1and{-60:1} +%\CurveBetween-50,0and50,0WithDirs45:1and{-75:1} +%\CurveBetween-50,0and50,0WithDirs45:1and{-90:1}} +%\put(120,0){% +%\Line(-50,0)(50,0) +%\CurveBetween-50,0and50,0WithDirs45:1and{15:1} +%\CurveBetween-50,0and50,0WithDirs45:1and{30:1} +%\CurveBetween-50,0and50,0WithDirs45:1and{45:1} +%\CurveBetween-50,0and50,0WithDirs45:1and{60:1} +%\CurveBetween-50,0and50,0WithDirs45:1and{75:1} +%\CurveBetween-50,0and50,0WithDirs45:1and{90:1}} +%\end{picture} +%\caption{Curves between two points}\label{fig:curva-due-punti} +%\end{figure} % % The first macro initializes the drawing and the third one strokes it; the % real work is done by the second macro. The first macro initializes the @@ -2116,7 +2710,7 @@ and the derived files curve2e.sty and curve2e.pdf. \CopyVect\@tempa,\@tempb to\@Dzero \DirOfVect\@Dzero to\@Dzero} % \end{macrocode} -% And this re-initializes the direction after a cusp +% And this re-initializes the direction to create a cusp: % \begin{macrocode} \def\ChangeDir<#1>{% \GetCoord(#1)\@tempa\@tempb @@ -2125,13 +2719,128 @@ and the derived files curve2e.sty and curve2e.pdf. \ignorespaces} % \end{macrocode} % -% The next macro is the finishing one; it strokes the whole curve and closes the -% group that was opened with |\StartCurve|. +% The next macros are the finishing ones; the first strokes the whole curve, +% while the second fills the (closed) curve with the default color; both close +% the group that was opened with |\StartCurve|. The third macro is explained +% in a while; we anticipate it is functional to chose between the first two +% macros when a star is possibly used to switch between stroking and filling. +% \begin{macrocode} +\def\CurveFinish{\strokepath\endgroup\ignorespaces}% +\def\FillCurve{\fillpath\endgroup\ignorespaces} +\def\CurveEnd{\fillstroke\endgroup\ignorespaces} +% \end{macrocode} +% +% In order to draw the internal arcs it would be desirable to have a single +% macro that, given the destination point, computes the control points that +% produce a cubic Bézier spline that joins the starting point with the +% destination point in the best possible way. The problem is strongly ill +% defined and has an infinity of solutions; here we give two solutions: +% $(a)$ a supposedly smart one that resorts to osculating circles and +% requires only the direction at the destination point; and $(b)$ a less +% smart solution that requires the control points to be specified in a +% certain format. +% +% We start with solution $(b)$, |\CbezierTo|, the code of which is simpler +% than that of solution $(a)$; then we will produce the solution $(a)$, +% |\CurveTo|, that will become the main building block for a general path +% construction macro, |\Curve|. +% +% The ``naïve'' macro |\CBezierTo| simply uses the previous point direction saved in |\@Dzero| as a unit vector by the starting macro; specifies +% a destination point, the distance of the first control point from the +% starting point, the destination point direction that will save also for the +% next arc drawing macro as a unit vector, and the distance of the second +% control point from the destination point along this last direction. Both +% distances must be positive possibly fractional numbers. The syntax will +% be therefore: +%\begin{flushleft} +%\cs{CbezierTo}\meta{end +% point}|WithDir|\meta{direction}|AndDist|\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. +% +% This macro uses the input information to use the internal |pict2e| macro +% |\pIIe@curveto| with the proper arguments, and to save the final direction +% into the same |\@Dzero| macro for successive use of other macros. +% \begin{macrocode} +\def\CbezierTo#1WithDir#2AndDists#3And#4{% +\GetCoord(#1)\@tX\@tY \MakeVectorFrom\@tX\@tY to\@Puno +\GetCoord(#2)\@tX\@tY \MakeVectorFrom\@tX\@tY to \@Duno +\DirOfVect\@Duno to\@Duno +\ScaleVect\@Dzero by#3to\@Czero \AddVect\@Pzero and\@Czero to\@Czero +\ScaleVect\@Duno by-#4to \@Cuno \AddVect\@Puno and\@Cuno to \@Cuno +\GetCoord(\@Czero)\@XCzero\@YCzero +\GetCoord(\@Cuno)\@XCuno\@YCuno +\GetCoord(\@Puno)\@XPuno\@YPuno +\pIIe@curveto{\@XCzero\unitlength}{\@YCzero\unitlength}% + {\@XCuno\unitlength}{\@YCuno\unitlength}% + {\@XPuno\unitlength}{\@YPuno\unitlength}% +\CopyVect\@Puno to\@Pzero +\CopyVect\@Duno to\@Dzero +\ignorespaces}% +% \end{macrocode} +% +% With this building block it is not difficult to set up a macro that draws +% a Bézier arc between two given points, similarly as the other macro +% |\CurveBetween| described previously. +% % \begin{macrocode} -\def\CurveFinish{\strokepath\endgroup\ignorespaces}% +\def\CbezierBetween#1And#2WithDirs#3And#4UsingDists#5And#6{% +\StartCurveAt#1WithDir{#3}\relax +\CbezierTo#2WithDir#4AndDists#5And{#6}\CurveFinish} % \end{macrocode} + +% +% 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 +% 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 +% number of cut-and-try experiments. +% +%\begin{figure}[!tb] +%\begin{minipage}[t]{0.52\textwidth} +%\begin{verbatim} +%\unitlength=0.1\textwidth +%\begin{picture}(10,3) +%\CurveBetween0,0and10,0WithDirs1,1and{1,-1} +%\color{red}% +%\CbezierBetween0,0And10,0 WithDirs45:1And-45:1UsingDists4And{1} +%\CbezierBetween0,0And10,0 WithDirs45:1And-45:1UsingDists6And{1} +%\CbezierBetween0,0And10,0 WithDirs45:1And-45:1UsingDists8And{1} +%\CbezierBetween0,0And10,0 WithDirs45:1And-45:1UsingDists10And{1} +%\CbezierBetween0,0And10,0 WithDirs45:1And-45:1UsingDists12And{1} +%\end{picture} +%\end{verbatim} +%\end{minipage} +%\hfill +%\begin{minipage}{0.40\textwidth}\raggedleft +%\unitlength=0.1\textwidth +%\begin{picture}(10,3)(0,1.25) +%\CurveBetween0,0and10,0WithDirs1,1and{1,-1} +%\color{red}% +%\CbezierBetween0,0And10,0 WithDirs45:1And-45:1UsingDists4And{1} +%\CbezierBetween0,0And10,0 WithDirs45:1And-45:1UsingDists6And{1} +%\CbezierBetween0,0And10,0 WithDirs45:1And-45:1UsingDists8And{1} +%\CbezierBetween0,0And10,0 WithDirs45:1And-45:1UsingDists10And{1} +%\CbezierBetween0,0And10,0 WithDirs45:1And-45:1UsingDists12And{1} +%\end{picture} +%\end{minipage} +%\caption{Comparison between similar arcs drawn with \cs{CurveBetween} (black) +% and \cs{CbezierTo} (red)} +%\label{fig:Cbezier} +%\end{figure} % -% The ``real'' curve macro comes next; it is supposed to determine the control +% +% The ``smarter'' curve macro comes next; it is supposed to determine the control % points for joining the previous point (initial node) with the specified % direction to the next point with another specified direction (final node). % Since the control points are along the specified directions, it is necessary @@ -2144,39 +2853,20 @@ and the derived files curve2e.sty and curve2e.pdf. % osculating circle, 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 parts each of which should be -% interpreted as half the chord of the osculating circle; this curve chord -% division is made proportionally to the projection of the tangent directions -% on the chord itself. Excluding degenerate cases that may be dealt with -% directly, imagine the triangle built with the chord and the two tangents; -% this triangle is straightforward if there is no inflection point; otherwise it -% is necessary to change one of the two directions by reflecting it about the -% chord. This is much simpler to view if a general rotation of the whole -% construction is made so as to bring the curve chord on the $x$ axis, because -% the reflection about the chord amounts to taking the complex conjugate of one -% of the directions. In facts with a concave curve the ``left'' direction -% vector arrow and the ``right'' direction vector tail lay in the same half -% plane, while with an inflected curve, they lay in opposite half plains, so -% that taking the complex conjugate of one of directions re-establishes the -% correct situation for the triangle we are looking for. -% -% This done the perpendicular from the triangle vertex to the cord divides the -% chord in two parts (the foot of this perpendicular may lay outside the chord, -% but this is no problem since we are looking for positive solutions, so that -% if we get negative numbers we just negate them); these two parts are taken as -% the half chords of the osculating circles, therefore there is no problem -% determining the distances $K_{\mathrm{left}}$ and $K_{\mathrm{right}}$ from -% the left and right -% nodes by using the same formula we used with circular arcs. Well\dots\ the -% same formula means that we have to determine the radius from the half chord -% and its inclination with the node tangent; all things we can do with the -% complex number algebra and macros we already have at our disposal. If we look -% carefully at this computation done for the circular arc we discover that in -% practice we used the half chord length instead of the radius; so the coding -% is actually the same, may be just with different variable names. +% 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. +% +% 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: +%\begin{subequations}\label{equ:Kzero-Kuno} +%\begin{align} +%K_0 &= \frac{4}{3} s\frac{1-\cos\theta_0}{\sin^2\theta_0}\\ +%K_1 &=\frac{4}{3}s\frac{1-\cos\theta_1}{\sin^2\theta_1} +%\end{align} +%\end{subequations} % % We therefore start with getting the points and directions and calculating the -% chord and its direction +% chord and its direction: % \begin{macrocode} \def\CurveTo#1WithDir#2{% \def\@Puno{#1}\def\@Duno{#2}\DirOfVect\@Duno to\@Duno @@ -2187,117 +2877,75 @@ and the derived files curve2e.sty and curve2e.pdf. % \begin{macrocode} \MultVect\@Dzero by*\@DirChord to \@Dpzero \MultVect\@Duno by*\@DirChord to \@Dpuno -\GetCoord(\@Dpzero)\@Xpzero\@Ypzero -\GetCoord(\@Dpuno)\@Xpuno\@Ypuno +\GetCoord(\@Dpzero)\@DXpzero\@DYpzero +\GetCoord(\@Dpuno)\@DXpuno\@DYpuno +\DivideFN\@Chord by2 to\@semichord % \end{macrocode} % The chord needs not be actually rotated because it suffices its length -% along the real axis; the chord length is memorized in |\@Chord|. +% along the real axis; the chord length is memorised in |\@Chord| and +% its half is saved in |\@semichord|. % % We now examine the various degenerate cases, when either tangent is -% perpendicular to the chord, or when it is parallel pointing inward or outward, -% with or without inflection. +% perpendicular or parallel to the chord. Notice that we are calculating +% the distances of the control points from the adjacent nodes using the +% half chord length, not the full length. We also distinguish between the +% computations relative to the arc starting point and those relative to +% the end point. % -% We start with the $90^\circ$ case for the ``left'' direction -% separating the cases when the other direction is or is not $90^\circ$~\dots % \begin{macrocode} -\ifdim\@Xpzero\p@=\z@ - \ifdim\@Xpuno\p@=\z@ - \@tdA=0.666666\p@ - \Numero\@Mcpzero{\@Chord\@tdA}% - \edef\@Mcpuno{\@Mcpzero}% - \else - \@tdA=0.666666\p@ - \Numero\@Mcpzero{\@Chord\@tdA}% - \SetCPmodule\@Mcpuno from\@ne\@Chord\@Dpuno% - \fi +\ifdim\@DXpzero\p@=\z@ + \@tdA=1.333333\p@ + \Numero\@KCzero{\@semichord\@tdA}% +\fi +\ifdim\@DYpzero\p@=\z@ + \@tdA=1.333333\p@ + \Numero\@Kpzero{\@semichord\@tdA}% +\fi % \end{macrocode} -% \dots\ from when the ``left'' direction is not perpendicular to the chord; it -% might be parallel and we must distinguish the cases for the other direction~\dots -% \begin{macrocode} -\else - \ifdim\@Xpuno\p@=\z@ - \@tdA=0.666666\p@ - \Numero\@Mcpuno{\@Chord\@tdA}% - \SetCPmodule\@Mcpzero from\@ne\@Chord\@Dpzero% - \else - \ifdim\@Ypzero\p@=\z@ - \@tdA=0.333333\p@ - \Numero\@Mcpzero{\@Chord\@tdA}% - \edef\@Mcpuno{\@Mcpzero}% -% \end{macrocode} -% \dots\ from when the left direction is oblique and the other direction is -% either parallel to the chord~\dots -% \begin{macrocode} - \else - \ifdim\@Ypuno\p@=\z@ - \@tdA=0.333333\p@ - \Numero\@Mcpuno{\@Chord\@tdA}% - \SetCPmodule\@Mcpzero from\@ne\@Chord\@Dpzero -% \end{macrocode} -% \dots\ and, finally, from when both directions are oblique with respect to -% the chord; we must see if there is an inflection point; if both direction -% point to the same half plane we have to take the complex conjugate of one -% direction so as to define the triangle we were speaking about above. -% \begin{macrocode} - \else - \@tdA=\@Ypzero\p@ \@tdA=\@Ypuno\@tdA - \ifdim\@tdA>\z@ - \ConjVect\@Dpuno to\@Dwpuno - \else - \edef\@Dwpuno{\@Dpuno}% - \fi -% \end{macrocode} -% The control sequence |\@Dwpuno| contains the right direction for forming the -% triangle; we can make the weighed subdivision of the chord according to the -% horizontal components of the directions; we eventually turn negative values -% to positive ones since we are interested in the magnitudes of the control -% vectors. -% \begin{macrocode} - \GetCoord(\@Dwpuno)\@Xwpuno\@Ywpuno - \@tdA=\@Xpzero\p@ \@tdA=\@Ywpuno\@tdA - \@tdB=\@Xwpuno\p@ \@tdB=\@Ypzero\@tdB - \DividE\@tdB by\@tdA to\@Fact - \@tdC=\p@ \advance\@tdC-\@Fact\p@ - \ifdim\@tdC<\z@ \@tdC=-\@tdC\fi - \DividE\p@ by \@Fact\p@ to\@Fact - \@tdD=\p@ \advance\@tdD-\@Fact\p@ - \ifdim\@tdD<\z@ \@tdD=-\@tdD\fi -% \end{macrocode} -% Before dividing by the denominator we have to check the directions, although -% oblique to the chord are not parallel to one another; in this case there is -% no question of a weighed subdivision of the chord -% \begin{macrocode} - \ifdim\@tdD<0.0001\p@ - \def\@factzero{1}% - \def\@factuno{1}% - \else - \DividE\p@ by\@tdC to\@factzero - \DividE\p@ by\@tdD to\@factuno - \fi -% \end{macrocode} -% We now have the subdivision factors and we call another macro for determining -% the required magnitudes -% \begin{macrocode} - \SetCPmodule\@Mcpzero from\@factzero\@Chord\@Dpzero - \SetCPmodule\@Mcpuno from\@factuno\@Chord\@Dwpuno - \fi - \fi +% The distances we are looking for are positive generally fractional numbers; +% so if the components are negative, we take the absolute values. Eventually +% we determine the absolute control point coordinates. +% \begin{macrocode} +\unless\ifdim\@DXpzero\p@=\z@ + \unless\ifdim\@DYpzero\p@=\z@ + \edef\@CosDzero{\ifdim\@DXpzero\p@<\z@ -\fi\@DXpzero}% + \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@) + \DividE\@KCzero\@tdA by\@SinDzero\p@ to \@KCzero \fi \fi +\ScaleVect\@Dzero by\@KCzero to\@CPzero +\AddVect\@Pzero and\@CPzero to\@CPzero % \end{macrocode} -% Now we have all data we need and we determine the positions of the control -% points; we do not work any more on the rotated diagram of the horizontal -% chord, but we operate on the original points and directions; all we had to -% compute, after all, were the distances of the control points along the -% specified directions; remember that the ``left'' control point is along the -% positive ``left'' direction, while the ``right'' control point precedes the -% curve node along the ``right'' direction, so that a vector subtraction must -% be done. +% We now repeat the calculations for the arc end point, taking into +% consideration that the end point direction points outwards, so that in +% computing the end point control point we have to take this fact into +% consideration by using a negative sign for the distance; in this way +% the displacement of the control point from the end point takes place +% in a backwards direction. % \begin{macrocode} -\ScaleVect\@Dzero by\@Mcpzero to\@CPzero -\AddVect\@Pzero and\@CPzero to\@CPzero -\ScaleVect\@Duno by\@Mcpuno to\@CPuno -\SubVect\@CPuno from\@Puno to\@CPuno +\ifdim\@DXpuno\p@=\z@ + \@tdA=-1.333333\p@ + \Numero\@KCuno{\@semichord\@tdA}% +\fi +\ifdim\@DYpuno\p@=\z@ + \@tdA=-1.333333\p@ + \Numero\@KCuno{\@semichord\@tdA}% +\fi +\unless\ifdim\@DXpuno\p@=\z@ + \unless\ifdim\@DYpuno\p@=\z@ + \edef\@CosDuno{\ifdim\@DXpuno\p@<\z@ -\fi\@DXpuno}% + \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@) + \DividE\@KCuno\@tdA by\@SinDuno\p@ to \@KCuno + \fi +\fi +\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. @@ -2310,7 +2958,7 @@ and the derived files curve2e.sty and curve2e.pdf. {\@XPuno\unitlength}{\@YPuno\unitlength}% % \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 memorizes the final point as the +% be added to the path. On the opposite it memorises the final point as the % initial point of the next spline % \begin{macrocode} \CopyVect\@Puno to\@Pzero @@ -2318,37 +2966,30 @@ and the derived files curve2e.sty and curve2e.pdf. \ignorespaces}% % \end{macrocode} % -% The next macro is used to determine the control vectors lengths when we have -% the chord fraction, the chord length and the direction along which to compute -% the vector; all the input data (arguments from \#2 to \#4) may be passed as -% control sequences so the calling statement needs not use any curly braces. -% \begin{macrocode} -\def\SetCPmodule#1from#2#3#4{% -\GetCoord(#4)\t@X\t@Y -\@tdA=#3\p@ -\@tdA=#2\@tdA -\@tdA=1.333333\@tdA -\@tdB=\p@ \advance\@tdB +\t@X\p@ -\DividE\@tdA by\@tdB to#1\relax -\ignorespaces}% -% \end{macrocode} % -% We finally define the overall |\Curve| macro that recursively examines an +% We finally define the overall |\Curve| macro that has two flavors: starred +% and unstarred; the former fills the curve path with the locally selected +% color, while the latter just strokes the path. Both recursively examine an % arbitrary list of nodes and directions; node coordinates are grouped within % regular parentheses while direction components are grouped within angle -% brackets. The first call of the macro initializes the drawing process and +% brackets. The first call of the macro initialises the drawing process and % checks for the next node and direction; if a second node is missing, it issues % a warning message and does not draw anything. It does not check for a change in -% direction, because it would be meaningless at the beginning of a curve. -% The second macro defines the path to the next point and checks for another node; -% if the next list item is a square bracket delimited argument, it interprets it as +% direction, because it would be meaningless at the beginning of a curve. The +% second macro defines the path to the next point and checks for another node; if +% the next list item is a square bracket delimited argument, it interprets it as % a change of direction, while if it is another parenthesis delimited argument it % interprets it as a new node-direction specification; if the node and direction -% list is terminated, it issues the stroking command and exits the recursive -% process. The |@ChangeDir| macro is just an interface for executing the regular -% |\ChangeDir| macro, but also for recursing again by recalling |\@Curve|. -% \begin{macrocode} -\def\Curve(#1)<#2>{% +% list is terminated, it issues the stroking or filling command through +% |\CurveEnd|, and exits the recursive process. The |\CurveEnd| control +% sequence has a different meaning depending on the fact that the main macro +% was starred or unstarred. The |@ChangeDir| macro is just an interface to +% execute the regular |\ChangeDir| macro, but also for recursing again by +% recalling |\@Curve|. +% \begin{macrocode} +\def\Curve{\@ifstar{\let\fillstroke\fillpath\Curve@}% +{\let\fillstroke\strokepath\Curve@}} +\def\Curve@(#1)<#2>{% \StartCurveAt#1WithDir{#2}% \@ifnextchar\lp@r\@Curve{% \PackageWarning{curve2e}{% @@ -2357,20 +2998,63 @@ and the derived files curve2e.sty and curve2e.pdf. \def\@Curve(#1)<#2>{% \CurveTo#1WithDir{#2}% \@ifnextchar\lp@r\@Curve{% - \@ifnextchar[\@ChangeDir\CurveFinish}} + \@ifnextchar[\@ChangeDir\CurveEnd}} \def\@ChangeDir[#1]{\ChangeDir<#1>\@Curve} % \end{macrocode} % % 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| for a more versatile set of drawing macros; evidently nobody -% forbids to exploit the full power of the |\cbezier| original macro for cubic -% splines. +% |\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 +% cubic Bézier splines in a more comfortable way. +% +%\begin{figure}[!htb] +%\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>% +%} +%\put(50,0){\VECTOR(0,0)(45,0)\VECTOR(0,-25)(0,25) +%\Zbox(45,1)[br]{x}\Zbox(1,25)[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} +%\end{figure} +% +% As it can be seen in figure~\ref{fig:sinewave} the two diagrams should +% approximately represent a sine wave. With Bézier curves, that resort on +% polynomials, it is impossible to represent a transcendental function, but +% 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 +% 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 +% single arcs drawn with the |\CbezierBetween| macro. +% +% I believe that the set of new macrosprovided 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 +%</package> +%\fi % -% I believe that the set of new macros 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. % \Finale % \endinput |