From dbca2cc7b2da8f2a0391ea92f04ee49e3f5aa7dd Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 30 Mar 2019 21:26:00 +0000 Subject: curve2e (30mar19) git-svn-id: svn://tug.org/texlive/trunk@50663 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/curve2e/README.txt | 84 +- Master/texmf-dist/doc/latex/curve2e/curve2e.pdf | Bin 636364 -> 513014 bytes Master/texmf-dist/doc/latex/curve2e/manifest.txt | 61 - Master/texmf-dist/source/latex/curve2e/curve2e.dtx | 5807 ++++++++++++-------- Master/texmf-dist/source/latex/curve2e/ltxdoc.cfg | 7 + .../texmf-dist/tex/latex/curve2e/curve2e-v161.sty | 904 +++ Master/texmf-dist/tex/latex/curve2e/curve2e.sty | 466 +- 7 files changed, 4527 insertions(+), 2802 deletions(-) delete mode 100644 Master/texmf-dist/doc/latex/curve2e/manifest.txt create mode 100644 Master/texmf-dist/source/latex/curve2e/ltxdoc.cfg create mode 100644 Master/texmf-dist/tex/latex/curve2e/curve2e-v161.sty (limited to 'Master/texmf-dist') diff --git a/Master/texmf-dist/doc/latex/curve2e/README.txt b/Master/texmf-dist/doc/latex/curve2e/README.txt index d6345867ba9..63631d80e63 100644 --- a/Master/texmf-dist/doc/latex/curve2e/README.txt +++ b/Master/texmf-dist/doc/latex/curve2e/README.txt @@ -10,29 +10,50 @@ %% License information appended %% File README.txt for package curve2e - [2019/02/07 v.1.61 Extension package for pict2e] + [2019-03-29 v.2.0.1 Extension package for pict2e] -This file is an extension of the package pict2e.sty which extends the standard -picture LaTeX environment according to what Leslie Lamport specified in the -second edition of his LaTeX manual. -This further extension allows to draw lines and vectors with any non integer -slope parameters, to draw dashed lined of any slope, to draw arcs and curved -vectors, to draw curves where just the interpolating nodes are specified -together with the slopes at the nodes; closed paths of any shape can be filled -with color; all coordinates are treated as ordered pairs, i.e. 'complex numbers'. -Some of these features have been incorporated in the 2011 version of pict2e; -therefore this package avoids any modification to the original pict2e commands. +The package bundle curve2e is composed of the following files -Curve2e now accepts polar coordinates in addition to the usual cartesian ones; -several macros have been upgraded and a new macro for tracing cubic Bezier -splines with their control nodes specified in polar form is available. +curve2e.dtx +curve2e.pdf +README.txt +curve2e-v161.sty +ltxdoc.cfg + +curve2e.dtx is the documented TeX source file of file curve2e.sty; you get +both curve2e.sty and curve2e.pdf by running pdflatex on curve2e.dtx. +The ltxdoc.cfg file customises the way the documentation file is typeset. +This .cfg file is not subject to the LPPL licence. + +README.txt, this file, contains general information. + +Curve2e-v161.sty contains the previous version of the package; see below +why the older version might become necessary for the end user. + +Curve2e.sty is an extension of the package pict2e.sty which extends the +standard picture LaTeX environment according to what Leslie Lamport +specified in the second edition of his LaTeX manual. + +This further extension allows to draw lines and vectors with any non +integer slope parameters, to draw dashed lined of any slope, to draw arcs +and curved vectors, to draw curves where just the interpolating nodes are +specified together with the slopes at the nodes; closed paths of any shape +can be filled with color; all coordinates are treated as ordered pairs, +i.e. 'complex numbers'; coordinates may be expressed also in polar form. +Some of these features have been incorporated in the 2011 version of +pict2e; therefore this package avoids any modification to the original +pict2e commands. + +Curve2e now accepts polar coordinates in addition to the usual cartesian +ones; several macros have been upgraded and a new macro for tracing cubic +Bezier splines with their control nodes specified in polar form is available. The same applies to quadratic Bezier splines. This version solves a conflict with package eso-pic. -This version of curve2e is fully compatible with pict2e dated 2014/01/12 -version 0.2z. +This version of curve2e is almost fully compatible with pict2e dated +2014/01/12 version 0.2z. If you specify @@ -40,6 +61,37 @@ If you specify the package pict2e is automatically invoked with the specified options. +The -almost compatible- frase is necessary to explain that this version +of curve2e uses some `functions' of the LaTeX3 language that were made +available to the LaTeX developer by mid October 2018. Should the user +have an older or a basic/incomplete installation of the TeX system, +such L3 functions might not be available. This is why this +package checks the presence of the developer interface; in case +such interface is not available it falls back to the previous version +renamed curve2e-v161.sty, which is part of this bundle, and that must +not be renamed in any way. The compatibility mentioned above implies +that the user macros remain the same, but their implementation requires +the L3 interface. + +The package has the LPPL status of author maintained. + +According to the LPPL licence, you are entitled to modify this package, +as long as you fulfil the few conditions set forth by the Licence. + +Nevertheless this package is an extension to the standard LaTeX package +pict2e (2014). Therefore any change must be controlled on the +parent package pict2e, so as to avoid redefining what has already been +incorporated in the official package. + +If you prefer sending me your modifications, as long as I will maintain +this package, I will possibly include every (documented) suggestion or +modification into this package and, of course, I will acknowledge your +contribution. + +Claudio Beccari + +claudio dot beccari at gmail dot com + %% %% %% Distributable under the LaTeX Project Public License, diff --git a/Master/texmf-dist/doc/latex/curve2e/curve2e.pdf b/Master/texmf-dist/doc/latex/curve2e/curve2e.pdf index 2996792e137..519ee316798 100644 Binary files a/Master/texmf-dist/doc/latex/curve2e/curve2e.pdf and b/Master/texmf-dist/doc/latex/curve2e/curve2e.pdf differ diff --git a/Master/texmf-dist/doc/latex/curve2e/manifest.txt b/Master/texmf-dist/doc/latex/curve2e/manifest.txt deleted file mode 100644 index ec39b2d9ebc..00000000000 --- a/Master/texmf-dist/doc/latex/curve2e/manifest.txt +++ /dev/null @@ -1,61 +0,0 @@ -%% -%% This is file `manifest.txt', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% curve2e.dtx (with options: `manifest') -%% -%% Copyright (C) 2005--2019 Claudio Beccari all rights reserved. -%% License information appended -%% -File manifest.txt for package curve2e - [2019/02/07 v.1.61 Extension package for pict2e] - - -The package bundle curve2e is composed of the following files - -curve2e.dtx -curve2e.pdf -mainfest.txt -README.txt - -Manifest.txt is this file. - -curve2e.dtx is the documented TeX source file of file curve2e.sty; you get -both curve2e.sty and curve2e.pdf by running pdflatex on curve2e.dtx. - -README.txt contains general information. - -The package has the LPPL status of author maintained. - -According to the LPPL licence, you are entitled to modify this package, -as long as you fulfil the few conditions set forth by the Licence. - -Nevertheless this package is an extension to the standard LaTeX package pict2e -(2014). Therefore any change must be controlled against the parent package -pict2e so as to avoid redefining what has already been incorporated in the -official package. - -If you prefer sending me your modifications, as long as I will maintain this -package, I will possibly include every (documented) suggestion or modification -into this package. - -Claudio Beccari - -claudio.beccari@gmail.com - -%% -%% -%% Distributable under the LaTeX Project Public License, -%% version 1.3c or higher (your choice). The latest version of -%% this license is at: http://www.latex-project.org/lppl.txt -%% -%% This work is "author-maintained" -%% -%% This work consists of file curve2e.dtx, and the derived files -%% curve2e.sty and curve2e.pdf, plus the auxiliary derived files -%% README.txt and manifest.txt. -%% -%% -%% End of file `manifest.txt'. diff --git a/Master/texmf-dist/source/latex/curve2e/curve2e.dtx b/Master/texmf-dist/source/latex/curve2e/curve2e.dtx index d0672852dd7..902cd4e1a6c 100644 --- a/Master/texmf-dist/source/latex/curve2e/curve2e.dtx +++ b/Master/texmf-dist/source/latex/curve2e/curve2e.dtx @@ -29,7 +29,7 @@ README.txt and manifest.txt. \generate{\file{curve2e.sty}{\from{curve2e.dtx}{package}}} \generate{\file{README.txt}{\from{curve2e.dtx}{readme}}} -\generate{\file{manifest.txt}{\from{curve2e.dtx}{manifest}}} +\generate{\file{curve2e-v161.sty}{\from{curve2e.dtx}{v161}}} \def\tmpa{plain} \ifx\tmpa\fmtname\endgroup\expandafter\bye\fi @@ -46,25 +46,24 @@ README.txt and manifest.txt. % %<+package>\ProvidesPackage{curve2e}% %<+readme>File README.txt for package curve2e -%<+manifest>File manifest.txt for package curve2e -%<*package|readme|manifest> - [2019/02/07 v.1.61 Extension package for pict2e] -% +%<*package|readme> + [2019-03-29 v.2.0.1 Extension package for pict2e] +% %<*driver> \documentclass{ltxdoc}\errorcontextlines=9 \hfuzz 10pt \usepackage[utf8]{inputenc} \usepackage{lmodern,textcomp} \usepackage{mflogo} -\usepackage{multicol,amsmath,trace} +\usepackage{multicol,amsmath,fancyvrb,trace} \usepackage{curve2e} \GetFileInfo{curve2e.dtx} \title{The extension package \textsf{curve2e}} -\author{Claudio Beccari} -\date{Version number \fileversion; last revised \filedate.} +\author{Claudio Beccari\thanks{E-mail: \texttt{claudio dot beccari at gmai dot com}}} +\date{Version \fileversion~--~Last revised \filedate.} \providecommand*\diff{\mathop{}\!\mathrm{d}} \renewcommand\meta[1]{{\normalfont\textlangle\textit{#1}\textrangle}} -\renewcommand\marg[1]{\texttt{\{\meta{#1}\}}} +\renewcommand\marg[1]{\texttt{\char123\meta{#1}\char125}} \providecommand\oarg{} \renewcommand\oarg[1]{\texttt{[\meta{#1}]}} \providecommand\aarg{} @@ -83,13 +82,18 @@ README.txt and manifest.txt. \def\Zbox(#1){\bgroup\edef\@tempA{#1}\@Zbox} -\newcommand*\@Zbox[2][]{\fboxrule\z@\fboxsep=0.75ex\relax +\newcommand*\@Zbox[2][]{\fboxrule\z@\fboxsep=0.75ex\def\@tempB{#1}% \setbox2575\hbox{\fbox{$\relax\rule[-0.5ex]{0pt}{2.5ex}#2\relax$}}\relax \ifx\@tempB\empty \put(\@tempA){\makebox(0,0){\box2575}}\else \put(\@tempA){\makebox(0,0)[#1]{\box2575}}\fi\egroup\ignorespaces} -\begin{document} +\providecommand\setfontsize{} +\DeclareRobustCommand\setfontsize[2][1.2]{% +\linespread{#1}\fontsize{#2}{#2}\selectfont} + + +\begin{document}%\OnlyDescription \maketitle \columnseprule=0.4pt \begin{multicols}{2} @@ -100,37 +104,59 @@ README.txt and manifest.txt. % % \fi % -% \CheckSum{3138} +% \CheckSum{5560} % \begin{abstract} -% This file documents the |curve2e| extension package to the recent -% implementation of the |pict2e| bundle that has been described by Lamport -% himself in the second edition of his \LaTeX\ handbook. -% -% 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. -% -% This extension redefines a couple of commands and introduces some more drawing -% facilities that allow to draw circular arcs and arbitrary curves with the -% minimum of user intervention. This beta version is open to the contribution of -% other users as well as it may be incorporated in other people's packages. -% Please cite the original author and the chain of contributors. +% This file documents the |curve2e| extension package to the |pict2e| +% bundle implementation that has been described by Lamport +% himself in the 1994 second edition of his \LaTeX\ handbook. +% +% 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 early versions of this package; apparently there +% are no conflicts, but only the advanced features 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 minimum of user intervention. This version is open to the +% contribution of other users as well as it may be incorporated in other +% people's packages. Please cite the original author and the chain of +% contributors. % \end{abstract} % +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%\section{The configuration file} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% This package |curve2e| is distributed with a |ltxdoc.cfg| configuration +% file that contains, besides the preamble and the postamble comment lines, +% the following code line: +%\begin{verbatim} +%\AtBeginDocument{\OnlyDescription} +%\end{verbatim} +% +% If you want to type the whole documentation, comment out that code line +% in the |ltxdoc.cfg| file. This is the only modification allowed by the +% LPPL licence that does not require to change the file name. % +% For your information the initial part is about 20~pages long; the whole +% documentation is about 80~pages long. +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \section{Package \texttt{pict2e} and this extension \texttt{curve2e}} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % Package \texttt{pict2e} was announced in issue 15 of \texttt{latexnews} -% around December 2003; it was declared that the new package would replace the -% dummy one that has been accompanying every release of \LaTeXe\ since its -% beginnings in 1994. The dummy package was just issuing an info message that -% simply announced the temporary unavailability of the real package. -% -% Eventually Gäßlein and Niepraschk implemented what Lamport himself had already -% 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 what follows. +% around December 2003; it was declared that the new package would replace +% the dummy one that has been accompanying every release of \LaTeXe\ since +% its beginnings in 1994. The dummy package was just issuing an info +% message that simply announced the temporary unavailability of the real +% package. +% +% Eventually Gäßlein and Niepraschk implemented what Lamport himself had +% already 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 what follows. % \begin{enumerate} % \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 @@ -140,179 +166,217 @@ README.txt and manifest.txt. % limited number of specific glyphs contained in the special \LaTeX\ % \texttt{picture} fonts. %^^A -% \item Quarter circles were also limited in their radii for the same reason. +% \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 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. %^^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. +% \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 % 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. +% 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. %^^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 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. %^^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 There are two shapes for the arrow tips; the triangular one +% traditional with \LaTeX\ vectors, or the arrow tip with PostScript style. %^^A -% \item The |\linethickness| command changes the thickness of all lines, straight, -% curved, vertical, horizontal, arrow tipped, et cetera. +% \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 package |curve2e| adds the following features. % \begin{enumerate} -%\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. +% \item Point coordinates my be specified in both cartesian and polar form: +% internally they are handeld as cartesian coordinates, but the user can +% specify his/her points also in polar form. In order to avoid confusion +% with other grapgic packages, |curve2e| uses the usual comma separated +% couple of integer or fractional numebrs for cartesian coordinates, and +% the couple \texttt{\meta{angle}:\meta{radius}} for polar coordinates. +% All graphic object commands accept polar or cartesian coordinates 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 cartesian or polar coordinates. %^^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 Most if not all cartesian 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 as +% roto-amplification operators. %^^A -% \item Commands for specifying the way two lines or curves join to one another. +% \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 this original feature is directly 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 -% direction coefficients, but maintaining the same syntax as in the original -% \texttt{picture} environment (now available also with |pict2e|). +% \item originally 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 this functionality +% available directly with |pict2e|. % ^^A -% \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 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, +% \item A new macro |\Line| was originally defined so as to avoid the need +% to specify the horizontal projection of inclined lines; now this +% functionality id available directly with |pict2e|; but 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 -% their coordinates; this is now the normal behavior of the |\Line| macro of -% |pict2e| so that |\LINE| is now renamed |\segment|; there is no need -% to use the |\put| command with this line specification. +% \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 in this package |\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. +% \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 |\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. +% 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 -% original macro but with the vector slope limitations removed; |\Vector| gets -% 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. +% original macro but with the vector slope limitations removed; |\Vector| +% gets 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 it is redefined so as to allow -% an optional specification of the way segments for the polyline are joined to -% one another. +% accepts from two vertices up to an arbitrary (reasonably limited) number +% of 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. Vertices may be specified with polar coordinates %^^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. +% \item The |pict2e| |polygon| macro to draw closed polylines, in practice +% general polygons, has been redefined in such a way that it can accept the +% various vertices specified with polar coordinates. The |polygon*| macro +% produces a color filled polygon; the default color is black, but a +% different color may be specified with the usual |\color| command given +% within the same group where |\polygon*| is enclosed. %^^A -% \item Two new macros |\VectorArc| and |\VectorARC| are defined in order to -% draw circular arcs with an -% arrow at one or both ends. +% \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 with the current color. 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 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. +% \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 |\Curve| is a recursive macro that can draw an unlimited (reasonably -% low) number of connected Bézier spline arcs with continuos tangents except -% for cusps; these arcs require only the specification of te tangent -% direction at the interpolation nodes. It is possible to use a lower level -% macro |\CbezierTo| that does the same but lets the user specify the control -% points of each arc; it is more difficult to use but it is more performant. +% \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 current +% color. %^^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. +% \item |\Curve| is a recursive macro that can draw an unlimited +% (reasonably limited) number of connected Bézier spline arcs with +% continuous tangents except for cusps; these arcs require only the +% specification of the 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 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 +% 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. +% convenient to use the starred version of the |\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 (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 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. 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. +% 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 been +% done yet. +% +% In order to make the necessary calculations many macros have been defined +% so as to use complex number arithmetics to manipulate point coordinates, +% directions (unit vectors, also known as `versors'), rotations and the +% like. In the first versions of this package the trigonometric functions +% were also been defined in a way that the author believed to be more +% efficient than those defined by the \texttt{trig} package; in any case +% the macro names were sufficiently different to accommodate both +% definition sets in the same \LaTeX\ run. With the progress of the +% \LaTeX\,3 language, the |xfp| has recently become available, by which any +% sort of calculations can be done with floating point numbers; therefore +% the most common algebraic, irrational and transcendental functions can +% be computed in the background with the stable internal floating point +% facilities. We maintain some computation with complex number algebra, +% but use the |xfp| functionalities for other computations. +% +% 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 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. 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 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. +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Summary and examples of new commands} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% 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 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. +% \item This package |curve2e| calls directly the \LaTeX\ packages |color| +% and |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 see +% 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: +% \item The user is offered new commands in order to control the line +% terminators and the line joins; specifically: % \begin{itemize} % \item |\roundcap|: the line is terminated with a semicircle; % \item |\squarecap|: the line is terminated with a half square; @@ -320,54 +384,86 @@ README.txt and manifest.txt. % \item |\beveljoin|: two lines are joined with a bevel join; % \item |\miterjoin|: two lines are joined with a miter join. % \end{itemize} -% 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. +% 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 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 -% width, but if a command refers to the internal value |\@halfwidth| the line will -% be drawn with a thickness of 0.5\,pt. The command |\linethickness| redefines the -% above internals but does not change the default width value; all these width -% specifications apply to all lines, straight ones, curved ones, circles, ovals, -% vectors, dashed, et cetera. It's better to recall that |\thinlines| and -% |\thicklines| are declarations that do not take arguments; on the opposite the -% other two commands follow the standard syntax: +% \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 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 width, but if a command refers to the internal value +% |\@halfwidth| the line will be drawn with a thickness of 0.5\,pt. The +% command |\linethickness| redefines the above internals but does not +% change the default width value; all these width specifications apply to +% all lines, straight ones, curved ones, circles, ovals, vectors, dashed, +% et cetera. It's better to recall that |\thinlines| and |\thicklines| are +% declarations that do not take arguments; on the opposite the other two +% commands follow the standard syntax: % \begin{flushleft} % |\linethickness|\marg{dimensioned value}\\ % |\defaultlinewidth|\marg{dimensioned value} % \end{flushleft} -% where \meta{dimensioned value} means a length specification complete of its -% units or a dimensional expression. +% 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. +% \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 -% 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 -% using command |\put|. -% The same applies to the vector commands |\Vector| and |\VECTOR|. Experience has -% shown that the commands intended to join two specified coordinates are -% particularly useful. +% 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 using command |\put|. +% The same applies to the vector commands |\Vector| and |\VECTOR| and +% |\VVECTOR|; the latter command behaves as |\VECTOR| but draws a vector +% with arrow tips at both ends; furthermore this command is available only with this new release of the |curve2e| package. +% Experience has shown that the commands intended to join two specified +% points are particularly useful. +% \begin{figure} +% \begin{minipage}{.48\textwidth} +% \begin{verbatim} +% \unitlength=.5mm +% \begin{picture}(60,20) +% \put(0,0){\GraphGrid(80,20)} +% \put(0,0){\vector(1.5,2.3){10}} +% \put(20,0){\Vector(10,15.33333)} +% \VECTOR(40,0)(50,15.33333) +% \ifdefined\VVECTOR \VVECTOR(60,0)(80,10)\fi +% \end{picture} +% \end{verbatim} +% \end{minipage} +% \hfill +% \begin{minipage}{.48\textwidth}\centering +% \unitlength=.5mm +% \begin{picture}(60,20) +% \put(0,0){\GraphGrid(80,20)} +% \put(0,0){\vector(1.5,2.3){10}} +% \put(20,0){\Vector(10,15.33333)} +% \VECTOR(40,0)(50,15.33333) +% \ifdefined\VVECTOR \VVECTOR(60,0)(80,10)\fi +% \end{picture} +% \end{minipage} +% \caption{Three (displaced) identical vectors obtained with the three +% vector macros\ifdefined\VVECTOR; a double tipped vector is also shown\fi.}\label{fig:vectors} +% \end{figure} %^^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 order the specified -% points; the syntax is: +% \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 join in order the +% specified points; the syntax is: % \begin{flushleft} %\cs{polyline}\oarg{optional join style}\parg{$P_1$}\parg{$P_2$}\texttt{...}\parg{$P_n$} % \end{flushleft} -% See figure~\ref{fig:polyline} where a regular pentagon is drawn; usage of polar -% coordinates is also shown. +% 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} @@ -386,29 +482,87 @@ README.txt and manifest.txt. % \end{picture}\hspace*{2em} % \end{minipage} % \caption{Polygonal line obtained by means of the \texttt{\string\polyline} -% command; coordinates are in polar form.} +% command; vertex coordinates are in polar form.} % \label{fig:polyline} % \end{figure} % -% Although you can draw polygons with |\polyline|, as it was done in -% figure~\ref{fig:polyline}, do not confuse this command with the command -% |\polygon| defined in |pict2e| 2009; the latter automatically joins the -% 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. -%^^A -% \item The new command |\Dashline| (alias: |\Dline| for backwards compatibility) +% 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)[l]{40,0}} +%\put(90:30){\circle*{1.5}}\put(90:31){\makebox(0,0)[bc]{90:30}} +%\put(60:30){\circle*{1.5}}\put(60:3){\Zbox(60:27)[bc]{60{:}30}} +%\put(30,30){\circle*{1.5}}\put(30.7,30.7){\makebox(0,0)[bc]{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} +% +% A similar example may be obtained with the |\polygon| macro that does +% not require to terminate the polyline at the starting point. +% Figure~\ref{fig:polygon} shows how to get a coloured filled pentagon. +% +% \begin{figure}[!ht] +% \begin{minipage}{.48\linewidth} +% \begin{verbatim} +% \unitlength=.5mm +% \begin{picture}(40,32)(-20,-20) +% \color{magenta} +% \polygon*(90:20)(162:20)(234:20)(306:20)(378:20) +% \end{picture} +% \end{verbatim} +% \end{minipage} +% \hfill +% \begin{minipage}{.48\linewidth}\raggedleft +% \unitlength=.5mm +% \begin{picture}(40,32)(-20,-20) +% \color{magenta} +% \polygon*(90:20)(162:20)(234:20)(306:20)(378:20) +% \end{picture}\hspace*{2em} +% \end{minipage} +% \caption{A pentagon obtained by means of the \texttt{\string\polygon*} +% command; vertex coordinates are in polar form.} +% \label{fig:polygon} +% \end{figure} +% +% \item The new command |\Dashline| (alias: |\Dline| for backwards +% compatibility) % \begin{flushleft} % |\Dashline|\parg{first point}\parg{second point}\marg{dash length} % \end{flushleft} -% draws a dashed line containing as many dashes as possible, long as specified, -% and separated by a gap exactly the same size; actually, in order to make an -% even gap-dash sequence, the desired dash length is used to do some computations -% in order to find a suitable length, close to the one specified, such that the -% distance of the end points is evenly divided in equally sized dashes and gaps. -% The end points may be anywhere in the drawing area, without any constraint on -% the slope of the joining segment. The desired dash length is specified as a -% fractional multiple of |\unitlength|; see +% draws a dashed line containing as many dashes as possible, just as long +% as specified, and separated by a gap exactly the same size; actually, +% in order to make an even gap-dash sequence, the desired dash length is +% used to do some computations in order to find a suitable length, close +% to the one specified, such that the distance of the end points is evenly +% divided in equally sized dashes and gaps. +% The end points may be anywhere in the drawing area, without any +% constraint on the slope of the joining segment. The desired dash length +% is specified as a fractional multiple of |\unitlength|; see % figure~\ref{fig:dashline}. % \begin{figure}[!ht] % \begin{minipage}{.48\textwidth} @@ -424,6 +578,7 @@ README.txt and manifest.txt. % \put(0,25){\circle*{2}} % \put(20,40){\circle*{2}} % \Dotline(0,0)(40,40){2} +% \put(40,40){\circle*{2}} % \end{picture} % \end{verbatim} % \end{minipage} @@ -439,50 +594,120 @@ README.txt and manifest.txt. % \Dashline(0,25)(20,40){4} % \put(0,25){\circle*{2}} % \put(20,40){\circle*{2}} -% \Dotline(0,0)(40,40){2} +% \Dotline(0,0)(40,40){2} +% \put(40,40){\circle*{2}} % \end{picture} % \end{minipage} % \caption{Dashed lines and graph grid}\label{fig:dashline} % \end{figure} +% Another example of usage of cartesian and polar coordinates usage is +% shown in figure~\ref{fig:polar} together with its code. +% +%\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{blue}% +%\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{blue}% +%\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 -%\item Analogous to |\Dashline|, a new command |\Dotline| draws a dotted line with -% the syntax: +%\item Analogous to |\Dashline|, a new command |\Dotline| draws a dotted +% line with the syntax: % \begin{flushleft} % |\Dotline|\parg{first point}\parg{end point}\marg{dot gap} % \end{flushleft} -% See figures~\ref{fig:dashline} and~\ref{fig:dottedlines} for examples. +% See figures~\ref{fig:dashline} and~\ref{fig:dottedlines} for examples. +% +%\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} %^^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 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. +% 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 +% 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 on 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. Several examples of usage of such grid are shown in several figures. %^^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° 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° 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. -% -% These trigonometric functions are used within the complex number macros; but if -% the user wants to use them the syntax is the following: +% \item New trigonometric function macros have been computed by means of +% the functionalities of the |xfp| package. The compared to the other +% existing macros is that angles are specified in sexagesimal degrees, so +% that the user needs not transform to radians. The computations are done +% taking into account that abnormal values can occasionally be avoided, +% for example $\tan90^\circ$ must be avoided and replaced with a suitably +% large number, because the TeX\ system does not handle “infinity”. +% +% These trigonometric functions are used within the complex number macros; +% but if the user wants to use them the syntax is the following: %\begin{flushleft} % \cs{SinOf}\meta{angle}\texttt{to}\meta{control sequence} %\\ @@ -492,19 +717,21 @@ README.txt and manifest.txt. %\end{flushleft} % 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: +% \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} % \cs{Arc}\parg{center}\parg{starting point}\marg{angle}\\ % \cs{VectorArc}\parg{center}\parg{starting point}\marg{angle}\\ % \cs{VectorARC}\parg{center}\parg{starting point}\marg{angle}\\ %\end{flushleft} -% If the angle is specified numerically it must be enclosed in braces, while if it -% is specified with a control sequence the braces (curly brackets) are not -% necessary. The above macro |\Arc| draws a simple circular arc without arrows; -% |\VectorArc| draws an arc with an arrow tip at the ending point; |\VectorARC| -% draws an arc with arrow tips at both ends; see figure~\ref{fig:arcs}. +% 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 necessary. The above macro |\Arc| draws a simple +% circular arc without arrows; |\VectorArc| draws an arc with an arrow +% tip at the ending point; |\VectorARC| draws an arc with arrow tips at +% both ends; see figure~\ref{fig:arcs}. % \begin{figure} % \begin{minipage}{.48\textwidth} % \begin{verbatim} @@ -534,20 +761,22 @@ README.txt and manifest.txt. % \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 -% plane, but also as operators so as to scale and rotate other objects. In the -% following \meta{vector} means a comma separated pair of fractional numbers, -% \meta{vector macro} means a macro the contains a comma separated pair of -% fractional numbers; \meta{angle macro} means a macro that contains the angle -% of a vector in sexagesimal degrees; \meta{argument} means a brace delimited -% numeric value, even a macro; \textit{macro} is a valid macro name, that -% is a backslash followed by letters, or anything else that can receive a -% definition. A `direction' of a vector is its versor; the angle of a vector -% is the angle between the vector and the positive $x$ axis in counterclockwise -% direction, generally directly used in the Euler formula $ \vec{v} = -% Me^{\mathrm{j}\varphi}$. +% \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 (here we use only cartesian +% coordinates). They are used to address specific points in the drawing +% plane, but also as operators so as to scale and rotate other objects. In +% the following \meta{vector} means a comma separated pair of fractional +% numbers, \meta{vector macro} means a macro that contains a comma +% separated pair of fractional numbers; \meta{angle macro} means a macro +% that contains the angle of a vector in sexagesimal degrees; +% \meta{argument} means a brace delimited numeric value, even a macro; +% \textit{macro} is a valid macro name, i.e.~a backslash followed by +% letters, or anything else that can receive a definition. A +% \emph{direction} of a vector is its versor;% the angle of a vector is +% the angle between the vector and the positive $x$ axis in +% counterclockwise direction, as generally directly used in the +% Euler formula $ \vec{v} = Me^{\mathrm{j}\varphi}$. % % {\footnotesize\begin{itemize} % \item |\MakeVectorFrom|\meta{two arguments}|to|\meta{vector macro} @@ -570,31 +799,85 @@ README.txt and manifest.txt. % \end{itemize}} %^^A % \item General curves can be drawn with the |pict2e| macro |\curve| but it -% 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 -% the control points, while letting the user specify only the nodes through -% which the curve must pass, and the tangent direction of the curve in such -% nodes. This macro is |\Curve| and must be followed by an ``unlimited'' -% sequence of node-direction coordinates as a quadruple defined as +% 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 the control points, while letting the user specify only the +% nodes through which the curve must pass, and the tangent direction of the +% curve in such nodes. Such commands are the following: +%\begin{itemize} +% +%\item \cs{Curve} to draw a sequence of arcs as explained above, using +% third order (cubic) Bézier splines. The starred version of this command +% fills the internal part of the curve with the current color; if the last +% arc finishes where the fist arc starts, it is clear what is the interior; +% if it does not, the driver (not the code of this package, but the +% driver between this code and the physical representation on paper or +% screen) assumes a straight line closure of the whole path. +% +%\item \cs{Qurve} similar to |\Curve|, but with second order (quadratic) +% Bézier splines. The starred version fills the interior with the current +% color +% +%\item \cs{CurveBetween} draws a single cubic Bézier spline between two +% given nodes and with two given directions vectors. +% +%\item \cs{CBezierBetween} draws a single cubic Bézier spline between two +% given nodes, with two given directions versors along which the +% control node distances are specified. This is the most general macro +% (rather difficult to use) with which not only the arc end points are +% specified but also the control nodes coordinates are given. +% +%\end{itemize} +% +% The main macro is |\Curve| and must be followed by an +% ``unlimited'' sequence of node-direction coordinates as a quadruple +% defined as %\[ % \parg{node coordinates}\aarg{direction vector} %\] -% Possibly if a sudden change of direction has to be performed (cusp) another item -% can be inserted after one of those quadruples in the form +% Possibly if a sudden change of direction has to be performed (cusp) +% another item can be inserted after one of those quadruples in the form %\[ % \mbox{\dots\parg{...}\aarg{...}\oarg{new direction vector}\parg{...}\aarg{...}\dots} %\] +% +% Possibly it is necessary to specifiy the “tension” or the “looseness” +% of a specific Bézier arc; such tension parameters range from 0 (zero) +% to~4; the zero value implies a very stiff arc, as if it was a string +% subject to a high tension (i.e. with zero looseness); a value of~4 +% implies a very low tension (very high looseness), almost as if the string +% was not subject to any tension. In \MF\ or \MP\ language such a concept +% is used very often; in this package, where the Hobby algorithms are +% not used, the parameter value appears to mean the opposite of tension. +% A couple of comma separated tension values may be optionally used, they +% are separated with a semicolon form the direction vector, +% and they apply to the arc terminating with the last node; their +% specification must +% precede any possible change of tangent according to this +% syntax\footnote{The tension may be specified only for cubic splines, +% because the quadratic ones do not use enough parameters to control the +% tension; not all commands for drawing cubic splines accept this +% optional tension specification.}: +%\[ +%\mbox{\dots\parg{...}\aarg{\upshape{\em direction vector}\texttt{;}{\em start tension}|,|{\em end tension}}\parg{...}\aarg{...}\dots} +%\] +% % The |\Curve| macro does not (still) have facilities for cycling the path, -% that is to close the path from the last specified node-direction to the first -% specified node-direction. The tangent direction need not be specified with -% a unit vector, although only its direction is relevant; the scaling of the -% specified direction vector to a unit vector is performed by the macro itself. +% that is to close the path from the last specified node-direction to the +% first specified node-direction; but, as already mentioned, if the ending +% node of the last arc does not coincide with the stating node of the +% first arc, a straight line is assumed to join such nodes; this line does +% not get drawn, but with starred commands no lines are drawn because only +% the interior is coloured. +% The tangent direction need not be specified with a unit vector, although +% only its direction is relevant; the scaling of the specified direction +% vector to a unit vector is performed by the macro itself. % Therefore one cannot specify the fine tuning of the curve convexity as it -% 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} +% can be done with other programs or commands, as for example with \MF\ +% or the |pgf/tikz| package and environment. See figure~\ref{fig:curve} for +% an example. % \begin{figure}[htb] % \begin{minipage}{.48\textwidth} % \begin{verbatim} @@ -650,106 +933,2788 @@ README.txt and manifest.txt. % 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. +% Figure~\ref{fig:arcspline} shows a geometric construction that contains the geometric elements and symbols used to determine the parameters of a cubic spline required to draw a quarter circle. This construction containa many of the commands described so far. % -% \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 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 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 -% facilities offered by the |dvips| driver. -% -% Another package |ebezier| performs about the same as |curve2e| but draws its -% Bézier curves by using little dots partially superimposed to one another. The -% documentation is quite interesting but since it explains very clearly what -% 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|. +%\begin{figure}[p] +%\begin{minipage}{\linewidth}\small +%\begin{verbatim} +%\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$}}% +%\segment(0,-40)(-40,0)\segment(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}}% +%\segment(-40,0)(-20,20)\put(-20,20){\circle*{2}}% +%\put(-20,21.5){\makebox(0,0)[b]{$C_1$}}% +%\segment(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} +%\end{verbatim} +%\end{minipage}\vspace{\stretch{1}} % -% \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. +%\begin{minipage}{\linewidth}\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$}}% +%\segment(0,-40)(-40,0)\segment(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}}% +%\segment(-40,0)(-20,20)\put(-20,20){\circle*{2}}% +%\put(-20,21.5){\makebox(0,0)[b]{$C_1$}}% +%\segment(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} +%\end{minipage} +%\caption{The code to display the Nodes and control points for an arc to +% be approximated with a cubic Bézier spline} +%\label{fig:arcspline} +%\end{figure} % -% Josef Tkadlec and the author collaborated extensively in order to make a better -% real long division so as to get the fractional part and to avoid as much as -% possible any numeric overflow; many Josef's ideas are incorporated in the macro -% that is implemented in this package, although the macro used by Josef is -% slightly different from this one. Both versions aim at a better accuracy and -% at widening the operand ranges. % -% Daniele Degiorgi spotted a fault in the kernel definition of |\linethickness| -% that heavily influenced also |curve2e|; see below. +% To show what you can do with |\CurveBetween| see the code and result +% shown in figure~\ref{fig:curva-due-punti}. Notice the effect of changing the directions at both or a the end nodes os a single cubic spline. The directions are conveniently expressed with unit vectors described by polar coordinates. + +%\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 with different start and end slopes}\label{fig:curva-due-punti} +%\end{figure} % -% Thanks also to Jin-Hwan Cho and Juho Lee who suggested a small but crucial -% modification in order to have \texttt{curve2e} work smoothly also with XeTeX -% (XeLaTeX). Actually if version 0.2x or later, dated 2009/08/05 or later, of -% |pict2e| is being used, such modification is not necessary, but it's true -% that it becomes imperative if older versions are used. +% A little more complicated is the use of the |\CBezierBetween| macro, +% figure~\ref{fig:Cbezier}. The directions are specified with unit +% vectors in polar form; the control points are specified by adding their +% distances from their neighbouring nodes; actually the right distance +% is maintained to the value~1, while the left one increases from~4 to~10. +% The black line corresponds to the standard |\CurveBetween| where the +% default distance is computed by default to trace an arc of a circle and +% is approximately~3.5. % -% \StopEventually{% -% \begin{thebibliography}{9} -% \bibitem{pict2e} Gäßlein H., Niepraschk R., and Tkadlec J. -% \emph{The \texttt{pict2e} -% package}, 2014, PDF documentation of \texttt{pict2e} is part of any modern complete distribution of the \TeX\ system. In case of a basic or partial system installation, the package may be installed by means of the specific facilities of the distribution. It may be read by means of the line command \texttt{texdoc pict2e}. -% \end{thebibliography} -% } +%\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} % -% \section{Source code} -% \subsection{Some preliminary extensions to the \texttt{pict2e} package} -% 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] -\RequirePackage{xparse} -% \end{macrocode} +% In figure~\ref{fig:tensions} the effect of tension specification is +% shown. The red line corresponds to the default tension, since the +% tension values are not specified. The black lines correspond to the +% various values used in the various commands to the |\Curve| macro. +% With a tension of zero, the spline is almost coincident wit the +% horizontal base line of the frame. Increasing the tension value +% to~4.5, the curved becomes taller and taller, until it wraps itself +% displaying an evident loop. We would say that the value of ~2 is a +% reasonable maximum and increasing that tension value is just to +% obtain special effects. % -% 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{figure}[!htb]\centering +%\begin{minipage}{0.48\textwidth}\small +%\begin{verbatim} +%\raggedleft\unitlength=0.01\textwidth +%\begin{picture}(70,70) +%\put(0,0){\color{blue}\frame(70,70){}} +%\put(0,0){\color{red}\Curve(0,0)<1,1>(70,0)<1,-1>} +%\Curve(0,0)<1,1>(70,0)<1,-1;0,0> +%\Curve(0,0)<1,1>(70,0)<1,-1;0.2,0.2> +%\Curve(0,0)<1,1>(70,0)<1,-1;2,2> +%\Curve(0,0)<1,1>(70,0)<1,-1;4.5,4.5> +%\Curve(0,0)<1,1>(70,0)<1,-1;0,3> +%\Curve(0,0)<1,1>(70,0)<1,-1;3,0> +%\end{picture} +%\end{verbatim} +%\end{minipage} +%\hfill +%\begin{minipage}{0.46\textwidth} +%\raggedleft\unitlength=0.01\textwidth +%\begin{picture}(70,70) +%\put(0,0){\color{blue}\framebox(70,70){}} +%\put(0,0){\color{red}\Curve(0,0)<1,1>(70,0)<1,-1>} +%\Curve(0,0)<1,1>(70,0)<1,-1;0,0> +%\Curve(0,0)<1,1>(70,0)<1,-1;0.2,0.2> +%\Curve(0,0)<1,1>(70,0)<1,-1;2,2> +%\Curve(0,0)<1,1>(70,0)<1,-1;4.5,4.5> +%\Curve(0,0)<1,1>(70,0)<1,-1;0,3> +%\Curve(0,0)<1,1>(70,0)<1,-1;3,0> +%\end{picture} +%\end{minipage} +%\caption{The effects of tension factors}\label{fig:tensions} +%\end{figure} +% +% Figure~\ref{fig:sinewave} displays two approximations of a sine wave; +% Bézier splines can approximate transcendental curves, but the +% approximation may be a poor one, depending on the approximated curve, +% if few arcs are used to draw it. With arcs specified with more +% complicated macros the approximation is better even with a lower number +% of arcs. With many arcs it is possible to approximate almost anything. +% On the left side a modest approximation is obtained with just three +% standard arcs obtained with |\Curve| and four node specifications; +% on the right we have just two arcs created with |CBezierBetween| +% with tension specification and control point distances; this drawing +%is almost undistinguishable from a real sinusoid. +% +%\begin{figure}[!htb] +%\begin{minipage}{\linewidth} +%\begin{verbatim} +%\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,0)[br]{x}\Zbox(0,26)[tl]{y} +%\Curve(0,0)<77:1>(10,20)<1,0;2,0.4>(30,-20)<1,0;0.4,0.4>(40,0)<77:1;0.4,2> +%} +%\put(55,0){\VECTOR(0,0)(45,0)\VECTOR(0,-25)(0,25) +%\Zbox(45,0)[br]{x}\Zbox(0,26)[tl]{y} +%\CbezierBetween0,0And20,0WithDirs77:1And-77:1UsingDists28And{28} +%\CbezierBetween20,0And40,0WithDirs-77:1And77:1UsingDists28And{28}} +%\end{picture} +%\end{verbatim} +%\end{minipage}\vspace{\baselineskip} +% +%\begin{minipage}{\linewidth} +%\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,0)[br]{x}\Zbox(0,26)[tl]{y} +%\Curve(0,0)<77:1>(10,20)<1,0;2,0.4>(30,-20)<1,0;0.4,0.4>(40,0)<77:1;0.4,2> +%} +%\put(55,0){\VECTOR(0,0)(45,0)\VECTOR(0,-25)(0,25) +%\Zbox(45,0)[br]{x}\Zbox(0,26)[tl]{y} +%\CbezierBetween0,0And20,0WithDirs77:1And-77:1UsingDists28And{28} +%\CbezierBetween20,0And40,0WithDirs-77:1And77:1UsingDists28And{28}} +%\end{picture} +%\end{minipage} +%\caption{A sequence of arcs; the left figure has been drawn with the +% \cs{Curve} command with a sequence of four couples of point-direction +% arguments; the right figure has been drawn with two commands +% \cs{CbezierBetween} that include also the specification of the control +% points} +%\label{fig:sinewave} +%\end{figure} +% +% In figure~\ref{fig:quadratic-arcs} some lines drawn with quadratic +% splines by means of the |\Qurve| macro are shown. In the left there are +% some open and closed curves inscribed within a square. On the right a +% “real" circle is compared to a quadratic spline circle; the word “real” +% is emphasised because it actually is an approximation with four +% quarter-circle cubic splines that, in spite of being drawn with third +% degree parametric polynomials, approximate very well a real circle; on +% the opposite the quadratic spline circle is clearly a poor approximation +% even if the maximum radial error amounts just to about 6\% of the radius. +% +%\begin{figure}[p] +%\begin{minipage}{\linewidth} +%\begin{Verbatim}[fontsize=\setfontsize{7.75}] +%\unitlength=0.0045\textwidth +%\begin{picture}(100,100) +%\put(0,0){\framebox(100,100){}} +%\put(50,50){% +% \Qurve(0,-50)<1,0>(50,0)<0,1>(0,50)<-1,0>(-50,0)<0,-1>(0,-50)<1,0> +%\color{green} +% \Qurve*(0,-50)<0,1>(50,0)<1,0>[-1,0](0,50)<0,1>[0,-1](-50,0)<-1,0>[1,0](0,-50)<0,-1> +%} +%\Qurve(0,0)<1,4>(50,50)<1,0>(100,100)<1,4> +%\put(5,50){\Qurve(0,0)<1,1.5>(22.5,20)<1,0>(45,0)<1,-1.5>% +%(67.5,-20)<1,0>(90,0)<1,1.5>} +%\Zbox(0,0)[tc]{0,0}\Zbox(100,0)[tc]{100,0} +%\Zbox(100,100)[bc]{100,100}\Zbox(0,100)[bc]{0,100} +%\Pall[2](0,0)\Pall[2](100,0)\Pall[2](100,100)\Pall[2](0,100) +%\end{picture} +%\hfill +%\begin{picture}(100,100) +%\put(0,0){\framebox(100,100){}} +%\put(50,50){% +%\Qurve(0,-50)<1,0>(50,0)<0,1>(0,50)<-1,0>(-50,0)<0,-1>(0,-50)<1,0> +%\Curve(0,-50)<1,0>(50,0)<0,1>(0,50)<-1,0>(-50,0)<0,-1>(0,-50)<1,0>} +%\Zbox(50,50)[t]{O}\Pall[2](50,50)\put(50,50){\Vector(45:50)}\Zbox(67,70)[tl]{R} +%\end{picture} +%\end{Verbatim} +%\end{minipage}\vspace{2\baselineskip} +% +%\begin{minipage}{\linewidth} +%\unitlength=0.0045\textwidth +%\begin{picture}(100,100) +%\put(0,0){\framebox(100,100){}} +%\put(50,50){\Qurve(0,-50)<1,0>(50,0)<0,1>(0,50)<-1,0>(-50,0)<0,-1>(0,-50)<1,0>} +%\put(50,50){\color{green}% +%\Qurve*(0,-50)<0,1>(50,0)<1,0>[-1,0](0,50)<0,1>[0,-1](-50,0)<-1,0>[1,0](0,-50)<0,-1>} +%\Qurve(0,0)<1,4>(50,50)<1,0>(100,100)<1,4> +%\put(5,50){\Qurve(0,0)<1,1.5>(22.5,20)<1,0>(45,0)<1,-1.5>(67.5,-20)<1,0>(90,0)<1,1.5>} +%\Zbox(0,0)[tc]{0,0}\Zbox(100,0)[tc]{100,0} +%\Zbox(100,100)[bc]{100,100}\Zbox(0,100)[bc]{0,100} +%\Pall[2](0,0)\Pall[2](100,0)\Pall[2](100,100)\Pall[2](0,100) +%\end{picture} +%\hfill +%\begin{picture}(100,100) +%\put(0,0){\framebox(100,100){}} +%\put(50,50){\Qurve(0,-50)<1,0>(50,0)<0,1>(0,50)<-1,0>(-50,0)<0,-1>(0,-50)<1,0> +%\Curve(0,-50)<1,0>(50,0)<0,1>(0,50)<-1,0>(-50,0)<0,-1>(0,-50)<1,0>} +%\Zbox(50,50)[t]{O}\Pall[2](50,50)\put(50,50){\Vector(45:50)}\Zbox(67,70)[tl]{R} +%\end{picture} +%\end{minipage} +% +%\caption{\rule{0pt}{4ex}Several graphs drawn with quadratic Bézier splines. On the right a quadratic spline circle is compared with a cubic line circle.} +%\label{fig:quadratic-arcs} +%\end{figure} +% +% Notice that the previous version of |curve2e| contained an error and +% would color the outside of the green four-pointed star. +% The |curve2e-v161|, attached to this bundle, has been corrected; +% therefore it is not actually identical to the previous version, +% although the latter one performed correctly for everything else except +% for color-filled quadratic paths. +% +% \end{enumerate} +% +% +% 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 released in 1994; in the |latexnews| news-letter of December +% 2003; the first implementation was 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. +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Remark} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% 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 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 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 facilities offered by the |dvips| driver. +% +% Another package |ebezier| performs about the same as |curve2e| but draws +% its Bézier curves by using little dots partially superimposed to one +% another. The documentation is quite interesting but since it explains +% very clearly what exactly are the Bézier splines. Apparently |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|. +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Acknowledgements} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% 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. +% +% Josef Tkadlec and the author collaborated extensively in order to make a +% better real long division so as to get correctly the quotient fractional +% part and to avoid as much as possible any numeric overflow; many Josef's +% ideas are incorporated in the macro that was implemented in the previous +% version of this package, although the macro used by Josef was slightly +% different. Both versions aim/aimed at a better accuracy and at widening +% the operand ranges. In this version we abandoned the long division macro, +% and substituted it with the floating point division provided by the +% |xfp| package. +% +% Daniele Degiorgi spotted a fault in the kernel definition of +% |\linethickness| that heavily influenced also |curve2e|; see below in +% the code documentation part. +% +% Thanks also to Jin-Hwan Cho and Juho Lee who suggested a small but +% crucial modification in order to have \texttt{curve2e} work smoothly also +% with XeTeX (XeLaTeX). Actually if version 0.2x or later, dated 2009/08/05 +% or later, of |pict2e| is being used, such modification is not necessary, +% but it's true that it becomes imperative if older versions are used. +% +% \StopEventually{% +% \begin{thebibliography}{9} +% \bibitem{pict2e} Gäßlein H., Niepraschk R., and Tkadlec J. +% \emph{The \texttt{pict2e} package}, 2014, PDF documentation of +% \texttt{pict2e}; this package is part of any modern complete distribution +% of the \TeX\ system. In case of a basic or partial system installation, +% the package may be installed by means of the specific facilities of the +% distribution. It may be read by means of the line command \texttt{texdoc +% pict2e}. +% \end{thebibliography} +% } +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Source code} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Some preliminary extensions to the \texttt{pict2e} package} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 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. +% If you want to use package \texttt{xcolor}, load it after +% \texttt{curve2e}. +% +% Here we load also the |xparse| and |xfp| packages because we use their +% functionalities; but we do load them only if they are not already loaded +% with or without options; nevertheless we warn the user who wants to load +% them explicitly, to do this action before loading \texttt{curve2e}. +% The |xfp| package is absolutely required; if this package can not found +% it in the \TeX\ system installation, the loading of this package is +% aborted, and the previous version 1.61 of |curve2e| is loaded in its +% place; the overall functionalities should non change much, nevertheless +% the functionalities of |xfp| are not available. +%\iffalse +%<*package> +%\fi +% \begin{macrocode} +\IfFileExists{xfp.sty}{% + \RequirePackage{color} + \RequirePackageWithOptions{pict2e}[2014/01/01] + \@ifl@aded{sty}{xparse}{}{\RequirePackage{xparse}} + \@ifl@aded{sty}{xfp}{}{\RequirePackage{xfp}}% +}{% + \RequirePackage{curve2e-v161}% + \PackageWarningNoLine{curve2e}{% + Package xfp is required, but apparently\MessageBreak% + such package cannot be found in this \MessageBreak% + TeX system installation\MessageBreak% + Either your installation is not complete \MessageBreak% + or it is older than 2018-10-17.\MessageBreak% + \MessageBreak% + ***************************************\MessageBreak% + Version 1.61 of curve2e has been loaded\MessageBreak% + instead of the current version\MessageBreak% + ***************************************\MessageBreak}% + \endinput +} +% \end{macrocode} +% +% 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} +\def\TRON{\tracingcommands\tw@ \tracingmacros\tw@}% +\def\TROF{\tracingcommands\z@ \tracingmacros\z@}% +% \end{macrocode} +% +% Next we define some new dimension registers that will be used by the +% subsequent macros; should they be already defined, there will not be any +% redefinition; nevertheless the macros should be sufficiently protected +% so as to avoid overwriting register values loaded by other macro +% packages. +% \begin{macrocode} +\ifx\undefined\@tdA \newdimen\@tdA \fi +\ifx\undefined\@tdB \newdimen\@tdB \fi +\ifx\undefined\@tdC \newdimen\@tdC \fi +\ifx\undefined\@tdD \newdimen\@tdD \fi +\ifx\undefined\@tdE \newdimen\@tdE \fi +\ifx\undefined\@tdF \newdimen\@tdF \fi +\ifx\undefined\defaultlinewidth \newdimen\defaultlinewidth \fi +% \end{macrocode} +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Line thickness macros} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 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 are half as thick; so when the default line thickness is specified +% to, say, 1pt, thick lines will be 1pt thick and thin lines will be 0.5pt +% thick. The default whole width of thick lines is 0,8pt, but this is +% specified in the kernel of \LaTeX\ and\slash or in \texttt{pict2e}. On +% the opposite it is necessary to redefine |\linethickness| because the +% \LaTeX\ kernel global definition does not hide the space after the closed +% brace when you enter something such as |\linethickness{1mm}| followed by +% a space or a new line.\footnote{Thanks to Daniele Degiorgi +% (\texttt{degiorgi@inf.ethz.ch}).} +% \begin{macrocode} +\gdef\linethickness#1{% +\@wholewidth#1\@halfwidth.5\@wholewidth\ignorespaces}% +\newcommand\defaultlinethickness[1]{\defaultlinewidth=#1\relax +\def\thicklines{\linethickness{\defaultlinewidth}}% +\def\thinlines{\linethickness{.5\defaultlinewidth}}\thinlines \ignorespaces}% +% \end{macrocode} +% The |\ignorespaces| at the end of these macros is for avoiding spurious +% spaces to get into the picture that is being drawn, because +% these spaces introduce picture deformities often difficult to spot and +% eliminate. +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Improved line and vector macros} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% The macro |\LIne| allows to draw a line with arbitrary inclination +% as if it was a polygonal with just two vertices; actually it joins the +% canvas coordinate origin with the specified relative coordinate; +% therefore this object must be set in place by means of a |\put| command. +% Since its starting point is always at a relative 0,0 coordinate point +% inside the box created with |\put|, the two arguments define the +% horizontal and the vertical component respectively. +% \begin{macrocode} +\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 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} +\def\segment(#1)(#2){\@killglue\polyline(#1)(#2)}% +% \end{macrocode} +% By passing its ending points coordinates to the |\polyline| macro, both +% macro arguments are a pair of coordinates, not their components; in other +% words, if $P_1=(x_1, y_2)$ and $P_2=(x_2, y_2)$, then the first argument +% is the couple $x_1, y_1$ and likewise the second argument is $x_2, y_2$. +% Notice that since |\polyline| accepts also the corner coordinates in +% polar form, also|\segment| accepts the polar form. Please remember that +% the decimal separator is the decimal \emph{point}, while the \emph{comma} +% acts as coordinate separator. This recommendation is particularly +% important for non-English speaking users, since in all other languages +% the comma must be used as the decimal separator. +% +% The |\line| macro is redefined by making use of a division routine +% performed in floating point arithmetics; for this reason the \LaTeX\ +% kernel and the overall \TeX\ system installation must be as recent as +% the release date of the \texttt{xfp} package, i.e. 2018-10-17. +% The floating point division macro receives in input two fractional +% numbers and yields on output their fractional ratio. +% Notice that this command |\line| should follow the same syntax as the +% original pre~1994 \LaTeX\ version; but the new definition accepts the +% direction coefficients in polar mode; that is, instead of specifying a +% slope of $30^\circ$ with the actual sine and cosine (or values +% proportional to such functions), for example |(0.5,0.866025)|, you may +% specify it as |(30:1)|, i.e. as a unit vector with the required slope of +% $30^\circ$. +% +% The beginning of the macro definition is the same as that of \texttt{pict2e}: +% \begin{macrocode} +\def\line(#1)#2{\begingroup + \@linelen #2\unitlength + \ifdim\@linelen<\z@\@badlinearg\else +% \end{macrocode} +% but as soon as it is verified that the line length is not negative, +% things change remarkably; in facts the machinery for complex numbers is +% invoked. This makes the code much simpler, not necessarily more +% efficient; nevertheless |\DirOfVect| takes the only macro argument (that +% actually contains a comma separated pair of fractional numbers) and +% copies it to |\Dir@line| (an arbitrarily named control sequence) after +% re-normalizing to unit magnitude; this is passed to |GetCoord| that +% separates the two components into the control sequences |\d@mX| and +% |\d@mY|; these in turn are the values that are actually operated upon by +% the subsequent commands. +% \begin{macrocode} + \expandafter\DirOfVect#1to\Dir@line + \GetCoord(\Dir@line)\d@mX\d@mY +% \end{macrocode} +% The normalised vector direction is actually formed with the directing +% cosines of the line direction; since the line length is actually the +% horizontal component for non vertical lines, it is necessary to compute +% the actual line length for non vertical lines by dividing the given +% length by the magnitude of the horizontal cosine |\d@mX|, and the line +% length is accordingly scaled: +% \begin{macrocode} + \ifdim\d@mX\p@=\z@\else + \edef\sc@lelen{\fpeval{1 / abs(\d@mX)}}\relax + \@linelen=\sc@lelen\@linelen + \fi +% \end{macrocode} +% Of course, if the line is vertical this division must not take place. +% Finally the \texttt{moveto}, \texttt{lineto} and \texttt{stroke} language +% keywords are invoked by means of the internal \texttt{pict2e} commands in +% order to draw the line. Notice that even vertical lines are drawn with +% the PDF language commands instead of resorting to the DVI low level +% language that was used in both \texttt{pict2e} and the original +% (pre 1994) \texttt{picture} commands; it had a meaning in the old times, +% but it certainly does not have any, since lines are drawn by the driver +% that produces the output in a human visible document form, not by \TeX\ +% the program. +% \begin{macrocode} + \moveto(0,0) + \pIIe@lineto{\d@mX\@linelen}{\d@mY\@linelen}% + \strokepath + \fi +\endgroup\ignorespaces}% +% \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 perform in a better way compared to the 2004 version +% that was limited to integer direction coefficients up to 999 in +% magnitude. In any case this |curve2e| version accepts polar coordinates +% as slope couples, making it much simpler to draw lines with specific +% slopes. +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Dashed and dotted lines} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 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 macros. +% +% We distinguish these macros 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 must 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 +% unity. 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 of the line length. +% The syntac is the following: +% \begin{flushleft} +% \cs{Dashline}\meta{\texttt{*}}\parg{first point}\parg{second point}\marg{dash length} +% \end{flushleft} +% where \meta{first point} contains the coordinates of the starting point +% and \meta{second point} those of the ending point; of course the +% \meta{dash length}, which equals the dash gap, is mandatory. The asterisk +% plays a specific role; in facts, if coordinates are specified in polar +% form, without the optional asterisk the dashed line is misplaced, while +% if the asterisk is specified, the whole object is pout in the proper +% position. On the opposite, if the coordinates are in cartesian form the +% \meta{first point} coordinates play the role they are supposed to do even +% without the asterisk. +% \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 + \DivideFN\DlineMod by#3 to\NumD + \NumA=\fpeval{trunc(\NumD,0)}\relax + \unless\ifodd\NumA\advance\NumA\@ne\fi + \NumB=\NumA \divide\NumB\tw@ + \DividE\DlineMod\p@ by\NumA\p@ to\D@shMod + \DividE\p@ by\NumA\p@ to \@tempa + \MultVect\V@ttC by\@tempa,0 to\V@ttB + \MultVect\V@ttB by 2,0 to\V@ttC + \advance\NumB\@ne + \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} +% +% A simpler |\Dotline| macro can draw a dotted line between two given +% points; the dots are rather small, therefore the inter dot distance is +% computed in such a way as to have the first and the last dot at the +% exact position of the dotted-line end-points; again the specified dot +% distance is nominal in 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}\meta{\texttt{*}}\parg{start point}\parg{end point}\marg{dot distance} +%\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=\fpeval{trunc(\NumD,0)}\relax + \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} +% +% 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. +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Coordinate handling} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% The new macro |\GetCoord| splits a vector (or complex number) +% specification 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| and |\multiput| commands are +% redefined to accept the same syntax; the whole work is done by +% |\SplitNod@| and its subsidiaries. +% +% Notice that package |eso-pic| uses |picture| macros in its definitions, +% but its original macro |\LenToUnit| is incompatible with this +% |\GetCoord| macro; its function is to translate real lengths into +% coefficients to be used as multipliers of the current |\unitlength|; in +% case that the |eso-pic| had been loaded, at the |\begin{document}| +% execution the |eso-pic| macro is redefined using the e-\TeX\ commands +% so as to make it compatible with these local macros.\footnote{Thanks to +% Franz-Joseph Berthold who was so kind to spot the bug.} +% \begin{macrocode} +\AtBeginDocument{\@ifpackageloaded{eso-pic}{% +\renewcommand\LenToUnit[1]{\strip@pt\dimexpr#1*\p@/\unitlength}}{}}% +% \end{macrocode} +% The above redefinition is delayed at |\AtBeginDocument| in order to have +% the possibility to check the the |eso-pic| package had actually been +% loaded. Nevertheless the code is defined here just because the origina +%l |eso-pic| macro was interfering with the algorithms of coordinate +% handling. +% +% But let us come to the real subject of this section. We define a +% |\GettCoord| macro that passes control to the service macro with the +% expanded arguments; expanding arguments allows to use macros to name +% points, instead of explicit coordinates; with this version of |curve2e| +% this facility is not fully exploited, but a creative user can use this +% feature. +% \begin{macrocode} +\def\GetCoord(#1)#2#3{% +\expandafter\SplitNod@\expandafter(#1)#2#3\ignorespaces} +\def\SplitNod@(#1)#2#3{\isnot@polar#1:!!(#1)#2#3}% +% \end{macrocode} +% The macro that detects the form of the coordinates is |\isnot@polar|; +% it 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. this macro uses delimited arguments, therefore low +% level definition syntax must be used. +% \begin{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#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} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Vectors} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 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 corresponding to the limitations specified by Lamport (integer three +% digit signed numbers) and sets up a transformation in order to make it +% possible to draw each vector as an horizontal left-to-right arrow and +% then to rotate it by its angle about its tail point; with |pict2e| 2009, +% possibly this redefinition of |\vector| is not necessary, but we do it +% as well and for the same reasons we had for redefining |\line|; actually +% there are two macros for tracing the contours that are eventually filled +% by the principal macro; each contour macro draws the vector with a +% \LaTeX\ or a PostScript styled arrow tip whose parameters are specified +% by default or may be taken from the parameters taken from the|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 |curve2e| package +% redefinitions. +% +% Because of these features the redefinitions and the new macros are +% different from those used for straight lines. +% +% We start with the redefinition of |\vector| and we use the machinery for +% vectors (as complex numbers) we used for |\line|. +% \begin{macrocode} + \def\vector(#1)#2{% + \begingroup + \GetCoord(#1)\d@mX\d@mY + \@linelen#2\unitlength +% \end{macrocode} +% As in \texttt{pict2e} we avoid tracing vectors if the slope parameters +% are both zero. +% \begin{macrocode} + \ifdim\d@mX\p@=\z@\ifdim\d@mY\p@=\z@\@badlinearg\fi\fi +% \end{macrocode} +% But we check only for the positive nature of the $l_x$ component; if it +% is negative, we simply change sign instead of blocking the typesetting +% process. This is useful also for macros |\Vector|, |\VECTOR|, and +% |\VVECTOR| to be defined in a while. +% \begin{macrocode} + \ifdim\@linelen<\z@ \@linelen=-\@linelen\fi +% \end{macrocode} +% We now make a vector with the slope coefficients even if one or the +% other is zero and we determine its direction; the real and imaginary +% parts of the direction vector are also the values we need for the +% subsequent rotation. +% \begin{macrocode} + \MakeVectorFrom\d@mX\d@mY to\@Vect + \DirOfVect\@Vect to\Dir@Vect +% \end{macrocode} +% In order to be compatible with the original \texttt{pict2e} we need to +% transform the components of the vector direction in lengths with the +% specific names |\@xdim| and |\@ydim|^^A--------! Necessario? +% \begin{macrocode} + \YpartOfVect\Dir@Vect to\@ynum \@ydim=\@ynum\p@ + \XpartOfVect\Dir@Vect to\@xnum \@xdim=\@xnum\p@ +% \end{macrocode} +% If the vector is really sloping we need to scale the $l_x$ component in +% order to get the vector total length; we have to divide by the cosine of +% the vector inclination which is the real part of the vector direction. +% We use the floating point division function; since it yields a ``factor'' +% We directly use it to scale the length of the vector. I finally memorise +% the true vector length in the internal dimension |@tdB| +% \begin{macrocode} + \ifdim\d@mX\p@=\z@ + \else\ifdim\d@mY\p@=\z@ + \else + \edef\sc@lelen{\fpeval{1 / abs(\@xnum)}}\relax + \@linelen=\sc@lelen\@linelen + \fi + \fi + \@tdB=\@linelen +% \end{macrocode} +% The remaining code is definitely similar to that of \texttt{pict2e}; the +% real difference consists in the fact that the arrow is designed by itself +% without the stem; but it is placed at the vector end; therefore the first +% statement is just the transformation matrix used by the output driver to +% rotate the arrow tip and to displace it the right amount. But in order +% to draw only the arrow tip I have to set the |\@linelen| length to zero. +% \begin{macrocode} +\pIIe@concat\@xdim\@ydim{-\@ydim}\@xdim{\@xnum\@linelen}{\@ynum\@linelen}% + \@linelen\z@ + \pIIe@vector + \fillpath +% \end{macrocode} +% Now we can restore the stem length that must be shortened by the +% dimension of the arrow; by examining the documentation of \texttt{pict2e} +% we discover that we have to shorten it by an approximate amount of $AL$ +% (with the notations of \texttt{pict2e}, figs~10 and~11); the arrow tip +% parameters are stored in certain variables with which we can determine +% the amount of the stem shortening; if the stem was too short and the new +% length is negative, we avoid designing such a stem. +% \begin{macrocode} + \@linelen=\@tdB + \@tdA=\pIIe@FAW\@wholewidth + \@tdA=\pIIe@FAL\@tdA + \advance\@linelen-\@tdA + \ifdim\@linelen>\z@ + \moveto(0,0) + \pIIe@lineto{\@xnum\@linelen}{\@ynum\@linelen}% + \strokepath\fi + \endgroup} +% \end{macrocode} +% +% We define the macro that does not require the specification of the +% length or the $l_x$ length component; the way the new |\vector| macro +% works does not actually require this specification, because \TeX\ can +% compute the vector length, provided the two direction components are +% exactly the horizontal and vertical vector components. If the horizontal +% component is zero, the actual length must be specified as the vertical +% component. The object defined with |\Vector|, as well as |\vector|, +% must be put in place by means of a |\put| command. +% \begin{macrocode} +\def\Vector(#1){{% +\GetCoord(#1)\@tX\@tY +\ifdim\@tX\p@=\z@ + \vector(\@tX,\@tY){\@tY}% +\else + \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. +% \begin{macrocode} +\def\VECTOR(#1)(#2){\begingroup +\SubVect#1from#2to\@tempa +\expandafter\put\expandafter(#1){\expandafter\Vector\expandafter(\@tempa)}% +\endgroup\ignorespaces} +% \end{macrocode} +% +% The double tipped vector is built on the |\VECTOR| macro by simply +% drawing two vectors from the middle point of the double tipped vector. +% \begin{macrocode} +\def\VVECTOR(#1)(#2){{\SubVect#1from#2to\@tempb +\ScaleVect\@tempb by0.5to\@tempb +\AddVect\@tempb and#1to\@tempb +\VECTOR(\@tempb)(#2)\VECTOR(\@tempb)(#1)\ignorespaces}} +% \end{macrocode} +% +% The \texttt{pict2e} documentation says that if the vector length is zero +% the macro draws only the arrow tip; this may work with macro |\vector|, +% certainly not with |\Vector| and |\VECTOR|. This might be useful for +% adding an arrow tip to a circular arc. See examples in +% figure~\ref{fig:vectors}. +% +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Polylines and polygons} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% We now define the polygonal line macro; its syntax is very simple: +% \begin{flushleft} +% \cs{polygonal}\oarg{join}\texttt{(}$P_0$\texttt{)(}$P_1$\texttt{)(}$P_2$)% +% \texttt{\dots(}$P_n$\texttt{)} +% \end{flushleft} +% Remember: |\polyline| has been incorporated into |pict2e| 2009, but we +% redefine it so as to allow an optional argument to specify the line join +% type. +% +% In order to write a recursive macro we need aliases for the parentheses; +% actually we need only the left parenthesis, but some editors complain +% about unmatched delimiters, so we define an alias also for the right parenthesis. +% \begin{macrocode} +\let\lp@r( \let\rp@r) +% \end{macrocode} +% The first call to |\polyline|, besides setting the line joints, examines +% the first point coordinates and moves the drawing position to this point; +% afterwards it looks for the second point coordinates; they start with a +% left parenthesis; if this is found the coordinates should be there, but +% if the left parenthesis is missing (possibly preceded by spaces that are +% ignored by the |\@ifnextchar| macro) then a warning message is output +% together with the line number where the missing parenthesis causes the +% warning: beware, this line number might point to several lines further on +% along the source file! In any case it's necessary to insert a +%|\@killglue|command, because |\polyline| refers to absolute coordinates, +% and not necessarily is put in position through a |\put| command that +% provides to eliminate any spurious spaces preceding this command. +% +% \begin{figure}[!hb] +% \begin{minipage}{0.55\textwidth} +%\begin{verbatim} +% \unitlength=0.07\hsize +% \begin{picture}(8,8)(-4,-4)\color{red} +% \polygon*(45:4)(135:4)(-135:4)(-45:4) +% \end{picture} +%\end{verbatim} +% \end{minipage} +% \hfill +% \begin{minipage}{0.4\textwidth}\centering +% \unitlength=0.07\hsize +% \begin{picture}(8,8)(-4,-4)\color{red} +% \polygon*(45:4)(135:4)(-135:4)(-45:4) +% \end{picture} +% \end{minipage} +% \caption{The code and the result of defining a polygon with its vertex +% polar coordinates}\label{fig:filled-polygon} +% \end{figure} +% +% In order to allow a specification for the joints of the various segments +% of a polyline it is necessary to allow for an optional parameter; +% the default is the bevel join. +% \begin{macrocode} +\renewcommand*\polyline[1][\beveljoin]{\p@lylin@[#1]} + +\def\p@lylin@[#1](#2){\@killglue#1\GetCoord(#2)\d@mX\d@mY + \pIIe@moveto{\d@mX\unitlength}{\d@mY\unitlength}% + \@ifnextchar\lp@r{\p@lyline}{% + \PackageWarning{curve2e}% + {Polylines require at least two vertices!\MessageBreak + Control your polyline specification\MessageBreak}% + \ignorespaces}} + +% \end{macrocode} +% 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. +% \begin{macrocode} +\def\p@lyline(#1){\GetCoord(#1)\d@mX\d@mY + \pIIe@lineto{\d@mX\unitlength}{\d@mY\unitlength}% + \@ifnextchar\lp@r{\p@lyline}{\strokepath\ignorespaces}} +% \end{macrocode} +% +% The same treatment must be done for the \cs{polygon} macros; we use the +% defining commands of package |xparse|, in order to use an optional +% asterisk; as it is usual with |picture| convex lines, the command with +% asterisk does not trace the contour, but fills the contour with the +% current color.The asterisk is tested at the beginning and, depending on +% its presence, a temporary switch is set to \texttt{true}; this being the +% case the contour is filled, otherwise it is simply stroked. +% \begin{macrocode} +\providecommand\polygon{} +\RenewDocumentCommand\polygon{s O{\beveljoin} }{\@killglue\begingroup +\IfBooleanTF{#1}{\@tempswatrue}{\@tempswafalse}% +\@polygon[#2]} + +\def\@polygon[#1](#2){\@killglue#1\GetCoord(#2)\d@mX\d@mY + \pIIe@moveto{\d@mX\unitlength}{\d@mY\unitlength}% + \@ifnextchar\lp@r{\@@polygon}{% + \PackageWarning{curve2e}% + {Polygons require at least two vertices!\MessageBreak + Control your polygon specification\MessageBreak}% + \ignorespaces}} + + \def\@@polygon(#1){\GetCoord(#1)\d@mX\d@mY + \pIIe@lineto{\d@mX\unitlength}{\d@mY\unitlength}% + \@ifnextchar\lp@r{\@@polygon}{\pIIe@closepath + \if@tempswa\pIIe@fillGraph\else\pIIe@strokeGraph\fi + \endgroup + \ignorespaces}} +% \end{macrocode} +% Now, for example, a filled polygon can be drawn using polar coordinates +% for its vertices; see figure~\ref{fig:filled-polygon} +% +% Remember; the polygon polar coordinates are relative to the origin of +% the local axes; therefore in order to position a polygon in a different +% position, it is necessary to do it through a |\put| command. + +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{The red service grid} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% The next command is very useful for debugging while editing one's +% drawing; 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 aid and the user should know what he/she is doing; +% nevertheless it is advisable to displace the grid by means of a |\put| +% command so that its grid lines coincide with the graph coordinates that +% are multiples of 10. Missing to do so the readings become cumbersome. +% The |\RoundUp| macro provides to increase the +% grid dimensions to integer multiples of ten. +% \begin{macrocode} +\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}% +\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 a while. +% \begin{macrocode} +\def\RoundUp#1modulo#2to#3{\expandafter\@tempcnta\Integer#1.??% +\count254\@tempcnta\divide\count254by#2\relax +\multiply\count254by#2\relax +\count252\@tempcnta\advance\count252-\count254 +\ifnum\count252>0\advance\count252-#2\relax +\advance\@tempcnta-\count252\fi\edef#3{\number\@tempcnta}\ignorespaces}% +% \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 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. +% \begin{macrocode} +\def\Integer#1.#2??{#1}% +% \end{macrocode} +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Math operations on fractional operands} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% This is not the place to complain about the fact that all programs of the +% \TeX\ system use only integer arithmetics; luckily enough, in 218 the +% package |xfp| was released: that package resorts in the background +% language \LaTeX\,3; this language now can compute fractional number +% operations coded in decimal digits and accepts also numbers written in +% the usual way in computer science, that is as a fractional, possibly +% signed, number followed by an expression that contains the exponent to +% 10 necessary to (ideally) move the fractional separator in one or the +% other direction according to the sign of the exponent of 10; in other +% words the L3 library for floating point calculations accepts such +% expressions as \texttt{123.456}, \texttt{0.12345e3}, and +% \texttt{12345e-3}, and any other equivalent expression. If the first +% number is integer, it assumes that the decimal separator is to the right +% of the rightmost digits of the digit string. +% +% Floating pint calculations may be done through the |\fpeval| L3 function +% with a very simple syntax: +% \begin{flushleft} +% \cs{fpeval}\marg{mathematical expression} +% \end{flushleft} +% where \meta{mathematica exression} can contain the usual algebraic +% operation sings, |= - * / ** ^| and the function names of the most +% common algebraic, trigonometric, and transcendental functions; for direct +% and inverse trigonometric functions it accepts arguments in radians and +% in sexagesimal degrees; it accepts the group of rounding/truncating +% operators; it can perform several kinds of comparisons; as to this date +% the todo list includes the direct and inverse hyperbolic functions. The +% mantissa length of the floating point operands amounts to 16 decimal +% digits. Further details may be read in the documentations of the |xfp| +% and |interface3| documents, just by typing into a command line window +% the command \texttt{texdoc \meta{document}}, where \meta{document} is +% just the name of the above named files without extension. +% +% Before the availability of the |xfp| package, it was necessary to fake +% fractional number computations by means of the native e-\TeX\ commands +% |\dimexpr|, i.e. to multiply each fractional number by the unit |\p@| +% (1\,pt) so as to get a length; operate un such lengths, and then +% stripping of the `pt' component from the result; very error prone and +% with less precision as the one that the modern decimal floating point +% calculations can do. Of course it is not so important to use fractional +% numbers with more that 5 or 6 fractional digits, because the other +% \TeX\ and \LaTeX\ macros cannot handle them, but it is very convenient +% to have simpler and more readable code. We therefore switched to the +% new floating point functionality, even if this maintains the |curve2e| +% functionality, but renders this package unusable with older \LaTeX\ +% kernel installations. It has already been explained that the input of +% |curve2e| gets aborted if the |xfp| package is not available. +% +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{The division macro} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% The most important macro is the division of two fractional numbers; we +% seek a macro that gets dividend and divisor as fractional numbers and +% saves their ratio in a macro; this is done in a simple way with the +% following code. +% \begin{macrocode} +\def\DividE#1by#2to#3{% + \edef#3{\fpeval{#1 / #2}}\relax +} +% \end{macrocode} +% In order to avoid problems with divisions by zero, or with numbers that +% yield results to large to be used as multipliers of lengths, it would be +% preferable that the above code be preceded or followed by some tests and +% possible messages. Actually we decided to avoid such tests and messages, +% because the internal L3 functions already provide some. This is what it +% was done in the previous versions of this package, when the |\fpeval| L3 +% function was not available. +% +% Notice that operands |#1| and |#2| may be integer numbers or fractional, +% or mixed numbers. They may be also dimensions, but while dimensions in +% printer points (72.27pt=1in) are handled as assumed, when different +% units are used, the length must be enclosed in parentheses: +%\begin{verbatim} +%\DividE(1mm)by(3mm) to\result +%\end{verbatim} +% yields correctly |\result=0.33333333|. Without parentheses the result is +% unpredictable. +% +% For backward compatibility we need an alias. +% \begin{macrocode} +\let\DivideFN\DividE +% \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 stripped away +% \begin{macrocode} +\def\MultiplY#1by#2to#3{\edef#3{\fpeval{#1 * #2}}}\relax +\let\MultiplyFN\MultiplY +% \end{macrocode} +% but with multiplication it is better to avoid computations with lengths. +% +% The next macro uses the \verb|\strip@pt| \LaTeX\ kernel macro to get the +% numerical value of a measure in points. One has to call |\Numero| with +% a control sequence and a dimension; the dimension value in points is +% assigned to the control sequence. +% \begin{macrocode} +\unless\ifdefined\Numero + \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 meaning \verb|\relax| +% then executes the test; therefore an undefined macro name is always +% defined to mean |\relax|. +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Trigonometric functions} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% We now start with trigonometric functions. In previous versions of this +% package we defined the macros |\SinOf|, |\CosOf| and |\TanOf| (|\CotOf| +% does not appear so essential) by means of the parametric +% formulas that require the knowledge of the tangent of the half angle. +% We wanted, and still want, to specify the angles in sexagesimal degrees, +% not in radians, so that accurate reductions to the main quadrants are +% possible. The formulas are +% \begin{eqnarray*} +% \sin\theta &=& \frac{2}{\cot x + \tan x}\\ +% \cos\theta &=& \frac{\cot x - \tan x}{\cot x + \tan x}\\ +% \tan\theta &=& \frac{2}{\cot x - \tan x}\\ +% \noalign{\hbox{where}} +% x &=& \theta/114.591559 +% \end{eqnarray*} +% is the half angle in degrees converted to radians. +% +% But now, in this new version, the availability of the floating point +% computations with the specific L3 library makes al the above superfluous; +% actually the above approach gave good results but it was cumbersome and +% limited by the fixed radix computations of the \TeX\ system programs. +% Matter of facts, we compared the results (with 6 fractional digits) the +% computations executed with the \texttt{sind} function name, in order to +% use the angles in degrees, and a table of trigonometric functions with +% the same number of fractional digits, and we di not find and difference, +% not even one unit on the sixth decimal digit. Probably the |\fpeval| +% computations, without rounding before the sixteenth significant digit, +% are much more accurate, but it is useless to have a better accuracy when +% the other \TeX\ and \LaTeX\ macros would not be able to exploit them. +% +% Having available such powerful instrument, even the tangent appears to +% be of little use for the kind of computations that are supposed to be +% required in this package. +% +% The codes for the computation of |\SinOf| and |\CosOf| of the angle in +% degrees is therefore the following +% \begin{macrocode} +\def\SinOf#1to#2{\edef#2{\fpeval{round(sind#1,6)}}}\relax +\def\CosOf#1to#2{\edef#2{\fpeval{round(cosd#1,6)}}}\relax +% \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. The |\ArgOfVect| macro receives on input a vector; +% from the signs of the horizontal and vertical components it determines +% the ratio and from this ratio the arctangent; but before doing this it +% tests the components in order to determine the quadrant of the vector +% tip; depending on signs it possibly adds what is necessary to determine +% the angle in the range $-180^\circ < \varphi \le +180^\circ$. If both +% components are zero, the angle is undefined, but for what concerns +% |curve2e| it is assigned the angle $0^circ$. +% \begin{macrocode} +\def\ArgOfVect#1to#2{\bgroup\GetCoord(#1){\t@X}{\t@Y}% +\def\s@gno{}% +\ifdim\t@X\p@=\z@ + \ifdim\t@Y\p@=\z@ + \def\ArcTan{0}% vettore nullo + \else + \def\ArcTan{90}% vettore verticale + \ifdim\t@Y\p@<\z@\def\ArcTan{-90}\fi + \fi +\else + \ifdim\t@Y\p@=\z@% vettore orizzontale + \ifdim\t@X\p@<\z@ + \def\ArcTan{180}% + \else + \def\ArcTan{0}% + \fi + \else % vettore qualsiasi + \edef\ArcTan{\fpeval{atand(\t@Y / \t@X)}}\relax + \ifdim\t@X\p@<\z@% vettore nei quadranti di sinistra + \ifdim\t@Y\p@<\z@ + \edef\ArcTan{\fpeval{\ArcTan - 180}}\relax + \else + \edef\ArcTan{\fpeval{\ArcTan + 180}}\relax + \fi + \fi + \fi +\fi +\edef\x{\noexpand\egroup\noexpand\edef\noexpand#2{\ArcTan}}% +\x\ignorespaces} +% \end{macrocode} +% +% It is worth examining the following table, where the angles of nine +% vectors $45^circ$ degrees from one another are computed from this macro. +% \begin{center} +% \begin{tabular}{l*9r} +% Vector &0,0 &1,0 &1,1 & 0,1 & -1,1& -1,0&-1,-1&0,-1&1,-1\\ +% Angle & 0 & 0 & 45 & 90 & 135 & 180 &-135 & -90& -45 +% \end{tabular} +% \end{center} +% Real computations with the |\ArgOfVect| macro produce those very numbers +% without the need of rounding; |\fpeval| produces all trimming of lagging +% zeros and rounding by itself. +% +% +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Arcs and curves preliminary information} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 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 arc starting point and the angular aperture. The arc has its +% reference point in its center, therefore it does not need to be put in +% place by the command |\put|; 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{center})(\meta{starting point})\marg{angle} +% \end{flushleft} +% which is totally equivalent to: +% \begin{flushleft}\ttfamily +% \cs{put}(\meta{center})\marg{\upshape\cs{Arc}(0,0)(\meta{starting point})\marg{angle}} +% \end{flushleft} +% 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{\normalfont{\itshape start angle}\texttt{:}{\itshape 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. +% +% The end point is obtained from the rotation of the starting point around +% the center; but the \texttt{pict2e} command |\pIIe@rotate| is such that +% the 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 roto-amplification operators. +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Complex number macros} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 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 used by the +% |picture| environment) there is the other conventional representation +% used by the engineers that stresses 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 we 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 or polar form of the Euler's formula +% \[ +% \mathrm{e}^{\mathrm{j}\phi} = \cos\phi+\mathrm{j}\sin\phi +% \] +% +% The magnitude of a vector is determined by taking a ‘clever’ square root +% of a function of the real and the imaginary parts; see further on. +% +% It's better to represent each complex number with one control sequence; +% this implies frequent assembling and disassembling the pair of real +% numbers that make up a complex number. These real components are +% assembled into the defining control sequence as a couple of coordinates, +% i.e.\ two comma separated integer or fractional signed decimal numbers. +% +% For assembling two real numbers into a complex number we use the +% following elementary macro: +% \begin{macrocode} +\def\MakeVectorFrom#1#2to#3{\edef#3{#1,#2}\ignorespaces}% +% \end{macrocode} +% Another elementary macro copies a complex number into another one: +% \begin{macrocode} +\def\CopyVect#1to#2{\edef#2{#1}\ignorespaces}% +% \end{macrocode} +% The magnitude is determined with the macro |\ModOfVect| with delimited +% arguments; as usual it is assumed that the results are retrieved by means +% of control sequences, not used directly. +% +% In the preceding version of package |curve2e| the magnitude $M$ was +% determined by taking the moduli of the real and imaginary parts, by +% changing their signs if necessary; the larger component was +% then taken as the reference one so that, if $a$ is larger than $b$, the +% square root of the sum of their squares is computed as such: +% \[ +% M = \sqrt{a^2+b^2} = \vert a\vert\sqrt{1+(b/a)^2} +% \] +% In this way the radicand never exceeds 2 and it was quite easy to get its +% square root by means of the Newton iterative process; due to the +% quadratic convergence, five iterations were more than sufficient. When +% one of the components was zero, the Newton iterative process was skipped. +% With the availability of the |xfp| package and its floating point +% algorithms it is much easier to compute the magnitude of a complex +% number; since these algorithms allow to use very large numbers, it is +% not necessary to normalise the complex number components to the largest +% one; therefore the code is much simpler than the ne used for implementing +% the Newton method in the previous versions of this package. +% \begin{macrocode} +\def\ModOfVect#1to#2{\GetCoord(#1)\t@X\t@Y +\edef#2{\fpeval{sqrt(\t@X*\t@X + \t@Y*\t@Y)}}\relax +\ignorespaces}% +% \end{macrocode} +% +% 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 form of the direction vector. If by any chance the direction +% of the null vector is requested, the output is again the null vector, +% without normalization. +% \begin{macrocode} +\def\DirOfVect#1to#2{\GetCoord(#1)\t@X\t@Y +\ModOfVect#1to\@tempa +\unless\ifdim\@tempa\p@=\z@ + \DividE\t@X\p@ by\@tempa to\t@X + \DividE\t@Y\p@ by\@tempa to\t@Y +\fi +\MakeVectorFrom\t@X\t@Y to#2\ignorespaces}% +% \end{macrocode} +% +% A cumulative macro uses the above ones to determine with one call both +% the magnitude and the direction of a complex number. The first argument +% is the input complex number, the second its magnitude, and the third is +% again a complex number normalised to unit magnitude (unless the input was +% the null complex number); remember always that output quantities must be +% specified with control sequences to be used at a later time. +% \begin{macrocode} +\def\ModAndDirOfVect#1to#2and#3{% +\GetCoord(#1)\t@X\t@Y +\ModOfVect#1to#2% +\DirOfVect#1to#3\ignorespaces}% +% \end{macrocode} +% The next macro computes the magnitude and the direction of the difference +% of two complex numbers; the first input argument is the minuend, the +% second is the subtrahend; the output quantities are the third argument +% containing the magnitude of the difference and the fourth is the +% direction of the difference. +% The service macro |\SubVect| executes the difference of two complex +% numbers and is described further on. +% \begin{macrocode} +\def\DistanceAndDirOfVect#1minus#2to#3and#4{% +\SubVect#2from#1to\@tempa +\ModAndDirOfVect\@tempa to#3and#4\ignorespaces}% +% \end{macrocode} +% We now have two macros intended to fetch just the real or, respectively, +% the imaginary part of the input complex number. +% \begin{macrocode} +\def\XpartOfVect#1to#2{% +\GetCoord(#1)#2\@tempa\ignorespaces}% +% +\def\YpartOfVect#1to#2{% +\GetCoord(#1)\@tempa#2\ignorespaces}% +% \end{macrocode} +% With the next macro we create a direction vector (second argument) from a +% given angle (first argument, in degrees). +% \begin{macrocode} +\def\DirFromAngle#1to#2{% +\CosOf#1to\t@X +\SinOf#1to\t@Y +\MakeVectorFrom\t@X\t@Y to#2\ignorespaces}% +% \end{macrocode} +% +% Sometimes it is necessary to scale a vector by an arbitrary real factor; +% this implies scaling both the real and imaginary part of the input given vector. +% \begin{macrocode} +\def\ScaleVect#1by#2to#3{\GetCoord(#1)\t@X\t@Y +\edef\t@X{\fpeval{#2 * \t@X}}\relax +\edef\t@Y{\fpeval{#2 * \t@Y}}\relax +\MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% +% \end{macrocode} +% Again, sometimes it is necessary to reverse the direction of rotation; +% this implies changing the sign of the imaginary part of a given complex +% number; this operation produces the complex conjugate of the given +% number. +% \begin{macrocode} +\def\ConjVect#1to#2{\GetCoord(#1)\t@X\t@Y +\edef\t@Y{-\t@Y}% +\MakeVectorFrom\t@X\t@Y to#2\ignorespaces}% +% \end{macrocode} +% +% With all the low level elementary operations we can now proceed to the +% definitions of the binary operations on complex numbers. We start with +% the addition: +% \begin{macrocode} +\def\AddVect#1and#2to#3{\GetCoord(#1)\tu@X\tu@Y +\GetCoord(#2)\td@X\td@Y +\edef\t@X{\fpeval{\tu@X + \td@X}}\relax +\edef\t@Y{\fpeval{\tu@Y + \td@Y}}\relax +\MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% +% \end{macrocode} +% Then the subtraction: +% \begin{macrocode} +\def\SubVect#1from#2to#3{\GetCoord(#1)\tu@X\tu@Y +\GetCoord(#2)\td@X\td@Y +\edef\t@X{\fpeval{\td@X - \tu@X}}\relax +\edef\t@Y{\fpeval{\td@Y - \tu@Y}}\relax +\MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% +% \end{macrocode} +% +% For the multiplication we need to split the operation according to the +% fact that we want to multiply by the second operand or by the complex +% conjugate of the second operand; it would be nice if we could use the +% usual postfixed asterisk notation for the complex conjugate, but we could +% not find a simple means for doing so; therefore we use the prefixed +% notation, that is I put the asterisk before the second operand. The first +% part of the multiplication macro just takes care of the multiplicand and +% then checks for the asterisk; if there is no asterisk it calls a second +% service macro that performs a regular complex multiplication, otherwise +% it calls a third service macro that executes the conjugate +% multiplication. +% \begin{macrocode} +\def\MultVect#1by{\@ifstar{\@ConjMultVect#1by}{\@MultVect#1by}}% +% +\def\@MultVect#1by#2to#3{\GetCoord(#1)\tu@X\tu@Y +\GetCoord(#2)\td@X\td@Y +\edef\t@X{\fpeval{\tu@X * \td@X - \tu@Y * \td@Y}}\relax +\edef\t@Y{\fpeval{\tu@Y * \td@X + \tu@X * \td@Y}}\relax +\MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% +% +\def\@ConjMultVect#1by#2to#3{\GetCoord(#1)\tu@X\tu@Y +\GetCoord(#2)\td@X\td@Y +\edef\t@X{\fpeval{\tu@X * \td@X + \tu@Y * \td@Y}}\relax +\edef\t@Y{\fpeval{\tu@Y * \td@X - \tu@X * \td@Y}}\relax +\MakeVectorFrom\t@X\t@Y to#3\ignorespaces} +% \end{macrocode} +% +% The division of two complex numbers implies scaling down the dividend +% by the magnitude of the divisor and by rotating the dividend scaled +% vector by the opposite direction of the divisor; therefore: +% \begin{macrocode} +\def\DivVect#1by#2to#3{\ModAndDirOfVect#2to\@Mod and\@Dir +\edef\@Mod{\fpeval{1 / \@Mod}}\relax +\ConjVect\@Dir to\@Dir +\ScaleVect#1by\@Mod to\@tempa +\MultVect\@tempa by\@Dir to#3\ignorespaces}% +% \end{macrocode} +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Arcs and curved vectors} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% We are now in the position of really doing graphic work. +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsubsection{Arcs} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% We start with tracing a circular arc of arbitrary center, arbitrary +% starting point and arbitrary aperture; the first macro checks the +% aperture; if this is not zero it actually proceeds with the necessary +% computations, otherwise it does nothing. +% \begin{macrocode} +\def\Arc(#1)(#2)#3{\begingroup +\@tdA=#3\p@ +\unless\ifdim\@tdA=\z@ + \@Arc(#1)(#2)% +\fi +\endgroup\ignorespaces}% +% \end{macrocode} +% The aperture is already memorized in |\@tdA|; the |\@Arc| macro receives +% the center coordinates in the first argument and the coordinates of the +% starting point in the second argument. +% \begin{macrocode} +\def\@Arc(#1)(#2){% +\ifdim\@tdA>\z@ + \let\Segno+% +\else + \@tdA=-\@tdA \let\Segno-% +\fi +% \end{macrocode} +% The rotation angle sign is memorised in |\Segno| and |\@tdA| now contains +% the absolute value of the arc aperture. +% +% If the rotation angle is larger than $360^\circ$ a message is issued that +% informs the user that the angle will be reduced modulo $360^\circ$; this +% operation is performed by successive subtractions rather than with +% modular arithmetics on the assumption that in general one subtraction +% suffices. +% \begin{macrocode} +\Numero\@gradi\@tdA +\ifdim\@tdA>360\p@ + \PackageWarning{curve2e}{The arc aperture is \@gradi\space degrees + and gets reduced\MessageBreak% + to the range 0--360 taking the sign into consideration}% + \@whiledim\@tdA>360\p@\do{\advance\@tdA-360\p@}% +\fi +% \end{macrocode} +% Now the radius is determined and the drawing point is moved to the +% starting point. +% \begin{macrocode} +\SubVect#2from#1to\@V \ModOfVect\@V to\@Raggio +\CopyVect#2to\@pPun +\CopyVect#1to\@Cent \GetCoord(\@pPun)\@pPunX\@pPunY +% \end{macrocode} +% From now on it's better to define a new macro that will be used also in +% the subsequent macros that draw arcs; here we already have the starting +% point coordinates and the angle to draw the arc, therefore we just call +% the new macro, stroke the line and exit. +% \begin{macrocode} +\@@Arc\strokepath\ignorespaces}% +% \end{macrocode} +% And the new macro |\@@Arc| starts with moving the drawing point to the +% first% point and does everything needed for drawing the requested arc, +% except stroking it; I leave the \texttt{stroke} command to the completion +% of the calling macro and nobody forbids to use the |\@@Arc| macro for +% other purposes. +% \begin{macrocode} +\def\@@Arc{% +\pIIe@moveto{\@pPunX\unitlength}{\@pPunY\unitlength}% +% \end{macrocode} +% If the aperture is larger than $180^\circ$ it traces a semicircle in the +% right direction and correspondingly reduces the overall aperture. +% \begin{macrocode} +\ifdim\@tdA>180\p@ + \advance\@tdA-180\p@ + \Numero\@gradi\@tdA + \SubVect\@pPun from\@Cent to\@V + \AddVect\@V and\@Cent to\@sPun + \MultVect\@V by0,-1.3333333to\@V + \if\Segno-\ScaleVect\@V by-1to\@V\fi + \AddVect\@pPun and\@V to\@pcPun + \AddVect\@sPun and\@V to\@scPun + \GetCoord(\@pcPun)\@pcPunX\@pcPunY + \GetCoord(\@scPun)\@scPunX\@scPunY + \GetCoord(\@sPun)\@sPunX\@sPunY + \pIIe@curveto{\@pcPunX\unitlength}{\@pcPunY\unitlength}% + {\@scPunX\unitlength}{\@scPunY\unitlength}% + {\@sPunX\unitlength}{\@sPunY\unitlength}% + \CopyVect\@sPun to\@pPun +\fi +% \end{macrocode} +% If the remaining aperture is not zero it continues tracing the rest of +% the arc. 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. +% +% 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 +%= \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 + \SubVect\@Cent from\@pPun to\@V + \MultVect\@V by\@Dir to\@V + \AddVect\@Cent and\@V to\@sPun + \@tdA=.5\@tdA \Numero\@gradi\@tdA + \DirFromAngle\@gradi to\@Phimezzi + \GetCoord(\@Phimezzi)\@cosphimezzi\@sinphimezzi + \@tdB=1.3333333\p@ \@tdB=\@Raggio\@tdB + \@tdC=\p@ \advance\@tdC -\@cosphimezzi\p@ \Numero\@tempa\@tdC + \@tdB=\@tempa\@tdB + \DividE\@tdB by\@sinphimezzi\p@ to\@cZ + \ScaleVect\@Phimezzi by\@cZ to\@Phimezzi + \ConjVect\@Phimezzi to\@mPhimezzi + \if\Segno-% + \let\@tempa\@Phimezzi + \let\@Phimezzi\@mPhimezzi + \let\@mPhimezzi\@tempa + \fi + \SubVect\@sPun from\@pPun to\@V + \DirOfVect\@V to\@V + \MultVect\@Phimezzi by\@V to\@Phimezzi + \AddVect\@sPun and\@Phimezzi to\@scPun + \ScaleVect\@V by-1to\@V + \MultVect\@mPhimezzi by\@V to\@mPhimezzi + \AddVect\@pPun and\@mPhimezzi to\@pcPun + \GetCoord(\@pcPun)\@pcPunX\@pcPunY + \GetCoord(\@scPun)\@scPunX\@scPunY + \GetCoord(\@sPun)\@sPunX\@sPunY + \pIIe@curveto{\@pcPunX\unitlength}{\@pcPunY\unitlength}% + {\@scPunX\unitlength}{\@scPunY\unitlength}% + {\@sPunX\unitlength}{\@sPunY\unitlength}% +\fi} +% \end{macrocode} +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsubsection{Arc vectors} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% We exploit much of the above definitions for the |\Arc| macro for drawing +% circular arcs with an arrow at one or both ends; the first macro +% |\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 specific +% option to the \texttt{pict2e} package. +% +% 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. +% +% All these operations require a lot of ``playing'' with vector +% directions, but even if the operations are numerous, they do not do +% anything else but: (a) determining the end point and its direction; +% (b) determining the arrow 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) 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 other end +% of the arc; (g) shortening the total arc angular amplitude by the +% 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. +% +% The calling macros are very similar to the |\Arc| macro initial one: +% \begin{macrocode} +\def\VectorArc(#1)(#2)#3{\begingroup +\@tdA=#3\p@ \ifdim\@tdA=\z@\else + \@VArc(#1)(#2)% +\fi +\endgroup\ignorespaces}% +% +\def\VectorARC(#1)(#2)#3{\begingroup +\@tdA=#3\p@ +\ifdim\@tdA=\z@\else + \@VARC(#1)(#2)% +\fi +\endgroup\ignorespaces}% +% \end{macrocode} +% +% The single arrowed arc is defined with the following long macro where +% all the described operations are performed more or less in the described +% succession; probably the macro requires a little cleaning, but since it +% works fine we did not try to optimise it for time or number of tokens. +% The final part of the macro is almost identical to that of the plain arc; +% the beginning also is quite similar. The central part is dedicated to +% the positioning of the arrow tip and to the necessary calculations for +% determining the tip tilt and the reduction of the total arc length; pay +% attention that the arrow length, stored in |\@tdE| is a real length, +% while the radius stored in |\@Raggio| is just a multiple of the +% |\unitlength|, so that the division (that yields a good angular +% approximation to the arrow length as seen from the center of the arc) +% must be done with real lengths. The already defined |\@@Arc| macro +% actually draws the curved vector stem without stroking it. +% \begin{macrocode} +\def\@VArc(#1)(#2){% +\ifdim\@tdA>\z@ + \let\Segno+% +\else + \@tdA=-\@tdA \let\Segno-% +\fi \Numero\@gradi\@tdA +\ifdim\@tdA>360\p@ + \PackageWarning{curve2e}{The arc aperture is \@gradi\space degrees + and gets reduced\MessageBreak% + to the range 0--360 taking the sign into consideration}% + \@whiledim\@tdA>360\p@\do{\advance\@tdA-360\p@}% +\fi +\SubVect#1from#2to\@V \ModOfVect\@V to\@Raggio \CopyVect#2to\@pPun +\@tdE=\pIIe@FAW\@wholewidth \@tdE=\pIIe@FAL\@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 +\DirFromAngle\@tempa to\@Dir +\MultVect\@V by\@Dir to\@sPun +\edef\@tempA{\ifx\Segno-\m@ne\else\@ne\fi}% +\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=.5\@tdD \Numero\DeltaGradi\@tdD +\DirFromAngle\DeltaGradi to\@Dird +\MultVect\@Dir by*\@Dird to\@Dir +\GetCoord(\@Dir)\@xnum\@ynum +\put(\@tdX,\@tdY){\vector(\@xnum,\@ynum){0}}% +\@tdE =\ifx\Segno--\fi\DeltaGradi\p@ +\advance\@tdA -\@tdE \Numero\@gradi\@tdA +\CopyVect#1to\@Cent \GetCoord(\@pPun)\@pPunX\@pPunY +\@@Arc +\strokepath\ignorespaces}% +% \end{macrocode} +% +% The macro for the arc terminated with arrow tips at both ends is again +% very similar, except it is necessary to repeat the arrow tip positioning +% also at the starting point. The |\@@Arc| macro draws the curved stem. +% \begin{macrocode} +\def\@VARC(#1)(#2){% +\ifdim\@tdA>\z@ + \let\Segno+% +\else + \@tdA=-\@tdA \let\Segno-% +\fi \Numero\@gradi\@tdA +\ifdim\@tdA>360\p@ + \PackageWarning{curve2e}{The arc aperture is \@gradi\space degrees + and gets reduced\MessageBreak% + to the range 0--360 taking the sign into consideration}% + \@whiledim\@tdA>360\p@\do{\advance\@tdA-360\p@}% +\fi +\SubVect#1from#2to\@V \ModOfVect\@V to\@Raggio \CopyVect#2to\@pPun +\@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=\if\Segno--\fi\@gradi\p@ \Numero\@tempa\@tdD +\DirFromAngle\@tempa to\@Dir +\MultVect\@V by\@Dir to\@sPun% corrects the end point +\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\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}}% 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{\if\Segno-\else-\fi\@ne}% +\MultVect\@V by0,\@tempa to\@vPun +\@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}}% 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 +\AddVect\@Cent and\@V to\@pPun +\GetCoord(\@pPun)\@pPunX\@pPunY +\@@Arc +\strokepath\ignorespaces}% +% \end{macrocode} +% +% It must be understood that the curved vectors, the above circular arcs +% terminated with an arrow tip at one or both ends, have a nice appearance +% only if the arc radius is not too small, or, said in a different way, if +% the arrow tip angular width does not exceed a maximum of a dozen degrees +% (and this is probably already too much); the tip does not get curved as +% the arc is, therefore there is not a smooth transition from the curved +% stem and the straight arrow tip if this one is large in comparison to the arc radius. +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{General curves} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% The most used method to draw curved lines with computer programs is to +% connect several simple curved lines, general ``arcs'', one to another +% generally maintaining the same tangent at the junction. If the direction +% changes we are dealing with a cusp. +% +% The simple general arcs that are directly implemented in every program +% that display typeset documents, are those drawn with the parametric +% curves called \emph{Béźier splines}; given a sequence of points in the +% $x,y$ plane, say $P_0, P_1, P_2, p_3, \dots$ (represented as coordinate +% pairs, i.e. by complex numbers), the most common Bézier splines are the +% following ones: +% \begin{align} +% \mathcal{B}_1 &= P_0(1-t) + P_1t \label{equ:B-1} \\ +% \mathcal{B}_2 &= P_0(1-t)^2 + P_1 2(1-t)t + P_2t^2 \label{equ:B-2} \\ +% \mathcal{B}_3 &= P_0(1-t)^3 + P_1 3(1-t)^2t +P_2 3(1-t)t^2 +P_3t^3 +% \label{equ:B-3} +% \end{align} +% +% All these splines depend on parameter $t$; they have the property that +% for $t=0$ each line starts at the first point, while for $t=1$ they +% reach the last point; in each case the generic point $P$ on each curve +% takes off with a direction that points to the next point, while it +% lands on the destination point with a direction coming from the +% penultimate point; moreover, when $t$ varies from 0 to 1, the curve arc +% is completely contained within the convex hull formed by the polygon that +% has the spline points as vertices. +% +% Last but not least first order splines implement just straight lines +% and they are out of question for what concerns maxima, minima, +% inflection points and the like. Quadratic splines draw just +% parabolas, therefore they draw arcs that have the concavity just on one +% side of the path; therefore no inflection points. Cubic splines are +% extremely versatile and can draw lines with maxima, minima and inflection +% points. Virtually a multi-arc curve may be drawn by a set of cubic +% splines as well as a set of quadratic splines (fonts are a good example: +% Adobe Type~1 fonts have their contours described by cubic splines, while +% TrueType fonts have their contours described with quadratic splines; +% with a naked eye it is impossible to notice the difference). +% +% Each program that processes the file to be displayed is capable of +% drawing first order Bézier splines (segments) and third order Bézier +% splines, for no other reason, at least, because they have to draw vector +% fonts whose contours are described by Bézier splines; sometimes they +% have also the program commands to draw second order Bézier splines, but +% not always these machine code routines are available to the user for +% general use. For what concerns |pdftex|, |xetex| and |luatex|, they have +% the user commands for straight lines and cubic arcs. At least with +% |pdftex|, quadratic arcs must be simulated with a clever use of third +% order Bézier splines. +% +% Notice that \LaTeXe\ environment |picture| by itself is capable of +% drawing both cubic and quadratic Bézier splines as single arcs; but it +% resorts to ``poor man'' solutions. The |pict2e| package removes all the +% old limitations and implements the interface macros for sending the +% driver the necessary drawing information, including the transformation +% from typographical points (72.27\,pt/inch) to PostScript big points +% (72\,bp/inch). But for what concerns the quadratic spline it resorts to +% the clever use of a cubic spline. +% +% Therefore here we treat first the drawings that can be made with cubic +% splines; then we describe the approach to quadratic splines. +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%\subsection{Cubic splines} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Now we define a macro for tracing a general, not necessarily circular, +% arc. This macro resorts to a general triplet of macros with which it is +% possible to draw almost anything. It traces a single Bézier spline from +% a first point where the tangent direction is specified to a second point +% where again it is specified the tangent direction. Actually this is a +% special (possibly useless) case where the general |\curve| macro of +% |pict2e| could do the same or a better job. In any case\dots +% \begin{macrocode} +\def\CurveBetween#1and#2WithDirs#3and#4{% + \StartCurveAt#1WithDir{#3}\relax + \CurveTo#2WithDir{#4}\CurveFinish\ignorespaces +}% +% \end{macrocode} +% +% Actually the above macro is a special case of concatenation of the +% triplet formed by macros |\StartCurve|, |\CurveTo| and|\CurveFinish|; +% the second macro 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 may give raise to some little +% problems when they are very close to 90° in absolute value. Some control +% is exercised on these values, but some tests might fail if the angle +% derives from computations; this is a good place to use polar forms for +% the direction vectors. +% +% 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 +% drawing but also memorises the starting direction; the second macro +% traces the current Bézier arc reaching the destination point with the +% specified direction, but memorises this direction as the one with which +% to start the next arc. The overall curve is then always smooth because +% the various Bézier arcs join with continuous tangents. If a cusp is +% desired it is necessary to change the memorised direction at the end of +% the arc before the cusp and before the start of the next arc; this is +% better than stroking the curve before the cusp and then starting another +% curve, because the curve joining point at the cusp is not stroked with +% the same command, therefore we get two superimposed curve terminations. +% We therefore need another small macro |\ChangeDir| to perform this task. +% +% It is necessary to recall that the direction vectors point to the control +% points, but they do not define the control points themselves; they are +% just directions, or, even better, they are simply vectors with the +% desired direction; the macros themselves provide to the normalisation +% and memorization. +% +% The next desirable feature would be to design a macro that accepts +% optional node directions and computes the missing ones according to a +% suitable strategy. We can think of many such strategies, but none seems +% to be generally applicable, in the sense that one strategy might give +% good results, say, with sinusoids and another one, say, with cardioids, +% but neither one is suitable for both cases. +% +% For the moment we refrain from automatic direction computation, but we +% design the general macro as if directions were optional. +% +% Here we begin with the first initialising macro that receives with the +% first argument the starting point and with the second argument the +% direction of the tangent (not necessarily normalised to a unit vector) +% \begin{macrocode} +\def\StartCurveAt#1WithDir#2{% +\begingroup +\GetCoord(#1)\@tempa\@tempb +\CopyVect\@tempa,\@tempb to\@Pzero +\pIIe@moveto{\@tempa\unitlength}{\@tempb\unitlength}% +\GetCoord(#2)\@tempa\@tempb +\CopyVect\@tempa,\@tempb to\@Dzero +\DirOfVect\@Dzero to\@Dzero +\ignorespaces} +% \end{macrocode} +% And this re-initializes the direction to create a cusp: +% \begin{macrocode} +\def\ChangeDir<#1>{% +\GetCoord(#1)\@tempa\@tempb +\CopyVect\@tempa,\@tempb to\@Dzero +\DirOfVect\@Dzero to\@Dzero +\ignorespaces} +% \end{macrocode} +% +% 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 therefore is the follwing: +%\begin{flushleft} +%\cs{CbezierTo}\meta{end +% point}|WithDir|\meta{direction}|AndDists|\meta{$K_0$}|And|\meta{$K_1$} +%\end{flushleft} +% where \meta{end point} is a vector macro or a comma separated pair of +% values; again \meta{direction} is another vector macro or a comma +% separated pair of values, that not necessarily indicate a unit vector, +% since the macro provides to normalise it to unity; \meta{$K_0$} and +% \meta{$K_1$} are the distances of the control points from their +% respective node points; they must be positive integers or fractional +% numbers. If \meta{$K_1$} is a number must be enclosed in curly braces, +% while if it is a macro name (containing the desired fractional or +% integer value) there is no need for braces. +% +% This macro uses the input information to use the internal |pict2e| macro +% |\pIIe@curveto| with the proper arguments, and to save the final +% direction into the same |\@Dzero| macro for successive use of other +% arc-drawing 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 to the other macro +% |\CurveBetween| previously described and defined here: +% +% \begin{macrocode} +\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 five red curves drawn with |\CbezierBetween|; the +% five red curves differ only for the distance of their control point $C_0$ +% from the starting point; the differences are remarkable and the topmost +% curve even presents a slight inflection close to the end point. These +% effects cannot be obtained with the ``smarter'' macro |\CurveBetween|. +% But certainly this simpler macro is more difficult to use because the +% distances of the control points are difficult to estimate and require a +% number of cut-and-try experiments. +% +% +% 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 to determine the distances from the adjacent curve nodes. This +% must work correctly even if nodes and directions imply an inflection +% point somewhere along the arc. +% +% The strategy we devised consists in determining each control point as if +% it were the control point of a circular arc, precisely an arc of an +% osculating circle, i.e. a circle tangent to the curve at that node. The +% ambiguity of the stated problem may be solved by establishing that the +% chord of the osculating circle has the same direction as the chord of the +% arc being drawn, and that the curve chord is divided into two equal parts +% each of which should be interpreted as half the chord of the osculating +% circle. +% +% This makes the algorithm a little rigid; sometimes the path drawn is very +% pleasant, while in other circumstances the determined curvatures are too +% large or too small. We therefore add some optional information that lets +% us have some control over the curvatures; the idea is based on the +% concept of \emph{tension}, similar but not identical to the one used in +% the drawing programs \MF\ and \MP. We add to the direction information, +% with which the control nodes of the osculating circle arcs are +% determined, a scaling factor that should be intuitively related to the +% tension of the arc (actually, since the tension of the ‘rope’ is high +% when this parameter is low, probably a name such as ‘looseness’ would be +% better suited): the smaller this number, the closer the arc resembles +% a straight line as a rope subjected to a high tension; value zero is +% allowed, while a value of 4 is close to ``infinity'' and turns a quarter +% circle into a line with an unusual loop; a value of 2 turns a quarter +% circle almost into a polygonal line with rounded corner. Therefore these +% tension factors should be used only for fine tuning the arcs, not when +% a path is drawn for the first time. +% +% We devised a syntax for specifying direction and tensions: +%\begin{flushleft} +% \meta{direction\texttt{\upshape;}tension factors} +%\end{flushleft} +% where \emph{direction} contains a pair of fractional number that not +% necessarily refer to the components of a unit vector direction, but +% simply to a vector with the desired orientation (polar form is OK); the +% information contained from the semicolon (included) to the rest of the +% specification is optional; if it is present, the \emph{tension factors} +% is simply a comma separated pair of fractional or integer numbers that +% represent respectively the tension at the starting or the ending node of +% a path arc. +% +% We therefore need a macro to extract the mandatory and optional parts: +% \begin{macrocode} +\def\@isTension#1;#2!!{\def\@tempA{#1}% +\def\@tempB{#2}\unless\ifx\@tempB\empty\strip@semicolon#2\fi} + +\def\strip@semicolon#1;{\def\@tempB{#1}} +% \end{macrocode} +% By changing the tension values we can achieve different results: see +% figure~\ref{fig:tensions}. +% +% 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: +% \begin{macrocode} +\def\CurveTo#1WithDir#2{% +\def\@Tuno{1}\def\@Tzero{1}\relax +\edef\@Puno{#1}\@isTension#2;!!% +\expandafter\DirOfVect\@tempA to\@Duno +\bgroup\unless\ifx\@tempB\empty\GetCoord(\@tempB)\@Tzero\@Tuno\fi +\DistanceAndDirOfVect\@Puno minus\@Pzero to\@Chord and\@DirChord +% \end{macrocode} +% Then we rotate everything about the starting point so as to bring the +% chord on the real axis +% \begin{macrocode} +\MultVect\@Dzero by*\@DirChord to \@Dpzero +\MultVect\@Duno by*\@DirChord to \@Dpuno +\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 memorised in |\@Chord| and +% its half is saved in |\@semichord|. +% +% We now examine the various degenerate cases, when either tangent is +% 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. +% +% \begin{macrocode} +\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} +% 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@)\relax + \DividE\@KCzero\@tdA by\@SinDzero\p@ to \@KCzero + \fi +\fi +\MultiplyFN\@KCzero by \@Tzero to \@KCzero +\ScaleVect\@Dzero by\@KCzero to\@CPzero +\AddVect\@Pzero and\@CPzero to\@CPzero +% \end{macrocode} +% 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} +\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@)\relax + \DividE\@KCuno\@tdA by\@SinDuno\p@ to \@KCuno + \fi +\fi +\MultiplyFN\@KCuno by \@Tuno to \@KCuno +\ScaleVect\@Duno by\@KCuno to\@CPuno +\AddVect\@Puno and\@CPuno to\@CPuno +% \end{macrocode} +% Now we have the four points and we can instruct the internal +% \texttt{pict2e} macros to do the path drawing. +% \begin{macrocode} +\GetCoord(\@Puno)\@XPuno\@YPuno +\GetCoord(\@CPzero)\@XCPzero\@YCPzero +\GetCoord(\@CPuno)\@XCPuno\@YCPuno +\pIIe@curveto{\@XCPzero\unitlength}{\@YCPzero\unitlength}% + {\@XCPuno\unitlength}{\@YCPuno\unitlength}% + {\@XPuno\unitlength}{\@YPuno\unitlength}\egroup +% \end{macrocode} +% It does not have to stroke the curve because other Bézier splines might +% still be added to the path. On the opposite it memorises the final point +% as the initial point of the next spline +% \begin{macrocode} +\CopyVect\@Puno to\@Pzero +\CopyVect\@Duno to\@Dzero +\ignorespaces}% +% \end{macrocode} +% +% +% We finally define the overall |\Curve| macro that has two flavours: +% 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 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 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 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}{% + Curve specifications must contain at least two nodes!\Messagebreak + Please, control your \string\Curve\space specifications\MessageBreak}}} +\def\@Curve(#1)<#2>{% + \CurveTo#1WithDir{#2}% + \@ifnextchar\lp@r\@Curve{% + \@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| 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. +% +% 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 two times as +% many pieces of information in order to minimise the effects of the lack +% of control on the control points, and even with this added information +% the macro approaches the sine wave with less accuracy. At the same time +% for many applications the |\Curve| recursive macro proves to be much +% easier to use than with single arcs drawn with the |\CbezierBetween| +% macro. +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Quadratic splines} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% We want to create a recursive macro with the same properties as the above +% described |\Curve| macro, but that uses quadratic splines; we call it +% |\Qurve| so that the initial macro name letter reminds us of the nature +% of the splines being used. For the rest they have an almost identical +% syntax; with quadratic spline it is not possible to specify the distance +% of the control points from the extrema, since quadratic spline have just +% one control point that must lay at the intersection of the two tangent +% directions therefore with quadratic splines the tangents at each point +% cannot have the optional part that starts with a semicolon. The syntax, +% therefore, is just: +%\begin{flushleft} +%\cs{Qurve}\parg{first point}\aarg{direction}...\parg{any point}\aarg{direction}...\parg{last point}\aarg{direction} +%\end{flushleft} +% As with |\Curve|, also with |\Qurve| there is no limitation on the number +% of points, except for the computer memory size; it is advisable not to +% use many arcs otherwise it might become very difficult to find errors. +% +% The first macros that set up the recursion are very similar to those we +% wrote for |\Curve|: +% \begin{macrocode} +\def\Qurve{\@ifstar{\let\fillstroke\fillpath\Qurve@}% +{\let\fillstroke\strokepath\Qurve@}} + +\def\Qurve@(#1)<#2>{% + \StartCurveAt#1WithDir{#2}% + \@ifnextchar\lp@r\@Qurve{% + \PackageWarning{curve2e}{% + Quadratic curve specifications must contain at least + two nodes!\Messagebreak + Please, control your Qurve specifications\MessageBreak}}}% + +\def\@Qurve(#1)<#2>{\QurveTo#1WithDir{#2}% + \@ifnextchar\lp@r\@Qurve{% + \@ifnextchar[\@ChangeQDir\CurveEnd}}% + +\def\@ChangeQDir[#1]{\ChangeDir<#1>\@Qurve}% +% \end{macrocode} +% +% Notice that in case of long paths it might be better to use the single +% macros |\StartCurveAt|, |\QurveTo|, |\ChangeDir| and |\CurveFinish| +% (or |\FillCurve|), with their respective syntax, in such a way that a +% long list % of node-direction specifications passed to |\Qurve| may be +% split into shorter input lines in order to edit the input data in a more +% comfortable way. +% +% +% The macro that does everything is |\QurveTo|. it starts with reading its +% arguments received through the calling macro |\@Qurve| +% \begin{macrocode} +\def\QurveTo#1WithDir#2{% +\edef\@Puno{#1}\DirOfVect#2to\@Duno\bgroup +\DistanceAndDirOfVect\@Puno minus\@Pzero to\@Chord and\@DirChord +% \end{macrocode} +% It verifies if |\@Dpzero| and |\@Dpuno|, the directions at the two +% extrema of the arc, are parallel or anti-parallel by taking their +% ``scalar'' product (|\@Dpzero| times |\@Dpuno*|); if the imaginary +% component of the scalar product vanishes the two directions are +% parallel; in this case we produce an error message, but we continue by +% skipping this arc destination point; evidently the drawing will not be +% the desired one, but the job should not abort. +% \begin{macrocode} +\MultVect\@Dzero by*\@Duno to \@Scalar +\YpartOfVect\@Scalar to \@YScalar +\ifdim\@YScalar\p@=\z@ +\PackageWarning{curve2e}% + {Quadratic Bezier arcs cannot have their starting\MessageBreak + and ending directions parallel or antiparallel with\MessageBreak + each other. This arc is skipped and replaced with + a dotted line.\MessageBreak}% + \Dotline(\@Pzero)(\@Puno){2}\relax +\else +% \end{macrocode} +% Otherwise we rotate everything about the starting point so as to bring +% the chord on the real axis; we get also the components of the two +% directions that, we should remember, are unit vectors, not generic +% vectors, although the user can use the vector specifications that are +% more understandable to him/her: +% \begin{macrocode} +\MultVect\@Dzero by*\@DirChord to \@Dpzero +\MultVect\@Duno by*\@DirChord to \@Dpuno +\GetCoord(\@Dpzero)\@DXpzero\@DYpzero +\GetCoord(\@Dpuno)\@DXpuno\@DYpuno +% \end{macrocode} +% We check if the two directions point to the same half plane; this implies +% that these rotated directions point to different sides of the chord +% vector; all this is equivalent that the two direction Y components have +% opposite signs, so that their product is strictly negative, while the two +% X components product is not negative. +% \begin{macrocode} +\MultiplyFN\@DXpzero by\@DXpuno to\@XXD +\MultiplyFN\@DYpzero by\@DYpuno to\@YYD +\unless\ifdim\@YYD\p@<\z@\ifdim\@XXD\p@<\z@ +\PackageWarning{curve2e}% + {Quadratic Bezier arcs cannot have inflection points\MessageBreak + Therefore the tangents to the starting and ending arc\MessageBreak + points cannot be directed to the same half plane.\MessageBreak + This arc is skipped and replaced by a dotted line\MessageBreak}% + \Dotline(\@Pzero)(\@Puno){2}\fi +\else +% \end{macrocode} +% +% After these tests we should be in a ``normal'' situation. We first copy +% the expanded input information into new macros that have more explicit +% names: macros stating wit `S' denote the sine of the direction angle, +% while those starting with `C' denote the cosine of that angle. We will +% use these expanded definitions as we know we are working with the actual +% values. These directions are those relative to the arc chord. +% \begin{macrocode} +\edef\@CDzero{\@DXpzero}\relax +\edef\@SDzero{\@DYpzero}\relax +\edef\@CDuno{\@DXpuno}\relax +\edef\@SDuno{\@DYpuno}\relax +% \end{macrocode} +% Suppose we write the parametric equations of a straight line that departs +% from the beginning of the chord with direction angle $\phi_0$ and the +% corresponding equation of the straight line departing from the end of the +% chord (of length $c$) with direction angle $\phi_1$. We have to find the +% coordinates of the intersection point of these two straight lines. +%\begin{subequations} +%\begin{align} +% t \cos\phi_0 - s \cos\phi_1 &= c\\ +% t \sin\phi_0 - s \sin\phi_1 &= 0 +%\end{align} +%\end{subequations} +% The parameters $t$ and $s$ are just the running parameters; we have +% to solve those simultaneous equations in the unknown variables $t$ and +% $s$; these values let us compute the coordinates of the intersection +% point: +%\begin{subequations}\begin{align} +% X_C &=\dfrac{c\cos\phi_0\sin\phi_1}{\sin\phi_0\cos\phi_1 - \cos\phi_0\sin\phi_1} \\ +% Y_C &=\dfrac{c\sin\phi_0\sin\phi_1}{\sin\phi_0\cos\phi_1 - \cos\phi_0\sin\phi_1} +%\end{align}\end{subequations} +% +% Having performed the previous tests we are sure that the denominator is +% not vanishing (direction are not parallel or anti-parallel) and that it +% lays at the same side as the direction with angle $\phi_0$ with respect +% to the chord. +% +% The coding then goes on like this: +% \begin{macrocode} +\MultiplyFN\@SDzero by\@CDuno to\@tempA +\MultiplyFN\@SDuno by\@CDzero to\@tempB +\edef\@tempA{\strip@pt\dimexpr\@tempA\p@-\@tempB\p@}\relax +\@tdA=\@SDuno\p@ \@tdB=\@Chord\p@ \@tdC=\@tempA\p@ +\edef\@tempC{\strip@pt\dimexpr \@tdA*\@tdB/\@tdC}\relax +\MultiplyFN\@tempC by\@CDzero to \@XC +\MultiplyFN\@tempC by\@SDzero to \@YC +\ModOfVect\@XC,\@YC to\@KC +% \end{macrocode} +% Now we have the coordinates and the module of the intersection point +% vector taking into account the rotation of the real axis; getting back +% to the original coordinates before rotation, we get: +% \begin{macrocode} +\ScaleVect\@Dzero by\@KC to\@CP +\AddVect\@Pzero and\@CP to\@CP +\GetCoord(\@Pzero)\@XPzero\@YPzero +\GetCoord(\@Puno)\@XPuno\@YPuno +\GetCoord(\@CP)\@XCP\@YCP +% \end{macrocode} +% We have now the coordinates of the two extrema point of the quadratic arc +% and of the control point. Keeping in mind that the symbols $P_0$, $P_1$ +% and $C$ denote geometrical points but also their coordinates as ordered +% pairs of real numbers (i.e. they are complex numbers) we have to +% determine the parameters of a cubic spline that with suitable values +% get simplifications in its parametric equation so that it becomes a +% second degree function instead of a third degree one. It is possible, +% in spite of the fact the it appears impossible that e cubic form becomes +% a quadratic one; we should determine the values of $P_a$ and $P_b$ such +% that: +%\[ +% P_0(1-t)^3 +3P_a(1-t)^2t +3P_b(1-t)t^2 +P_1t^3 +%\] +% is equivalent to +%\[ +% P_0(1-t)^2 + 2C(1-t)t + P_1t^2 +%\] +% It turns out that the solution is given by +%\begin{equation} +% P_a= C+(P_0-C)/3 \qquad \text{and}\qquad P_b = C+(P_1- C)/3 +%\label{equ:spline3} +%\end{equation} +% +% The transformations implied by equations~\eqref{equ:spline3} are +% performed by the following macros already available from the |pict2e| +% package; we use them here with the actual arguments used for this task: +% \begin{macrocode} +\@ovxx=\@XPzero\unitlength \@ovyy=\@YPzero\unitlength +\@ovdx=\@XCP\unitlength \@ovdy=\@YCP\unitlength +\@xdim=\@XPuno\unitlength \@ydim=\@YPuno\unitlength + \pIIe@bezier@QtoC\@ovxx\@ovdx\@ovro + \pIIe@bezier@QtoC\@ovyy\@ovdy\@ovri + \pIIe@bezier@QtoC\@xdim\@ovdx\@clnwd + \pIIe@bezier@QtoC\@ydim\@ovdy\@clnht +% \end{macrocode} +% +% We call the basic |pict2e| macro to draw a cubic spline and we finish +% the conditional statements with which we started these calculations; +% eventually we close the group we opened at the beginning and we copy +% the terminal node information (position and direction) into the +% 0-labelled macros that indicate the starting point of the next arc. +% \begin{macrocode} + \pIIe@curveto\@ovro\@ovri\@clnwd\@clnht\@xdim\@ydim +\fi\fi\egroup +\CopyVect\@Puno to\@Pzero +\CopyVect\@Duno to\@Dzero +\ignorespaces} +% \end{macrocode} +% +% An example of usage is shown at the left in +% figure~\ref{fig:quadratic-arcs}\footnote{The commands \cs{legenda}, +% \cs{Pall} and \cs{Zbox} are specifically defined in the preamble of this +% document; they must be used within a \texttt{picture} environment. +% \cs{legenda} draws a framed legend made up of a single (short) math +% formula; \cs{Pall} is just a shorthand to put a filled small circle at a +% specified position' \cs{Zbox} puts a symbol in math mode a little +% displaced in the proper direction relative to a specified position. +% They are just handy to label certain objects in a \texttt{picture} +% diagram, but they are not part of the \texttt{curve2e} package.}. +% created with the code shown within figure~\ref{fig:quadratic-arcs}. +% +% Notice also that the inflexed line is made with two arcs that meet at +% the inflection point; the same is true for the line that resembles +% a sine wave. The cusps of the inner border of the green area are +% obtained with the usual optional argument already used also with the +% |\Curve| recursive macro. +% +% The ``circle'' inside the square frame is visibly different from a real +% circle, in spite of the fact that the maximum deviation from the true +% circle is just about 6\% relative to the radius; a quarter circle +% obtained with a single parabola is definitely a poor approximation of a +% real quarter circle; possibly by splitting each quarter circle in three +% or four partial arcs the approximation of a real quarter circle would be +% much better. On the right of figure~\ref{fig:quadratic-arcs} it is +% possible to compare a “circle” obtained with quadratic arcs with the the +% internal circle obtained with cubic arcs; the difference is easily seen +% even without using measuring instruments. +% +% With quadratic arcs we decided to avoid defining specific macros similar +% to |\CurveBetween| and |\CbezierBetween|; the first macro would not save +% any typing to the operator; furthermore it may be questionable if it was +% really useful even with cubic splines; the second macro with quadratic +% arcs is meaningless, since with quadratic arcs there is just one control +% point and there is no choice on its position. +% +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Conclusion} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% I believe that the set of new macros provided by this package can really +% help the user to draw his/her diagrams with more agility; it will be the +% accumulated experience to decide if this is true. +% +% As a personal experience we found very comfortable to draw ellipses and +% to define macros to draw not only such shapes or filled elliptical +% areas, but also to create “legends” with coloured backgrounds and +% borders. But this is an application of the functionality implemented in +% this package. +% +%\iffalse +% +%\fi +% +% +%\iffalse +%<*readme> +%\fi +% \section{The \texttt{README.txt} file} +%The following it the text that forms the contents of the |README.txt| +% file that accompanies the package. We fount it handy to have it in +% the documented source, because in this way certain informations +% don't need to be repeated again and again in different files. +% \begin{macrocode} +The package bundle curve2e is composed of the following files + +curve2e.dtx +curve2e.pdf +README.txt +curve2e-v161.sty +ltxdoc.cfg + +curve2e.dtx is the documented TeX source file of file curve2e.sty; you get +both curve2e.sty and curve2e.pdf by running pdflatex on curve2e.dtx. +The ltxdoc.cfg file customises the way the documentation file is typeset. +This .cfg file is not subject to the LPPL licence. + +README.txt, this file, contains general information. + +Curve2e-v161.sty contains the previous version of the package; see below +why the older version might become necessary for the end user. + +Curve2e.sty is an extension of the package pict2e.sty which extends the +standard picture LaTeX environment according to what Leslie Lamport +specified in the second edition of his LaTeX manual. + +This further extension allows to draw lines and vectors with any non +integer slope parameters, to draw dashed lined of any slope, to draw arcs +and curved vectors, to draw curves where just the interpolating nodes are +specified together with the slopes at the nodes; closed paths of any shape +can be filled with color; all coordinates are treated as ordered pairs, +i.e. 'complex numbers'; coordinates may be expressed also in polar form. +Some of these features have been incorporated in the 2011 version of +pict2e; therefore this package avoids any modification to the original +pict2e commands. + + +Curve2e now accepts polar coordinates in addition to the usual cartesian +ones; several macros have been upgraded and a new macro for tracing cubic +Bezier splines with their control nodes specified in polar form is available. The same applies to quadratic Bezier splines. + +This version solves a conflict with package eso-pic. + +This version of curve2e is almost fully compatible with pict2e dated +2014/01/12 version 0.2z. + +If you specify + +\usepackage[]{curve2e} + +the package pict2e is automatically invoked with the specified options. + +The -almost compatible- frase is necessary to explain that this version +of curve2e uses some `functions' of the LaTeX3 language that were made +available to the LaTeX developer by mid October 2018. Should the user +have an older or a basic/incomplete installation of the TeX system, +such L3 functions might not be available. This is why this +package checks the presence of the developer interface; in case +such interface is not available it falls back to the previous version +renamed curve2e-v161.sty, which is part of this bundle, and that must +not be renamed in any way. The compatibility mentioned above implies +that the user macros remain the same, but their implementation requires +the L3 interface. + +The package has the LPPL status of author maintained. + +According to the LPPL licence, you are entitled to modify this package, +as long as you fulfil the few conditions set forth by the Licence. + +Nevertheless this package is an extension to the standard LaTeX package +pict2e (2014). Therefore any change must be controlled on the +parent package pict2e, so as to avoid redefining what has already been +incorporated in the official package. + +If you prefer sending me your modifications, as long as I will maintain +this package, I will possibly include every (documented) suggestion or +modification into this package and, of course, I will acknowledge your +contribution. + +Claudio Beccari + +claudio dot beccari at gmail dot com +% \end{macrocode} +%\iffalse +% +%\fi +%\iffalse +%<*v161> +%\fi +% \section{The fall-back package version \texttt{curve2e-v161}} +% this is the fall-back version of |curve2e-v161.sty| to which the main +% file |curve2e.sty| falls back in case the interface package |xfp| is not +% available. % \begin{macrocode} +\NeedsTeXFormat{LaTeX2e}[2016/01/01] +\ProvidesPackage{curve2e-v161}% + [2019/02/07 v.1.61 Extension package for pict2e] + +\RequirePackage{color} +\RequirePackageWithOptions{pict2e}[2014/01/01] +\RequirePackage{xparse} \def\TRON{\tracingcommands\tw@ \tracingmacros\tw@}% \def\TROF{\tracingcommands\z@ \tracingmacros\z@}% -% \end{macrocode} -% -% Next we define some new dimension registers that will be used by the -% subsequent macros; should they be already defined, there will not be any -% redefinition; nevertheless the macros should be sufficiently protected so as -% to avoid overwriting register values loaded by other macro packages. -% \begin{macrocode} \ifx\undefined\@tdA \newdimen\@tdA \fi \ifx\undefined\@tdB \newdimen\@tdB \fi \ifx\undefined\@tdC \newdimen\@tdC \fi @@ -757,154 +3722,29 @@ README.txt and manifest.txt. \ifx\undefined\@tdE \newdimen\@tdE \fi \ifx\undefined\@tdF \newdimen\@tdF \fi \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 -% are half as thick; so when the default line thickness is specified to, say, -% 1pt, thick lines will be 1pt thick and thin lines will be 0.5pt thick. The -% default whole width of thick lines is 0,8pt, but this is specified in the -% kernel of \LaTeX\ and\slash or in \texttt{pict2e}. On the opposite it is -% necessary to redefine |\linethickness| because the \LaTeX\ kernel global -% definition does not hide the space after the closed brace when you enter -% something such as |\linethickness{1mm}| followed by a space or a new line. -%\footnote{Thanks to Daniele Degiorgi (\texttt{degiorgi@inf.ethz.ch}).} -% \begin{macrocode} \gdef\linethickness#1{\@wholewidth#1\@halfwidth.5\@wholewidth\ignorespaces}% \newcommand\defaultlinethickness[1]{\defaultlinewidth=#1\relax \def\thicklines{\linethickness{\defaultlinewidth}}% \def\thinlines{\linethickness{.5\defaultlinewidth}}% \thinlines\ignorespaces} -% \end{macrocode} -% The |\ignorespaces| at the end of this and the subsequent macros is for -% avoiding spurious spaces to get into the picture that is being drawn, because -% these spaces introduce picture deformities often difficult to spot and -% eliminate. -% -% \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 inside the box created with |\put|. The two arguments -% define the horizontal and the vertical component respectively. -% \begin{macrocode} \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 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} \def\segment(#1)(#2){\@killglue\polyline(#1)(#2)}% -% \end{macrocode} -% By passing its ending points coordinates to the |\polyline| macro, both macro -% arguments are a pair of coordinates, not their components; in other words, if -% $P_1=(x_1, y_2)$ and $P_2=(x_2, y_2)$, then the first argument is the couple -% $x_1, y_1$ and likewise the second argument is $x_2, y_2$. Please remember that -% the decimal separator is the decimal \emph{point}, while the \emph{comma} acts -% as coordinate separator. This recommendation is particularly important for -% non-English speaking users, since in all other languages the comma -% must be used as the decimal separator. -% -% The |\line| macro is redefined by making use of a new division routine that -% receives in input two dimensions and yields on output their fractional ratio. -% The beginning of the macro definition is the same as that of \texttt{pict2e}: -% \begin{macrocode} \def\line(#1)#2{\begingroup \@linelen #2\unitlength \ifdim\@linelen<\z@\@badlinearg\else -% \end{macrocode} -% but as soon as it is verified that the line length is not negative, things -% change remarkably; in facts the machinery for complex numbers is invoked. -% This makes the code much simpler, not necessarily more efficient; nevertheless -% |\DirOfVect| takes the only macro argument (that actually contains a comma -% separated pair of fractional numbers) and copies it to |\Dir@line| (an -% arbitrarily named control sequence) after re-normalizing to unit magnitude; -% this is passed to |GetCoord| that separates the two components into the -% control sequences |\d@mX| and|\d@mY|; these in turn are the values that are -% actually operated upon by the subsequent commands. -% \begin{macrocode} \expandafter\DirOfVect#1to\Dir@line \GetCoord(\Dir@line)\d@mX\d@mY -% \end{macrocode} -% The normalized vector direction is actually formed with the directing cosines -% of the line direction; since the line length is actually the horizontal -% component for non vertical lines, it is necessary to compute the actual line -% length for non vertical lines by dividing the given length by the -% magnitude of horizontal cosine |\d@mX|, and the line length is accordingly -% scaled: -% \begin{macrocode} \ifdim\d@mX\p@=\z@\else \DividE\ifdim\d@mX\p@<\z@-\fi\p@ by\d@mX\p@ to\sc@lelen \@linelen=\sc@lelen\@linelen \fi -% \end{macrocode} -% Of course, if the line is vertical this division must not take place. -% Finally the \texttt{moveto}, \texttt{lineto} and \texttt{stroke} language -% keywords are invoked by means of the internal \texttt{pict2e} commands in -% order to draw the line. Notice that even vertical lines are drawn with the -% ``PostScript'' commands instead of resorting to the dvi low level language -% that was used both in \texttt{pict2e} and in the original \texttt{picture} -% commands; it had a meaning in the old times, but it certainly does not have -% any when lines are drawn by the driver that drives the output to a visible -% document form, not by \TeX\ the program. -% \begin{macrocode} \moveto(0,0) \pIIe@lineto{\d@mX\@linelen}{\d@mY\@linelen}% \strokepath \fi \endgroup\ignorespaces}% -% \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 with the 2004 version that was limited to -% integer direction coefficients up to 999 in magnitude. -% -% \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{% @@ -912,17 +3752,17 @@ README.txt and manifest.txt. \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 - \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 - \DividE\p@ by\NumA\p@ to \@tempa - \MultVect\V@ttC by\@tempa,0 to\V@ttB + \SubVect\V@ttA from\V@ttB to\V@ttC + \ModOfVect\V@ttC to\DlineMod + \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 + \DividE\p@ by\NumA\p@ to \@tempa + \MultVect\V@ttC by\@tempa,0 to\V@ttB \MultVect\V@ttB by 2,0 to\V@ttC - \advance\NumB\@ne + \advance\NumB\@ne \edef\@mpt{\noexpand\egroup \noexpand\multiput(\V@ttA)(\V@ttC){\number\NumB}% {\noexpand\LIne(\V@ttB)}}% @@ -931,53 +3771,6 @@ README.txt and manifest.txt. \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 two given points; -% the dots are rather small, therefore the inter dot distance is computed in -% such a way as to have the first and the last dot at the exact position of -% the dotted-line end-points; again the specified dot distance is nominal in -% 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{% @@ -985,12 +3778,12 @@ README.txt and manifest.txt. \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 + \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}}}}% @@ -998,80 +3791,11 @@ README.txt and manifest.txt. \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; 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. -% Notice that package |eso-pic| uses macros in its definitions but its -% original macro |\LenToUnit| is incompatible with this |\GetCoord| macro; -% its function is to translate real lengths into coefficients to be used as -% multipliers of the current |\unitlength|; in case that the |eso-pic| -% had been loaded at the |\begin{document}| execution, the |eso-pic| -% macro is redefined using the e-\TeX\ commands so as to make it compatible -% with these local macros. Thanks to Franz-Joseph Berthold who was so kind -% to spot the bug. -% \begin{macrocode} \AtBeginDocument{\@ifpackageloaded{eso-pic}{% \renewcommand\LenToUnit[1]{\strip@pt\dimexpr#1*\p@/\unitlength}}{}} \def\GetCoord(#1)#2#3{% \expandafter\SplitNod@\expandafter(#1)#2#3\ignorespaces} -% \end{macrocode} -% 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\isnot@polar#1:#2!!{\def\@tempOne{#2}\ifx\@tempOne\empty \expandafter\@firstoftwo\else \expandafter\@secondoftwo\fi @@ -1096,105 +3820,16 @@ README.txt and manifest.txt. \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 -% corresponding to the limitations specified by Lamport (integer three digit -% signed numbers) and sets up a transformation in order to make it possible to -% draw each vector as an horizontal left-to-right arrow and then to rotate it by -% its angle about its tail point; with |pict2e| 2009, possibly this redefinition -% of |\vector| is not necessary, but we do it as well and for the same reasons -% we had for redefining |\line|; actually there are two macros for tracing the -% 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 -%|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 -% |curve2e| package redefinitions. -% -% Because of these features the redefinitions and the new macros are different -% from those used for straight lines. -% -% We start with the redefinition of |\vector| and we use the machinery for -% vectors (as complex numbers) we used for |\line|. -% \begin{macrocode} \def\vector(#1)#2{% \begingroup \GetCoord(#1)\d@mX\d@mY \@linelen#2\unitlength -% \end{macrocode} -% As in \texttt{pict2e} we avoid tracing vectors if the slope parameters are -% both zero. -% \begin{macrocode} \ifdim\d@mX\p@=\z@\ifdim\d@mY\p@=\z@\@badlinearg\fi\fi -% \end{macrocode} -% But we check only for the positive nature of the $l_x$ component; if it is -% negative, we simply change sign instead of blocking the typesetting process. -% This is useful also for macros |\Vector| and |\VECTOR| to be defined in a -% while. -% \begin{macrocode} \ifdim\@linelen<\z@ \@linelen=-\@linelen\fi -% \end{macrocode} -% We now make a vector with the slope coefficients even if one or the other is -% zero and we determine its direction; the real and imaginary parts of the -% direction vector are also the values we need for the subsequent rotation. -% \begin{macrocode} \MakeVectorFrom\d@mX\d@mY to\@Vect \DirOfVect\@Vect to\Dir@Vect -% \end{macrocode} -% In order to be compatible with the original \texttt{pict2e} we need to -% transform the components of the vector direction in lengths with the specific -% names |\@xdim| and |\@ydim| -% \begin{macrocode} \YpartOfVect\Dir@Vect to\@ynum \@ydim=\@ynum\p@ \XpartOfVect\Dir@Vect to\@xnum \@xdim=\@xnum\p@ -% \end{macrocode} -% If the vector is really sloping we need to scale the $l_x$ component in order -% to get the vector total length; we have to divide by the cosine of the vector -% inclination which is the real part of the vector direction. I use my division -% macro; since it yields a ``factor'' I directly use it to scale the length of -% the vector. I finally memorize the true vector length in the internal -% dimension |@tdB| -% \begin{macrocode} \ifdim\d@mX\p@=\z@ \else\ifdim\d@mY\p@=\z@ \else @@ -1203,27 +3838,10 @@ README.txt and manifest.txt. \fi \fi \@tdB=\@linelen -% \end{macrocode} -% The remaining code is definitely similar to that of \texttt{pict2e}; the -% real difference consists in the fact that the arrow is designed by itself -% without the stem; but it is placed at the vector end; therefore the first -% statement is just the transformation matrix used by the output driver to -% rotate the arrow tip and to displace it the right amount. But in order -% to draw only the arrow tip I have to set the |\@linelen| length to zero. -% \begin{macrocode} \pIIe@concat\@xdim\@ydim{-\@ydim}\@xdim{\@xnum\@linelen}{\@ynum\@linelen}% \@linelen\z@ \pIIe@vector \fillpath -% \end{macrocode} -% Now we can restore the stem length that must be shortened by the dimension of -% the arrow; examining the documentation of \texttt{pict2e} we discover that -% we have to shorten it by an approximate amount of $AL$ (with the notations of -% \texttt{pict2e}, figs~10 and~11); the arrow tip parameters are stored in -% certain variables with which we can determine the amount of the stem -% shortening; if the stem was too short and the new length is negative, we -% refrain from designing such stem. -% \begin{macrocode} \@linelen=\@tdB \@tdA=\pIIe@FAW\@wholewidth \@tdA=\pIIe@FAL\@tdA @@ -1233,96 +3851,16 @@ README.txt and manifest.txt. \pIIe@lineto{\@xnum\@linelen}{\@ynum\@linelen}% \strokepath\fi \endgroup} -% \end{macrocode} -% -% Now we define the macro that does not require the specification of the length -% or the $l_x$ length component; the way the new |\vector| macro works does not -% actually require this specification, because \TeX\ can compute the vector -% length, provided the two direction components are exactly the horizontal and -% vertical vector components. If the horizontal component is zero, the actual -% length% must be specified as the vertical component. -% \begin{macrocode} \def\Vector(#1){{% \GetCoord(#1)\@tX\@tY -\ifdim\@tX\p@=\z@\vector(\@tX,\@tY){\@tY} -\else -\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. -% \begin{macrocode} -\def\VECTOR(#1)(#2){\begingroup -\SubVect#1from#2to\@tempa -\expandafter\put\expandafter(#1){\expandafter\Vector\expandafter(\@tempa)}% -\endgroup\ignorespaces} -% \end{macrocode} -% -% The \texttt{pict2e} documentation says that if the vector length is zero the -% macro designs only the arrow tip; this may work with macro |\vector|, -% certainly not with |\Vector| and |\VECTOR|. This might be useful for adding -% an arrow tip to a circular arc. See examples in figure~\ref{fig:vectors}. -% -% \begin{figure} -% \begin{minipage}{.48\textwidth} -% \begin{verbatim} -% \unitlength=.5mm -% \begin{picture}(60,20) -% \put(0,0){\GraphGrid(60,20)} -% \put(0,0){\vector(1.5,2.3){10}} -% \put(20,0){\Vector(10,15.33333)} -% \VECTOR(40,0)(50,15.33333) -% \end{picture} -% \end{verbatim} -% \end{minipage} -% \hfill -% \begin{minipage}{.48\textwidth}\centering -% \unitlength=.5mm -% \begin{picture}(60,20) -% \put(0,0){\GraphGrid(60,20)} -% \put(0,0){\vector(1.5,2.3){10}} -% \put(20,0){\Vector(10,15.33333)} -% \VECTOR(40,0)(50,15.33333) -% \end{picture} -% \end{minipage} -% \caption{Three (displaced) identical vectors obtained with the three vector -% macros.}\label{fig:vectors} -% \end{figure} -% -% \subsection{Polylines} -% We now define the polygonal line macro; its syntax is very simple -% \begin{flushleft} -% \cs{polygonal}\oarg{join}\texttt{(}$P_0$\texttt{)(}$P_1$\texttt{)(}$P_2$)% -% \texttt{\dots(}$P_n$\texttt{)} -% \end{flushleft} -% Remember: |\polyline| has been incorporated into |pict2e| 2009, but we -% redefine it so as to allow an optional argument to specify the line join type. -% -% In order to write a recursive macro we need aliases for the parentheses; -% actually we need only the left parenthesis, but some editors complain about -% unmatched delimiters, so we define an alias also for the right parenthesis. -% \begin{macrocode} -\let\lp@r( \let\rp@r) -% \end{macrocode} -% The first call to |\polyline|, besides setting the line joints, examines -% the first point coordinates and moves the drawing position to this point; -% afterwards it looks for the second point coordinates; they start with a -% left parenthesis; if this is found the coordinates should be there, but -% if the left parenthesis is missing (possibly preceded by spaces that are -% ignored by the |\@ifnextchar| macro) then a warning message is output -% together with the line number where the missing parenthesis causes the -% warning: beware, this line number might point to several lines further on -% along the source file! In any case it's necessary to insert a |\@killglue| -% command, because |\polyline| refers to absolute coordinates not necessarily -% is put in position through a |\put| command that provides to eliminate any -% spurious spaces preceding this command. -% -% In order to allow a specification for the joints of the various segments of -% a polygonal line it is necessary to allow for an optional parameter; the default -% join is the bevel join. -% \begin{macrocode} +\ifdim\@tX\p@=\z@\vector(\@tX,\@tY){\@tY} +\else +\vector(\@tX,\@tY){\@tX}\fi}} +\def\VECTOR(#1)(#2){\begingroup +\SubVect#1from#2to\@tempa +\expandafter\put\expandafter(#1){\expandafter\Vector\expandafter(\@tempa)}% +\endgroup\ignorespaces} +\let\lp@r( \let\rp@r) \renewcommand*\polyline[1][\beveljoin]{\p@lylin@[#1]} \def\p@lylin@[#1](#2){\@killglue#1\GetCoord(#2)\d@mX\d@mY @@ -1333,24 +3871,14 @@ README.txt and manifest.txt. Control your polyline specification\MessageBreak}% \ignorespaces}} -% \end{macrocode} -% 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. -% \begin{macrocode} \def\p@lyline(#1){\GetCoord(#1)\d@mX\d@mY \pIIe@lineto{\d@mX\unitlength}{\d@mY\unitlength}% \@ifnextchar\lp@r{\p@lyline}{\strokepath\ignorespaces}} -% \end{macrocode} -% -% The same treatment must be done for the \cs{polygon} macros -% \begin{macrocode} -\providecommand\polygon{} +\providecommand\polygon{} \RenewDocumentCommand\polygon{s O{\beveljoin} }{\@killglue\begingroup \IfBooleanTF{#1}{\@tempswatrue}{\@tempswafalse}% -\@polygon[#2]} - +\@polygon[#2]} + \def\@polygon[#1](#2){\@killglue#1\GetCoord(#2)\d@mX\d@mY \pIIe@moveto{\d@mX\unitlength}{\d@mY\unitlength}% \@ifnextchar\lp@r{\@@polygon}{% @@ -1358,48 +3886,13 @@ README.txt and manifest.txt. {Polygons require at least two vertices!\MessageBreak Control your polygon specification\MessageBreak}% \ignorespaces}} - + \def\@@polygon(#1){\GetCoord(#1)\d@mX\d@mY \pIIe@lineto{\d@mX\unitlength}{\d@mY\unitlength}% \@ifnextchar\lp@r{\@@polygon}{\pIIe@closepath \if@tempswa\pIIe@fillGraph\else\pIIe@strokeGraph\fi \endgroup \ignorespaces}} -% \end{macrocode} -% Now, for example, a filled polygon can be drawn using polar coordinates -% for its vertices; see figure~\ref{fig:filled-polygon} -% -% \begin{figure} -% \begin{minipage}{0.55\textwidth} -%\begin{verbatim} -% \unitlength=0.07\hsize -% \begin{picture}(8,8)(-4,-4)\color{red} -% \polygon*(45:4)(135:4)(-135:4)(-45:4) -% \end{picture} -%\end{verbatim} -% \end{minipage} -% \hfill -% \begin{minipage}{0.4\textwidth}\centering -% \unitlength=0.07\hsize -% \begin{picture}(8,8)(-4,-4)\color{red} -% \polygon*(45:4)(135:4)(-135:4)(-45:4) -% \end{picture} -% \end{minipage} -% \caption{The code and the result of defining a polygon with its vertex -% polar coordinates}\label{fig:filled-polygon} -% \end{figure} -% -% -% \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 -% aid and the user should know what he/she is doing; nevertheless it is -% advisable to displace the grid by means of a |\put| command so that its grid -% lines coincide with the graph coordinates multiples of 10. Missing to do so -% the readings become cumbersome. The |\RoundUp| macro provides to increase the -% grid dimensions to integer multiples of ten. -% \begin{macrocode} \def\GraphGrid(#1,#2){\bgroup\textcolor{red}{\linethickness{.1\p@}% \RoundUp#1modulo10to\@GridWd \RoundUp#2modulo10to\@GridHt \@tempcnta=\@GridWd \divide\@tempcnta10\relax \advance\@tempcnta\@ne @@ -1407,184 +3900,32 @@ README.txt and manifest.txt. \@tempcnta=\@GridHt \divide\@tempcnta10\advance\@tempcnta\@ne \multiput(0,0)(0,10){\@tempcnta}{\line(1,0){\@GridWd}}\thinlines}% \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 -% a while. -% \begin{macrocode} \def\RoundUp#1modulo#2to#3{\expandafter\@tempcnta\Integer#1.??% \count254\@tempcnta\divide\count254by#2\relax \multiply\count254by#2\relax \count252\@tempcnta\advance\count252-\count254 \ifnum\count252>0\advance\count252-#2\relax \advance\@tempcnta-\count252\fi\edef#3{\number\@tempcnta}\ignorespaces}% -% \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 -% 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. -% \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 bits of the fractional part is constant (16) it is said -% that the number representation is in \emph{fixed radix}. This is much -% different form the scientific approach to fractional numbers where -% a 32-bit word reserves 24 bits to the significant digits, one bit for the sign, -% 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 milliseconds. -% -% \subsection{The new division macro} -% 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 -% made positive; should the numerator be zero it directly issues the zero -% 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 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 macro is already defined: -% \begin{macrocode} \unless\ifdefined\DividE -% \end{macrocode} -% Notice that |\dimexpr| is the specific extended mode control sequence we are -% going to use in order to perform our task; if the interpreter program is too -% old and/or it is a recent version, but it was compiled without activating the -% extended mode, the macro |\dimexpr| is undefined. -% -% 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 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 -% is stored into an internal register of 64\,bits; the final division by a factor -% stored into a register of 32 bits, so that in terms of scaled points a division -% 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 but not the termination of the program. During the -% division and a scaling down by 16 bits, the result is not simply truncated, but -% it is rounded to the nearest integer (in scaled points). The first two operands -% are lengths and the third is a macro. -% -% \begin{macrocode} - \def\DividE#1by#2to#3{\bgroup - \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 - \edef\x{% - \noexpand\egroup\noexpand\def\noexpand#3{% - \strip@pt\dimexpr\@DimA*\Num/\Den\relax}}% - \fi - \x\ignorespaces}% - \fi -% \end{macrocode} -% -% We need a similar macro to divide two fractional or integer numbers, -% not dimensions, and produce a macro that contains the fractional result. -% \begin{macrocode} +\def\DividE#1by#2to#3{\bgroup +\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 + \edef\x{% + \noexpand\egroup\noexpand\def\noexpand#3{% + \strip@pt\dimexpr\@DimA*\Num/\Den\relax}}% +\fi +\x\ignorespaces}% +\fi \unless\ifdefined\DivideFN \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|. -% \begin{macrocode} \unless\ifdefined\MultiplY \def\MultiplY#1by#2to#3{\bgroup \dimendef\@DimA 2254 \dimendef\@DimB2255 @@ -1596,105 +3937,20 @@ README.txt and manifest.txt. \let\MultiplyFN\MultiplY \fi \fi -% \end{macrocode} -% The next macro uses the \verb|\strip@pt| \LaTeX\ kernel macro to get the -% numerical value of a measure in points. One has to call |\Numero| with -% a control sequence and a dimension; the dimension value in points is -% assigned to the control sequence. -% \begin{macrocode} \unless\ifdefined\Numero \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 meaning \verb|\relax| -% then executes the test; therefore an undefined macro name is always defined -% to mean |\relax|. -% -% \subsection{Trigonometric functions} -% We now start with trigonometric functions. We define the macros |\SinOf|, -% |\CosOf| and |\TanOf| (we might define also |\CotOf|, but the cotangent does -% not appear so essential) by means of the parametric formulas that require the -% knowledge of the tangent of the half angle. We want to specify the angles -% in sexagesimal degrees, not in radians, so we can make accurate reductions to -% the main quadrants. We use the formulas -% \begin{eqnarray*} -% \sin\theta &=& \frac{2}{\cot x + \tan x}\\ -% \cos\theta &=& \frac{\cot x - \tan x}{\cot x + \tan x}\\ -% \tan\theta &=& \frac{2}{\cot x - \tan x}\\ -% \noalign{\hbox{where}} -% x &=& \theta/114.591559 -% \end{eqnarray*} -% is the half angle in degrees converted to radians. -% -% We use this slightly modified set of parametric formulas because the cotangent -% of $x$ is a by product of the computation of the tangent of $x$; in this way -% we avoid computing the squares of numbers that might lead to overflows. For -% the same reason we avoid computing the value of the trigonometric functions -% 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° -% the magnitude of the independent variable $y=2x$ (the angle in degrees -% 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 $10^{-6}$). -% -% We keep using grouping so that internal variables are local to these groups -% and do not mess up other things. -% -% The first macro is the service routine that computes the tangent and the -% cotangent of the half angle in radians; since we have to use always the -% reciprocal of this value, we call it |\X@| but in spite of the similarity it -% is the reciprocal of $x$. Notice that parameter \texttt{\#1} must be a length. -% \begin{macrocode} \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 -% (truncated) continued fraction expansion of the tangent function: -% \[ -% \tan x = \frac{1}{\displaystyle \frac{1\mathstrut}{\displaystyle x} -% -\frac{1}{\displaystyle \frac{3\mathstrut}{\displaystyle x} -% -\frac{1}{\displaystyle \frac{5\mathstrut}{\displaystyle x} -% -\frac{1}{\displaystyle \frac{7\mathstrut}{\displaystyle x} -% -\frac{1}{\displaystyle \frac{9\mathstrut}{\displaystyle x} -% -\frac{1}{\displaystyle \frac{11\mathstrut}{\displaystyle x} -% -\cdots}}}}}} -% \] -% \begin{macrocode} \countdef\I=2546\def\Tan{0}\I=11\relax \@whilenum\I>\z@\do{% \@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}% -% \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°, 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. -% -% Since all computations are done within a group, a trick is necessary in order to -% extract the sine value from the group; this is done by defining within the group -% a macro (in this case |\endSinOf|) with the expanded definition of the result, -% but in charge of of closing the group, so that when the group is closed the -% auxiliary function is not defined any more, although its expansion keeps getting -% executed so that the expanded result is thrown beyond the group end. -% \begin{macrocode} \def\SinOf#1to#2{\bgroup% \@tdA=#1\p@% \ifdim\@tdA>\z@% @@ -1733,11 +3989,6 @@ README.txt and manifest.txt. \edef\endSinOf{\noexpand\egroup \noexpand\def\noexpand#2{\@tempA}\noexpand\ignorespaces}% \endSinOf}% -% \end{macrocode} -% -% For the computation of the cosine we behave in a similar way using also the -% identical trick for throwing the result beyond the group end. -% \begin{macrocode} \def\CosOf#1to#2{\bgroup% \@tdA=#1\p@% \ifdim\@tdA>\z@% @@ -1745,11 +3996,9 @@ README.txt and manifest.txt. \else% \@whiledim\@tdA<\z@\do{\advance\@tdA 360\p@}% \fi -% \ifdim\@tdA>180\p@ \@tdA=-\@tdA \advance\@tdA 360\p@ \fi -% \ifdim\@tdA<90\p@ \def\Segno{+}% \else @@ -1778,13 +4027,6 @@ README.txt and manifest.txt. \edef\endCosOf{\noexpand\egroup \noexpand\def\noexpand#2{\@tempA}\noexpand\ignorespaces}% \endCosOf}% -% \end{macrocode} -% -% 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° 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@% \ifdim\@tdA>90\p@% @@ -1817,121 +4059,14 @@ README.txt and manifest.txt. \edef\endTanOf{\noexpand\egroup \noexpand\def\noexpand#2{\@tempA}\noexpand\ignorespaces}% \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 algorithm crashes; -% therefore it's virtually impossibile to get an absolute error lower than 0.0005. -% -% It is probably better to refer to the Newton iterations for solving the -% equation: -%\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}[!htb]\centering\unitlength=0.01\textwidth -%\begin{picture}(100,80) -%\legenda(15,73){y=\tan\theta} -%\legenda(37,73){t=\tan\theta_\infty} -%\put(0,0){\vector(1,0){100}}\Zbox(100,0)[br]{\theta} -%\put(0,0){\vector(0,1){80}}\Zbox(0,80)[tl]{y} -%\Dashline(90,0)(90,80){2.5} -%\Zbox(90,0)[br]{\pi/2} -%\Pall[2](28.8,11)\Line(0,11)(80,11)%\Dashline(28.8,0)(28.8,11){2.5} -%\Zbox(0,11)[bl]{t}\Zbox(28.8,0)[br]{\theta_\infty} -% -%\Dashline(34,0)(34,11){1.5}\Zbox(34,0)[bl]{\theta_{i+1}} -% -%\Pall[2](47.5,21.83)\Dashline(47.5,0)(47.5,21.83){2.5} -%\Dashline(0,21.83)(47.5,21.83){2.5} -%\Zbox(0,20.83)[bl]{y_i}\Zbox(47.5,0)[bl]{\theta_{i}} -% -%\Pall[2](61.2,36.38)\Dashline(61.2,0)(61.2,36.38){2.5} -%\Dashline(0,36.38)(61.2,36.38){2.5} -%\Zbox(0,36.38)[bl]{y_{i-1}}\Zbox(61.2,0)[bl]{\theta_{i-1}} -% -%\Pall[2](72,61.55367)\Dashline(72,0)(72,61.55367){2.5} -%\Dashline(0,61.55367)(72,61.55367){2.5} -%\Zbox(0,61.55367)[bl]{y_{i-2}}\Zbox(72,0)[bl]{\theta_{i-2}} -% -%\put(0,0){\linethickness{1pt} -%\Curve%(0,0)<1,0.34907>(28.8,11)<1,0.45456>(47.5,21.83)<1,0.76479>% -%(61.2,36.38)<1,1.91499>(72,61.55367)<1,4.65428>(74.4,71.6)<1,6.14571> -%}% -% -%\Line(34,11)(47.5,21.83) -%\Line(61.2,36.38)(47.5,11) -%\Line(72,61.55367)(61.2,11) -%\end{picture} -%\caption{Newton's method of tangents}\label{fig:tangenti} -%\end{figure} -% -% 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; possibly we limit the computations -% to the first octant and we resort to the cotangent when the tangent exceeds -% one; in this case we use the same algorithm, but we have to get the -% complementary angle; in order to make computations with positive numbers, -% we save the initial tangent sign and we restore it to the result. -% \begin{macrocode} \def\ArcTanOf#1to#2{\bgroup \countdef\Inverti 4444\Inverti=0 \def\Segno{} \edef\@tF{#1}\@tdF=\@tF\p@ \@tdE=57.295778\p@ \@tdD=\ifdim\@tdF<\z@ -\@tdF\def\Segno{-}\else\@tdF\fi -\ifdim\@tdD>\p@ +\ifdim\@tdD>\p@ \Inverti=\@ne -\@tdD=\dimexpr\p@*\p@/\@tdD\relax +\@tdD=\dimexpr\p@*\p@/\@tdD\relax \fi \unless\ifdim\@tdD>0.02\p@ \def\@tX{\strip@pt\dimexpr57.295778\@tdD\relax}% @@ -1951,125 +4086,8 @@ README.txt and manifest.txt. \edef\@tX{\strip@pt\dimexpr90\p@-\@tX\p@\relax} \fi \edef\x{\egroup\noexpand\edef\noexpand#2{\Segno\@tX}}\x\ignorespaces}% -% \end{macrocode} -% -% \subsection{Arcs and curves preliminary information} -% 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 -% arc starting point and the angular aperture. The arc has its reference point in -% its center, therefore it does not need to be put in place by the command |\put|; -% 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{center})(\meta{starting point})\marg{angle} -% \end{flushleft} -% which is totally equivalent to: -% \begin{flushleft}\ttfamily -% \cs{put}(\meta{center})\marg{\upshape\cs{Arc}(0,0)(\meta{starting point})\marg{angle}} -% \end{flushleft} -% 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. -% -% The end point is obtained from the rotation of the starting point around the -% center; but the \texttt{pict2e} command |\pIIe@rotate| is such that the -% 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 roto-amplification operators. -% -% \subsection{Complex number macros} -% 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 used by the |picture| -% environment) there is the other conventional representation used by the -% engineers that stress the roto-amplification nature of a complex number: -%\[ -%(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 or polar form of the Euler's formula -% \[ -% \mathrm{e}^{\mathrm{j}\phi} = \cos\phi+\mathrm{j}\sin\phi -% \] -% -% The magnitude of a vector is determined by taking a clever square root of a -% function of the real and the imaginary parts; see further on. -% -% It's better to represent each complex number with one control sequence; this -% implies frequent assembling and disassembling the pair of real numbers that -% make up a complex number. These real components are assembled into the -% defining control sequence as a couple of coordinates, i.e.\ two comma -% separated integer or fractional signed decimal numbers. -% -% For assembling two real numbers into a complex number we use the following -% elementary macro: -% \begin{macrocode} \def\MakeVectorFrom#1#2to#3{\edef#3{#1,#2}\ignorespaces}% -% \end{macrocode} -% Another elementary macro copies a complex number into another one: -% \begin{macrocode} \def\CopyVect#1to#2{\edef#2{#1}\ignorespaces}% -% \end{macrocode} -% The magnitude is determined with the macro |\ModOfVect| with delimited -% arguments; as usual it is assumed that the results are retrieved by means of -% control sequences, not used directly. -% -% The magnitude $M$ is determined by taking the moduli of the real and -% imaginary parts, changing their signs if necessary; the larger component is -% then taken as the reference one so that, if $a$ is larger than $b$, the -% square root of the sum of their squares is computed as such: -% \[ -% M = \sqrt{a^2+b^2} = \vert a\vert\sqrt{1+(b/a)^2} -% \] -% In this way the radicand never exceeds 2 and it is quite easy to get its -% square root by means of the Newton iterative process; due to the quadratic -% convergence, five iterations are more than sufficient. When one of the -% components is zero, the Newton iterative process is skipped. The overall -% macro is the following: -% \begin{macrocode} \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 @@ -2102,16 +4120,6 @@ README.txt and manifest.txt. \fi \Numero#2\@tempdimc \ignorespaces}% -% \end{macrocode} -% As a byproduct of the computation the control sequence |\@tempdimc| contains -% 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 -% form of the direction vector. If by any chance the direction of the null -% vector is requested, the output is again the null vector, without -% normalization. -% \begin{macrocode} \def\DirOfVect#1to#2{\GetCoord(#1)\t@X\t@Y \ModOfVect#1to\@tempa \unless\ifdim\@tempdimc=\z@ @@ -2119,68 +4127,25 @@ README.txt and manifest.txt. \DividE\t@Y\p@ by\@tempdimc to\t@Y \fi \MakeVectorFrom\t@X\t@Y to#2\ignorespaces}% -% \end{macrocode} -% -% A cumulative macro uses the above ones to determine with one call both the -% magnitude and the direction of a complex number. The first argument is the -% input complex number, the second its magnitude, and the third is again a -% complex number normalized to unit magnitude (unless the input was the null -% complex number); remember always that output quantities must be specified -% with control sequences to be used at a later time. -% \begin{macrocode} \def\ModAndDirOfVect#1to#2and#3{% \GetCoord(#1)\t@X\t@Y \ModOfVect#1to#2% \ifdim\@tempdimc=\z@\else - \DividE\t@X\p@ by\@tempdimc to\t@X + \DividE\t@X\p@ by\@tempdimc to\t@X \DividE\t@Y\p@ by\@tempdimc to\t@Y \fi \MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% -% \end{macrocode} -% The next macro computes the magnitude and the direction of the difference of -% two complex numbers; the first input argument is the minuend, the second is -% the subtrahend; the output quantities are the third argument containing the -% magnitude of the difference and the fourth is the direction of the difference. -% The service macro |\SubVect| executes the difference of two complex numbers -% and is described further on. -% \begin{macrocode} \def\DistanceAndDirOfVect#1minus#2to#3and#4{% -\SubVect#2from#1to\@tempa +\SubVect#2from#1to\@tempa \ModAndDirOfVect\@tempa to#3and#4\ignorespaces}% -% \end{macrocode} -% We now have two macros intended to fetch just the real or, respectively, the -% imaginary part of the input complex number. -% \begin{macrocode} \def\XpartOfVect#1to#2{% \GetCoord(#1)#2\@tempa\ignorespaces}% -% \def\YpartOfVect#1to#2{% \GetCoord(#1)\@tempa#2\ignorespaces}% -% \end{macrocode} -% With the next macro we create a direction vector (second argument) from a -% given angle (first argument). -% \begin{macrocode} \def\DirFromAngle#1to#2{% \CosOf#1to\t@X \SinOf#1to\t@Y \MakeVectorFrom\t@X\t@Y to#2\ignorespaces}% -% \end{macrocode} -% -% 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 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 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 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. -% -% \begin{macrocode} \def\ArgOfVect#1to#2{\bgroup\GetCoord(#1){\t@X}{\t@Y}% \def\s@gno{}\def\addflatt@ngle{0} \ifdim\t@X\p@=\z@ @@ -2212,79 +4177,39 @@ README.txt and manifest.txt. \fi \fi \edef\ArcTan{\unless\ifx\s@gno\empty\s@gno\fi\ArcTan}% -\unless\ifnum\addflatt@ngle=0\relax +\unless\ifnum\addflatt@ngle=0\relax \edef\ArcTan{% \strip@pt\dimexpr\ArcTan\p@\ifx\s@gno\empty-\else+\fi \addflatt@ngle\p@\relax}% \fi \edef\x{\noexpand\egroup\noexpand\edef\noexpand#2{\ArcTan}}% \x\ignorespaces} -% \end{macrocode} -% -% It is worth noting that the absolute average error in these computations is -% much lower than 0.0001°; pretty satisfactory since the typesetting engines work -% in fixed radix notation with 16 fractional binary digits, and an error on -% the fourth or fifth fractional decimal digit is almost the best it can be -% expected from this kind of arithmetics. -% -% Sometimes it is necessary to scale a vector by an arbitrary real factor; this -% implies scaling both the real and imaginary part of the input given vector. -% \begin{macrocode} \def\ScaleVect#1by#2to#3{\GetCoord(#1)\t@X\t@Y \@tempdima=\t@X\p@ \@tempdima=#2\@tempdima\Numero\t@X\@tempdima \@tempdima=\t@Y\p@ \@tempdima=#2\@tempdima\Numero\t@Y\@tempdima \MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% -% \end{macrocode} -% Again, sometimes it is necessary to reverse the direction of rotation; this -% implies changing the sign of the imaginary part of a given complex number; -% this operation produces the complex conjugate of the given number. -% \begin{macrocode} \def\ConjVect#1to#2{\GetCoord(#1)\t@X\t@Y \@tempdima=-\t@Y\p@\Numero\t@Y\@tempdima \MakeVectorFrom\t@X\t@Y to#2\ignorespaces}% -% \end{macrocode} -% -% With all the low level elementary operations we can now proceed to the -% definitions of the binary operations on complex numbers. We start with the -% addition: -% \begin{macrocode} \def\AddVect#1and#2to#3{\GetCoord(#1)\tu@X\tu@Y -\GetCoord(#2)\td@X\td@Y -\@tempdima\tu@X\p@\advance\@tempdima\td@X\p@ \Numero\t@X\@tempdima +\GetCoord(#2)\td@X\td@Y +\@tempdima\tu@X\p@\advance\@tempdima\td@X\p@ \Numero\t@X\@tempdima \@tempdima\tu@Y\p@\advance\@tempdima\td@Y\p@ \Numero\t@Y\@tempdima \MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% -% \end{macrocode} -% Then the subtraction: -% \begin{macrocode} \def\SubVect#1from#2to#3{\GetCoord(#1)\tu@X\tu@Y -\GetCoord(#2)\td@X\td@Y -\@tempdima\td@X\p@\advance\@tempdima-\tu@X\p@ \Numero\t@X\@tempdima +\GetCoord(#2)\td@X\td@Y +\@tempdima\td@X\p@\advance\@tempdima-\tu@X\p@ \Numero\t@X\@tempdima \@tempdima\td@Y\p@\advance\@tempdima-\tu@Y\p@ \Numero\t@Y\@tempdima \MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% -% \end{macrocode} -% -% For the multiplication we need to split the operation according to the fact -% that we want to multiply by the second operand or by the complex conjugate of -% the second operand; it would be nice if we could use the usual -% postfixed asterisk notation for the complex conjugate, but I could not find -% a simple means for doing so; therefore I use the prefixed notation, that is -% I put the asterisk before the second operand. The first part of the -% multiplication macro just takes care of the multiplicand and then checks for -% the asterisk; if there is no asterisk it calls a second service macro that -% performs a regular complex multiplication, otherwise it calls a third -% service macro that executes the conjugate multiplication. -% \begin{macrocode} \def\MultVect#1by{\@ifstar{\@ConjMultVect#1by}{\@MultVect#1by}}% -% \def\@MultVect#1by#2to#3{\GetCoord(#1)\tu@X\tu@Y -\GetCoord(#2)\td@X\td@Y +\GetCoord(#2)\td@X\td@Y \@tempdima\tu@X\p@ \@tempdimb\tu@Y\p@ \@tempdimc=\td@X\@tempdima\advance\@tempdimc-\td@Y\@tempdimb \Numero\t@X\@tempdimc \@tempdimc=\td@Y\@tempdima\advance\@tempdimc\td@X\@tempdimb \Numero\t@Y\@tempdimc \MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% -% \def\@ConjMultVect#1by#2to#3{\GetCoord(#1)\tu@X\tu@Y \GetCoord(#2)\td@X\td@Y \@tempdima\tu@X\p@ \@tempdimb\tu@Y\p@ \@tempdimc=\td@X\@tempdima\advance\@tempdimc+\td@Y\@tempdimb @@ -2292,52 +4217,22 @@ README.txt and manifest.txt. \@tempdimc=\td@X\@tempdimb\advance\@tempdimc-\td@Y\@tempdima \Numero\t@Y\@tempdimc \MakeVectorFrom\t@X\t@Y to#3\ignorespaces} -% \end{macrocode} -% -% The division of two complex numbers implies scaling down the dividend by the -% magnitude of the divisor and by rotating the dividend scaled vector by the -% opposite direction of the divisor; therefore: -% \begin{macrocode} \def\DivVect#1by#2to#3{\ModAndDirOfVect#2to\@Mod and\@Dir \DividE\p@ by\@Mod\p@ to\@Mod \ConjVect\@Dir to\@Dir \ScaleVect#1by\@Mod to\@tempa \MultVect\@tempa by\@Dir to#3\ignorespaces}% -% \end{macrocode} -% -% \subsection{Arcs and curved vectors} -% We are now in the position of really doing graphic work. -% \subsubsection{Arcs} -% We start with tracing -% a circular arc of arbitrary center, arbitrary starting point and arbitrary -% aperture; the first macro checks the aperture; if this is not zero it -% actually proceeds with the necessary computations, otherwise it does -% nothing. -% \begin{macrocode} \def\Arc(#1)(#2)#3{\begingroup -\@tdA=#3\p@ +\@tdA=#3\p@ \unless\ifdim\@tdA=\z@ \@Arc(#1)(#2)% \fi \endgroup\ignorespaces}% -% \end{macrocode} -% The aperture is already memorized in |\@tdA|; the |\@Arc| macro receives -% the center coordinates in the first argument and the coordinates of the -% starting point in the second argument. -% \begin{macrocode} \def\@Arc(#1)(#2){% \ifdim\@tdA>\z@ \let\Segno+% \else \@tdA=-\@tdA \let\Segno-% \fi -% \end{macrocode} -% The rotation angle sign is memorized in |\Segno| and |\@tdA| now contains the -% absolute value of the arc aperture. -% If the rotation angle is larger than $360^\circ$ a message is issued that -% informs the user that the angle will be reduced modulo $360^\circ$; this -% operation is performed by successive subtractions rather than with modular -% arithmetics on the assumption that in general one subtraction suffices. -% \begin{macrocode} \Numero\@gradi\@tdA \ifdim\@tdA>360\p@ \PackageWarning{curve2e}{The arc aperture is \@gradi\space degrees @@ -2345,32 +4240,12 @@ README.txt and manifest.txt. to the range 0--360 taking the sign into consideration}% \@whiledim\@tdA>360\p@\do{\advance\@tdA-360\p@}% \fi -% \end{macrocode} -% Now the radius is determined and the drawing point is moved to the stating -% point. -% \begin{macrocode} \SubVect#2from#1to\@V \ModOfVect\@V to\@Raggio \CopyVect#2to\@pPun \CopyVect#1to\@Cent \GetCoord(\@pPun)\@pPunX\@pPunY -% \end{macrocode} -% From now on it's better to define a new macro that will be used also in the -% subsequent macros that draw arcs; here we already have the starting point -% coordinates and the angle to draw the arc, therefore we just call the new -% macro, stroke the line and exit. -% \begin{macrocode} \@@Arc \strokepath\ignorespaces}% -% \end{macrocode} -% And the new macro |\@@Arc| starts with moving the drawing point to the first -% point and does everything needed for drawing the requested arc, except -% stroking it; I leave the \texttt{stroke} command to the completion of the -% calling macro and nobody forbids to use the |\@@Arc| macro for other purposes. -% \begin{macrocode} \def\@@Arc{% \pIIe@moveto{\@pPunX\unitlength}{\@pPunY\unitlength}% -% \end{macrocode} -% If the aperture is larger than $180^\circ$ it traces a semicircle in the -% right direction and correspondingly reduces the overall aperture. -% \begin{macrocode} \ifdim\@tdA>180\p@ \advance\@tdA-180\p@ \Numero\@gradi\@tdA @@ -2387,68 +4262,6 @@ README.txt and manifest.txt. {\@sPunX\unitlength}{\@sPunY\unitlength}% \CopyVect\@sPun to\@pPun \fi -% \end{macrocode} -% If the remaining aperture is not zero it continues tracing the rest of the arc. -% 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. -% -%\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 -%= \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 \SubVect\@Cent from\@pPun to\@V @@ -2482,66 +4295,17 @@ README.txt and manifest.txt. {\@scPunX\unitlength}{\@scPunY\unitlength}% {\@sPunX\unitlength}{\@sPunY\unitlength}% \fi} -% \end{macrocode} -% -% \subsubsection{Arc vectors} -% We exploit much of the above definitions for the |\Arc| macro for drawing -% circular arcs with an arrow at one or both ends; the first macro -% |\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 specific option to the -% \texttt{pict2e} package. -% -% 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. -% -% All these operations require a lot of ``playing'' with vector directions, -% but even if the operations are numerous, they do not do anything else but: -% (a) determining the end point and its direction; (b) determining the arrow -% 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) -% 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 -% other end of the arc; (g) shortening the total arc angular amplitude by the -% 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. -% -% The calling macros are very similar to the |\Arc| macro initial one: -% \begin{macrocode} \def\VectorArc(#1)(#2)#3{\begingroup \@tdA=#3\p@ \ifdim\@tdA=\z@\else \@VArc(#1)(#2)% \fi \endgroup\ignorespaces}% -% \def\VectorARC(#1)(#2)#3{\begingroup \@tdA=#3\p@ \ifdim\@tdA=\z@\else \@VARC(#1)(#2)% \fi \endgroup\ignorespaces}% -% \end{macrocode} -% -% The single arrowed arc is defined with the following long macro where all the -% described operations are performed more or less in the described succession; -% probably the macro requires a little cleaning, but since it works fine I did -% not try to optimize it for time or number of tokens. The final part of the -% macro is almost identical to that of the plain arc; the beginning also is -% quite similar. The central part is dedicated to the positioning of the arrow -% tip and to the necessary calculations for determining the tip tilt and the -% reduction of the total arc length; pay attention that the arrow length, stored -% in |\@tdE| is a real length, while the radius stored in |\@Raggio| is just -% a multiple of the |\unitlength|, so that the division (that yields a good -% angular approximation to the arrow length as seen from the center of the arc) -% must be done with real lengths. The already defined |\@@Arc| macro actually -% draws the curved vector stem without stroking it. -% \begin{macrocode} \def\@VArc(#1)(#2){% \ifdim\@tdA>\z@ \let\Segno+% @@ -2578,12 +4342,6 @@ README.txt and manifest.txt. \CopyVect#1to\@Cent \GetCoord(\@pPun)\@pPunX\@pPunY \@@Arc \strokepath\ignorespaces}% -% \end{macrocode} -% -% The macro for the arc terminated with arrow tips at both ends is again very -% similar, except it is necessary to repeat the arrow tip positioning also at -% the starting point. The |\@@Arc| macro draws the curved stem. -% \begin{macrocode} \def\@VARC(#1)(#2){% \ifdim\@tdA>\z@ \let\Segno+% @@ -2634,170 +4392,9 @@ README.txt and manifest.txt. \GetCoord(\@pPun)\@pPunX\@pPunY \@@Arc \strokepath\ignorespaces}% -% \end{macrocode} -% -% It must be understood that the curved vectors, the above circular arcs -% terminated with an arrow tip at one or both ends, have a nice appearance only -% if the arc radius is not too small, or, said in a different way, if the arrow -% tip angular width does not exceed a maximum of a dozen degrees (and this is -% probably already too much); the tip does not get curved as the arc is, -% therefore there is not a smooth transition from the curved stem and the -% straight arrow tip if this one is large in comparison to the arc radius. -% -% \subsection{General curves} -% The most used method to draw curved lines with computer programs is to -% connect several simple curved lines, general ``arcs'', one to another -% generally maintaining the same tangent at the junction. I the direction -% changes we are dealing with a cusp. -% -% The simple general arcs that are directly implemented in every program that -% display typeset documents, are those drawn with the parametri curves called -% \emph{Béźier splines}; given a sequence of points in the $x,y$ plane, say -% $P_0, P_1, P_2, p_3, \dots$ (represented as coordinate pairs, i.e. by complex -% numbers), the most common Bézier splines are the following ones: -% \begin{align} -% \mathcal{B}_1 &= P_0(1-t) + P_1t \label{equ:B-1} \\ -% \mathcal{B}_2 &= P_0(1-t)^2 + P_1 2(1-t)t + P_2t^2 \label{equ:B-2} \\ -% \mathcal{B}_3 &= P_0(1-t)^3 + P_1 3(1-t)^2t +P_2 3(1-t)t^2 +P_3t^3 -% \label{equ:B-3} -% \end{align} -% -% All these splines depend on parameter $t$; they have the property that for -% $t=0$ each line starts at the first point, while for $t=1$ they reach the -% last point; in each case the generic point $P$ on each curve takes off -% with a direction that points to the next point, while it reaches the -% destination point with a direction coming from the penultimate point; -% moreover, when $t$ varies from 0 to 1, the curve arc is completely -% contained within the convex hull formed by the polygon that has the -% spline points as vertices. Last but not least first order splines implement -% just straight lines and they are out of question for what concerns maxima, -% minima, inflection points and the like. Quadratic splines draw just -% parabolas, therefore they draw arcs that have the concavity just on one -% side of the path; therefore no inflection points. Cubic splines are -% extremely versatile and can draw lines with maxima, minima and inflection -% points. Virtually a multi-arc curve may be drawn by a set of cubic splines -% as well as a set of quadratic splines (fonts are a good example: Adobe -% Type~1 fonts have their contours described by cubic splines, while TrueType -% fonts have their contours described with quadratic splines; with a naked -% eye it is impossible to notice the difference). -% -% Each program that processes the file to be displayed is capable of drawing -% first order Bézier splines (segments) and third order Bézier splines, for -% no other reason, at least, because they have to draw vector fonts whose -% contours are described by Bézier splines; sometimes they have also the -% program commands to draw second order Bézier splines, but not always these -% machine code routines are available to the user for general use. For what -% concerns |pdftex|, |xetex| and |luatex|, they have the user commands for -% straight lines and cubic arcs. At least with |pdftex|, quadratic arcs must -% be simulated with a clever use of third order Bézier splines. -% -% Notice that \LaTeXe\ environment |picture| by itself is capable of drawing -% both cubic and quadratic Bézier splines as single arcs; but it resorts to -% ``poor man'' solutions. The |pict2e| package removes all the old limitations -% and implements the interface macros for sending the driver the -% necessary drawing information, including the transformation from -% typographical points (72.27\,pt/inch) to PostScript big points (72\,bp/inch). -% But for what concerns the quadratic spline it resorts to the clever use of a -% cubic spline. -% -% Therefore here we treat first the drawings that can be made with cubic -% splines; then we describe the approach to quadratic splines. -% -%\subsection{Cubic splines} -% Now we define a macro for tracing a general, not necessarily circular, arc. -% This macro resorts to a general triplet of macros with which it is possible -% to draw almost anything. It traces a single Bézier spline from a first point -% where the tangent direction is specified to a second point where again it is -% specified the tangent direction. Actually this is a special (possibly useless) -% case where the general |\curve| macro of |pict2e| could do the same or a -% better job. In any case\dots -% \begin{macrocode} \def\CurveBetween#1and#2WithDirs#3and#4{% \StartCurveAt#1WithDir{#3}\relax \CurveTo#2WithDir{#4}\CurveFinish\ignorespaces}% -% \end{macrocode} -% -% 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 may give raise to some little problems when they -% are very close to 90° in absolute value. Some control is exercised on these -% values, but some tests might fail if the angle derives from computations; -% this is a good place to use polar forms for the direction vectors. -% -%\begin{figure}\centering\unitlength=0.004\textwidth -%\begin{picture}(220,120)(-50,-20) -%\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 -% drawing but also memorizes the starting direction; the second macro traces -% the current Bézier arc reaching the destination point with the specified -% direction, but memorizes this direction as the one with which to start the -% next arc. The overall curve is then always smooth because the various -% Bézier arcs join with continuous tangents. If a cusp is desired it is -% necessary to change the memorized direction at the end of the arc before the -% cusp and before the start of the next arc; this is better than stroking the -% curve before the cusp and then starting another curve, because the curve -% joining point at the cusp is not stroked with the same command, therefore we get -% two superimposed curve terminations. We therefore need another small macro -% |\ChangeDir| to perform this task. -% -% It is necessary to recall that the directions point to the control points, -% but they do not define the control points themselves; they are just -% directions, or, even better, they are simply vectors with the desired -% direction; the macros themselves provide to the normalization and -% memorization. -% -% The next desirable point would be to design a macro that accepts optional node -% directions and computes the missing ones according to a suitable strategy. I -% can think of many such strategies, but none seems to be generally applicable, -% in the sense that one strategy might give good results, say, with sinusoids -% and another one, say, with cardioids, but neither one is suitable for both -% cases. -% -% For the moment we refrain from automatic direction computation, but we design -% the general macro as if directions were optional. -% -% Here we begin with the first initializing macro that receives in the first -% argument the starting point and in the second argument the direction of the -% tangent (not necessarily normalized to a unit vector) -% \begin{macrocode} \def\StartCurveAt#1WithDir#2{% \begingroup \GetCoord(#1)\@tempa\@tempb @@ -2807,67 +4404,14 @@ README.txt and manifest.txt. \CopyVect\@tempa,\@tempb to\@Dzero \DirOfVect\@Dzero to\@Dzero \ignorespaces} -% \end{macrocode} -% And this re-initializes the direction to create a cusp: -% \begin{macrocode} \def\ChangeDir<#1>{% \GetCoord(#1)\@tempa\@tempb \CopyVect\@tempa,\@tempb to\@Dzero \DirOfVect\@Dzero to\@Dzero \ignorespaces} -% \end{macrocode} -% -% 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\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}|AndDists|\meta{$K_0$}|And|\meta{$K_1$} -%\end{flushleft} -% where \meta{end point} is a vector macro or a comma separated pair of values; -% again \meta{direction} is another vector macro or a comma separated pair of -% values, that not necessarily indicate a unit vector, since the macro provides -% to normalise it to unity; \meta{$K_0$} and\meta{$K_1$} are the distances of -% the control point from their respective node points; they must be positive -% integers or fractional numbers. If \meta{$K_1$} is a number must be enclosed -% in curly braces, while if it is a macro name (containing the desired fractional -% or integer value) there is no need for braces. -% -% This macro uses the input information to use the internal |pict2e| macro -% |\pIIe@curveto| with the proper arguments, and to save the final direction -% 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 @@ -2883,188 +4427,24 @@ README.txt and manifest.txt. \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\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 five red curves drawn with |\CbezierBetween|; the -% five red curves differ only for the distance of their control point $C_0$ -% from the starting point; the differences are remarkable and the topmost -% curve even presents a slight inflection close to the end point. These -% effects cannot be obtained with the ``smarter'' macro |\CurveBetween|. But -% certainly this simpler macro is more difficult to use because the -% distances of the control point are difficult to estimate 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 ``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 -% to determine the distances from the adjacent curve nodes. This must work -% correctly even if nodes and directions imply an inflection point somewhere -% along the arc. -% -% The strategy I devised consists in determining each control point as if it -% were the control point of a circular arc, precisely an arc of an osculating -% circle, i.e. a circle tangent to the curve at that node. The ambiguity -% of the stated problem may be solved by establishing that the chord of the -% osculating circle has the same direction as the chord of the arc being drawn, -% and that the curve chord is divided into two equal parts each of which should be -% interpreted as half the chord of the osculating circle. -% This makes the algorithm a little rigid; sometimes the path drawn is very -% pleasant, while in other circumstances the determined curvatures are too -% large or too small. We therefore add some optional information that lets -% us have some control over the curvatures; the idea is based on the concept -% of \emph{tension}, similar but not identical to the one used in the drawing -% programs \MF\ and \MP. We add to the direction information, with which the -% control nodes of the osculating circle arcs are determined, a scaling factor -% that should be intuitively related to the tension of the arc: the smaller -% this number, the closer the arc resembles a straight line as a rope subjected -% to a high tension; value zero is allowed, while a value of 4 is close to -% ``infinity'' and turns a quarter circle into a line with an unusual loop; -% a value of 2 turns a quarter circle almost into a polygonal line -% with rounded corner. Therefore these tension factors should -% be used only for fine tuning the arcs, not as the first time a path is drawn. -% -% We devised a syntax for specifying direction and tensions: -%\begin{flushleft} -% \meta{direction\texttt{\upshape;}tension factors} -%\end{flushleft} -% where \emph{direction} contains a pair of fractional number that not -% necessarily refer to the components of a unit vector direction, but simply -% to a vector with the desired orientation; the information contained from -% the semicolon (included) to the rest of the specification is optional; if -% it is present, the \emph{tension factors} is simply a comma separated pair -% of fractional or integer numbers that represent respectively the tension -% at the starting or the ending node of a path arc. -% -% We therefor need a macro to extract the mandatory and optional parts: -% \begin{macrocode} \def\@isTension#1;#2!!{\def\@tempA{#1}% \def\@tempB{#2}\unless\ifx\@tempB\empty\strip@semicolon#2\fi} \def\strip@semicolon#1;{\def\@tempB{#1}} -% \end{macrocode} -% By changing the tension values we can achieve different results: see -% figure~\ref{fig:tensions}. -%\begin{figure}[!htb]\centering -%\begin{minipage}{0.48\textwidth}\small -%\begin{verbatim} -%\raggedleft\unitlength=0.01\textwidth -%\begin{picture}(70,70) -%\put(0,0){\color{blue}\frame(70,70){}} -%\put(0,0){\color{red}\Curve(0,0)<1,1>(70,0)<1,-1>} -%\Curve(0,0)<1,1>(70,0)<1,-1;0,0> -%\Curve(0,0)<1,1>(70,0)<1,-1;0.2,0.2> -%\Curve(0,0)<1,1>(70,0)<1,-1;2,2> -%\Curve(0,0)<1,1>(70,0)<1,-1;4.5,4.5> -%\Curve(0,0)<1,1>(70,0)<1,-1;0,3> -%\Curve(0,0)<1,1>(70,0)<1,-1;3,0> -%\end{picture} -%\end{verbatim} -%\end{minipage} -%\hfill -%\begin{minipage}{0.46\textwidth} -%\raggedleft\unitlength=0.01\textwidth -%\begin{picture}(70,70) -%\put(0,0){\color{blue}\framebox(70,70){}} -%\put(0,0){\color{red}\Curve(0,0)<1,1>(70,0)<1,-1>} -%\Curve(0,0)<1,1>(70,0)<1,-1;0,0> -%\Curve(0,0)<1,1>(70,0)<1,-1;0.2,0.2> -%\Curve(0,0)<1,1>(70,0)<1,-1;2,2> -%\Curve(0,0)<1,1>(70,0)<1,-1;4.5,4.5> -%\Curve(0,0)<1,1>(70,0)<1,-1;0,3> -%\Curve(0,0)<1,1>(70,0)<1,-1;3,0> -%\end{picture} -%\end{minipage} -%\caption{The effects of tension factors}\label{fig:tensions} -%\end{figure} -% -% -% We use the formula we got for arcs~\eqref{equ:corda}, where the half chord is -% indicated with $s$, and we derive the necessary distances: -%\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: -% \begin{macrocode} \def\CurveTo#1WithDir#2{% \def\@Tuno{1}\def\@Tzero{1}\relax \edef\@Puno{#1}\@isTension#2;!!% \expandafter\DirOfVect\@tempA to\@Duno \bgroup\unless\ifx\@tempB\empty\GetCoord(\@tempB)\@Tzero\@Tuno\fi -\DistanceAndDirOfVect\@Puno minus\@Pzero to\@Chord and\@DirChord -% \end{macrocode} -% Then we rotate everything about the starting point so as to bring the chord on -% the real axis -% \begin{macrocode} +\DistanceAndDirOfVect\@Puno minus\@Pzero to\@Chord and\@DirChord \MultVect\@Dzero by*\@DirChord to \@Dpzero \MultVect\@Duno by*\@DirChord to \@Dpuno \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 memorised in |\@Chord| and -% its half is saved in |\@semichord|. -% -% We now examine the various degenerate cases, when either tangent is -% 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. -% -% \begin{macrocode} \ifdim\@DXpzero\p@=\z@ \@tdA=1.333333\p@ \Numero\@KCzero{\@semichord\@tdA}% @@ -3073,11 +4453,6 @@ README.txt and manifest.txt. \@tdA=1.333333\p@ \Numero\@Kpzero{\@semichord\@tdA}% \fi -% \end{macrocode} -% 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}% @@ -3091,14 +4466,6 @@ README.txt and manifest.txt. \MultiplyFN\@KCzero by \@Tzero to \@KCzero \ScaleVect\@Dzero by\@KCzero to\@CPzero \AddVect\@Pzero and\@CPzero to\@CPzero -% \end{macrocode} -% 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} \ifdim\@DXpuno\p@=\z@ \@tdA=-1.333333\p@ \Numero\@KCuno{\@semichord\@tdA}% @@ -3120,47 +4487,15 @@ README.txt and manifest.txt. \MultiplyFN\@KCuno by \@Tuno to \@KCuno \ScaleVect\@Duno by\@KCuno to\@CPuno \AddVect\@Puno and\@CPuno to\@CPuno -% \end{macrocode} -% Now we have the four points and we can instruct the internal \texttt{pict2e} -% macros to do the path drawing. -% \begin{macrocode} \GetCoord(\@Puno)\@XPuno\@YPuno \GetCoord(\@CPzero)\@XCPzero\@YCPzero \GetCoord(\@CPuno)\@XCPuno\@YCPuno \pIIe@curveto{\@XCPzero\unitlength}{\@YCPzero\unitlength}% {\@XCPuno\unitlength}{\@YCPuno\unitlength}% {\@XPuno\unitlength}{\@YPuno\unitlength}\egroup -% \end{macrocode} -% It does not have to stroke the curve because other Bézier splines might still -% be added to the path. On the opposite it memorises the final point as the -% initial point of the next spline -% \begin{macrocode} \CopyVect\@Puno to\@Pzero \CopyVect\@Duno to\@Dzero \ignorespaces}% -% \end{macrocode} -% -% -% 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 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 -% 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 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>{% @@ -3174,70 +4509,6 @@ README.txt and manifest.txt. \@ifnextchar\lp@r\@Curve{% \@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| 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,0)[br]{x}\Zbox(0,26)[tl]{y} -%\Curve(0,0)<77:1>(10,20)<1,0;2,0.4>(30,-20)<1,0;0.4,0.4>(40,0)<77:1;0.4,2> -%} -%\put(55,0){\VECTOR(0,0)(45,0)\VECTOR(0,-25)(0,25) -%\Zbox(45,0)[br]{x}\Zbox(0,26)[tl]{y} -%\CbezierBetween0,0And20,0WithDirs77:1And-77:1UsingDists28And{28} -%\CbezierBetween20,0And40,0WithDirs-77:1And77:1UsingDists28And{28}} -%\end{picture} -%\caption{A sequence of arcs; the left figure has been drawn with the -% \cs{Curve} command with a sequence of four couples of point-direction -% arguments; the right figure has been drawn with two commands -% \cs{CbezierBetween} that include also the specification of the control -% points} -%\label{fig:sinewave} -%\end{figure} -% -% As it can be seen in figure~\ref{fig:sinewave} the two diagrams should -% 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 two times as many pieces of -% information in order to minimise the effects of the lack of control on the -% control points, and even with this added information the macro approaches -% the sine wave with less accuracy. At the same time for many applications -% the |\Curve| recursive macro proves to be much easier to use than with -% single arcs drawn with the |\CbezierBetween| macro. -% -% \subsection{Quadratic splines} -% We want to create a recursive macro with the same properties as the above -% described |\Curve| macro, but that uses quadratic splines; we call it -% |\Qurve| so that the initial macro name letter reminds us of the nature -% of the splines being used. For the rest they have an almost identical -% syntax; with quadratic spline it is not possible to specify the distance -% of the control points from the extrema, since quadratic spline have just -% one control point that must lay at the intersection of the two tangent -% directions therefore with quadratic splines the tangents at each point -% cannot have the optional part that starts with a semicolon. The syntax, therefore, is just: -%\begin{flushleft} -%\cs{Qurve}\parg{first point}\aarg{direction}...\parg{any point}\aarg{direction}...\parg{last point}\aarg{direction} -%\end{flushleft} -% As with |\Curve|, also with |\Qurve| there is no limitation on the number -% of points, except for the computer memory size; it is advisable not to use -% many arcs otherwise it might become very difficult to find errors. -% -% The first macros that set up the recursion are very similar to those we -% wrote for |\Curve|: -% \begin{macrocode} \def\Qurve{\@ifstar{\let\fillstroke\fillpath\Qurve@}% {\let\fillstroke\strokepath\Qurve@}} @@ -3245,63 +4516,30 @@ README.txt and manifest.txt. \StartCurveAt#1WithDir{#2}% \@ifnextchar\lp@r\@Qurve{% \PackageWarning{curve2e}{% - Quadratic curve specifications must contain at least + Quadratic curve specifications must contain at least two nodes!\Messagebreak Please, control your Qurve specifications\MessageBreak}}}% \def\@Qurve(#1)<#2>{\QurveTo#1WithDir{#2}% \@ifnextchar\lp@r\@Qurve{% \@ifnextchar[\@ChangeQDir\CurveEnd}}% \def\@ChangeQDir[#1]{\ChangeDir<#1>\@Qurve}% -% \end{macrocode} -% Notice that in case of long paths it might be better to use the single -% macros |\StartCurveAt|, |\QurveTo|, |\ChangeDir| and |\CurveFinish| -% (or |\FillCurve|), with their respective syntax, in such a way that a long list -% of node-direction specifications passed to |\Qurve| may be split into -% shorter input lines in order to edit the input data in a more comfortable way. -% -% -% The macro that does everything is |\QurveTo|. it start with reading its -% arguments received through the calling macro |\@Qurve| -% \begin{macrocode} \def\QurveTo#1WithDir#2{% \edef\@Puno{#1}\DirOfVect#2to\@Duno\bgroup \DistanceAndDirOfVect\@Puno minus\@Pzero to\@Chord and\@DirChord -% \end{macrocode} -% It verifies if |\@Dpzero| and |\@Dpuno|, the directions at the two extrema -% of the arc, are parallel or anti-parallel by taking their -% ``scalar'' product (|\@Dpzero| times |\@Dpuno*|); if the imaginary -% component of the scalar product vanishes the two directions are parallel; -% in this case we produce an error message, but we continue skipping this arc -% destination point; evidently the drawing will not be the desired one, but -% the job should not abort. -% \begin{macrocode} \MultVect\@Dzero by*\@Duno to \@Scalar \YpartOfVect\@Scalar to \@YScalar \ifdim\@YScalar\p@=\z@ \PackageWarning{curve2e}% {Quadratic Bezier arcs cannot have their starting\MessageBreak and ending directions parallel or antiparallel with\MessageBreak - each other. This arc is skipped and replaced with + each other. This arc is skipped and replaced with a dotted line.\MessageBreak}% \Dotline(\@Pzero)(\@Puno){2}\relax \else -% \end{macrocode} -% Otherwise we rotate everything about the starting point so as to bring the -% chord on the real axis; we get also the components of the two directions that, -% we should remember, are unit vectors, not generic vectors, although the user -% can use the vector specifications that are more understandable to him/her: -% \begin{macrocode} \MultVect\@Dzero by*\@DirChord to \@Dpzero \MultVect\@Duno by*\@DirChord to \@Dpuno \GetCoord(\@Dpzero)\@DXpzero\@DYpzero \GetCoord(\@Dpuno)\@DXpuno\@DYpuno -% \end{macrocode} -% We check if the two directions point to the same half plane; this implies -% that these rotated directions point to different sides of the chord vector; -% all this is equivalent that the two direction Y components have opposite -% signs, and therefore their product is strictly negative, and that the two -% X components product is not negative. -% \begin{macrocode} \MultiplyFN\@DXpzero by\@DXpuno to\@XXD \MultiplyFN\@DYpzero by\@DYpuno to\@YYD \unless\ifdim\@YYD\p@<\z@\ifdim\@XXD\p@<\z@ @@ -3312,86 +4550,23 @@ README.txt and manifest.txt. This arc is skipped and replaced by a dotted line\MessageBreak}% \Dotline(\@Pzero)(\@Puno){2}\fi \else -% \end{macrocode} -% -% After these tests we should be in a ``normal'' situation.We first copy -% the expanded input information into new macros that have more explicit -% names: macros stating wit `S' denote the sine of the direction angle, -% while those starting with `C' denote the cosine of that angle. We will -% use these expanded definitions as we know we are working with the actual -% values. These directions are those relative to the arc chord. -% \begin{macrocode} \edef\@CDzero{\@DXpzero}\relax \edef\@SDzero{\@DYpzero}\relax \edef\@CDuno{\@DXpuno}\relax \edef\@SDuno{\@DYpuno}\relax -% \end{macrocode} -% Suppose we write the parametric equations of a straight line that departs -% from the beginning of the chord with direction angle $\phi_0$ and the -% corresponding equation of the straight line departing from the end of the -% chord (of length $c$) with direction angle $\phi_1$. We have to find the -% coordinates of the intersection point of these two straight lines. -%\begin{subequations} -%\begin{align} -% t \cos\phi_0 - s \cos\phi_1 &= c\\ -% t \sin\phi_0 - s \sin\phi_1 &= 0 -%\end{align} -%\end{subequations} -% The parameters $t$ and $s$ are just the running parameters; we have -% to solve those simultaneous equations in the unknown variables $t$ and $s$; -% these values let us comupte the coordinates of the intersection point: -%\begin{subequations}\begin{align} -% X_C &=\dfrac{c\cos\phi_0\sin\phi_1}{\sin\phi_0\cos\phi_1 - \cos\phi_0\sin\phi_1} \\ -% Y_C &=\dfrac{c\sin\phi_0\sin\phi_1}{\sin\phi_0\cos\phi_1 - \cos\phi_0\sin\phi_1} -%\end{align}\end{subequations} -% -% Having performed the previous tests we are sure that the denominator is not -% vanishing (direction are not parallel or anti-parallel) and that it lays at -% the same side as the direction with angle $\phi_0$ with respect to the chord. -% The coding then goes on like this: -% \begin{macrocode} -\MultiplyFN\@SDzero by\@CDuno to\@tempA -\MultiplyFN\@SDuno by\@CDzero to\@tempB +\MultiplyFN\@SDzero by\@CDuno to\@tempA +\MultiplyFN\@SDuno by\@CDzero to\@tempB \edef\@tempA{\strip@pt\dimexpr\@tempA\p@-\@tempB\p@}\relax \@tdA=\@SDuno\p@ \@tdB=\@Chord\p@ \@tdC=\@tempA\p@ \edef\@tempC{\strip@pt\dimexpr \@tdA*\@tdB/\@tdC}\relax -\MultiplyFN\@tempC by\@CDzero to \@XC -\MultiplyFN\@tempC by\@SDzero to \@YC -\ModOfVect\@XC,\@YC to\@KC -% \end{macrocode} -% We eventually computed the coordinates and the module of the intersection -% point vector taking into account the rotation of the real axis; getting -% back to the original coordinates before rotation we get: -% \begin{macrocode} -\ScaleVect\@Dzero by\@KC to\@CP -\AddVect\@Pzero and\@CP to\@CP -\GetCoord(\@Pzero)\@XPzero\@YPzero -\GetCoord(\@Puno)\@XPuno\@YPuno -\GetCoord(\@CP)\@XCP\@YCP -% \end{macrocode} -% We have now the coordinates of the two extrema point of the quadratic arc -% and of the control point. Keeping in mind that the symbols $P_0$, $P_1$ -% and $C$ denote geometrical points but also their coordinates as ordered -% pairs of real numbers (i.e. they are complex numbers) we have to determine -% the smart cubic arc nodes and control points; we should determine the -% values of $P_a$ and $P_b$ such that -%\[ -% P_0(1-t)^3 +3P_a(1-t)^2t +3P_b(1-t)t^2 +P_1t^3 -%\] -% is equivalent to -%\[ -% P_0(1-t)^2 + 2C(1-t)t + P_1t^2 -%\] -% It turns out that the solution is given by -%\begin{equation} -%P_a= C+(P_0-C)/3 \qquad \text{and}\qquad P_b = C+(P_1- C)/3 -%\label{equ:spline3} -%\end{equation} -% -% The transformations implied by equations~\eqref{equ:spline3} are performed -% by the following macros already available from the |pict2e| package; we -% use them here with the actual arguments used for this task: -% \begin{macrocode} +\MultiplyFN\@tempC by\@CDzero to \@XC +\MultiplyFN\@tempC by\@SDzero to \@YC +\ModOfVect\@XC,\@YC to\@KC +\ScaleVect\@Dzero by\@KC to\@CP +\AddVect\@Pzero and\@CP to\@CP +\GetCoord(\@Pzero)\@XPzero\@YPzero +\GetCoord(\@Puno)\@XPuno\@YPuno +\GetCoord(\@CP)\@XCP\@YCP \@ovxx=\@XPzero\unitlength \@ovyy=\@YPzero\unitlength \@ovdx=\@XCP\unitlength \@ovdy=\@YCP\unitlength \@xdim=\@XPuno\unitlength \@ydim=\@YPuno\unitlength @@ -3400,189 +4575,17 @@ README.txt and manifest.txt. \pIIe@bezier@QtoC\@xdim\@ovdx\@clnwd \pIIe@bezier@QtoC\@ydim\@ovdy\@clnht \pIIe@moveto\@ovxx\@ovyy -% \end{macrocode} -% -% We call the basic |pict2e| macro to draw a cubic spline and we finish -% the conditional statements with which we started these calculations; -% eventually we close the group we opened at the beginning and we copy -% the terminal node information (position and direction) into the -% 0-labelled macros that indicate the starting point of the next arc. -% \begin{macrocode} \pIIe@curveto\@ovro\@ovri\@clnwd\@clnht\@xdim\@ydim \fi\fi\egroup \CopyVect\@Puno to\@Pzero \CopyVect\@Duno to\@Dzero \ignorespaces} -% \end{macrocode} -% -% An example of usage is shown at the left in figure~\ref{fig:quadratic-arcs}\footnote{The commands \cs{legenda}, \cs{Pall} and -% \cs{Zbox} are specifically defined in the preamble of this document; they must -% be used within a \texttt{picture} environment. \cs{legenda} draws a framed -% legend made up of a single (short) math formula; \cs{Pall} is just a shorthand -% to put a filled small circle at a specified position' \cs{Zbox} puts a -% symbol in math mode a little displaced in the proper direction relative to -% a specified position. They are just handy to label certain objects in a -% \texttt{picture} diagram, but they are not part of the \texttt{curve2e} -% package.}. -% created with the following code: -%\begin{verbatim} -%\begin{figure}[!htp] -%\unitlength=0.0045\textwidth -%\begin{picture}(100,100) -%\put(0,0){\framebox(100,100){}} -%\put(50,50){\Qurve(0,-50)<1,0>(50,0)<0,1>(0,50)<-1,0>% -%(-50,0)<0,-1>(0,-50)<1,0>\color{green}% -%\Qurve*(0,-50)<0,1>(50,0)<1,0>[-1,0](0,50)<0,1>[0,-1] -%(-50,0)<-1,0>[1,0](0,-50)<0,-1>} -%\Qurve(0,0)<1,4>(50,50)<1,0>(100,100)<1,4> -%\put(5,50){\Qurve(0,0)<1,1.5>(22.5,20)<1,0>(45,0)<1,-1.5>% -%(67.5,-20)<1,0>(90,0)<1,1.5>} -%\Zbox(0,0)[tl]{0,0}\Zbox(100,0)[tr]{100,0} -%\Zbox(100,100)[br]{100,100}\Zbox(0,100)[bl]{0,100} -%\end{picture} -%\end{figure} -%\end{verbatim} -% -%\begin{figure}[!tb] -%\unitlength=0.0045\textwidth -%\begin{picture}(100,100) -%\put(0,0){\framebox(100,100){}} -%\put(50,50){\Qurve(0,-50)<1,0>(50,0)<0,1>(0,50)<-1,0>(-50,0)<0,-1>(0,-50)<1,0>\color{green}% -%\Qurve*(0,-50)<0,1>(50,0)<1,0>[-1,0](0,50)<0,1>[0,-1](-50,0)<-1,0>[1,0](0,-50)<0,-1>} -%\Qurve(0,0)<1,4>(50,50)<1,0>(100,100)<1,4> -%\put(5,50){\Qurve(0,0)<1,1.5>(22.5,20)<1,0>(45,0)<1,-1.5>(67.5,-20)<1,0>(90,0)<1,1.5>} -%\Zbox(0,0)[tl]{0,0}\Zbox(100,0)[tr]{100,0} -%\Zbox(100,100)[br]{100,100}\Zbox(0,100)[bl]{0,100} -%\Pall[2](0,0)\Pall[2](100,0)\Pall[2](100,100)\Pall[2](0,100) -%\end{picture} -%\hfill -%\begin{picture}(100,100) -%\put(0,0){\framebox(100,100){}} -%\put(50,50){\Qurve(0,-50)<1,0>(50,0)<0,1>(0,50)<-1,0>(-50,0)<0,-1>(0,-50)<1,0> -%\Curve(0,-50)<1,0>(50,0)<0,1>(0,50)<-1,0>(-50,0)<0,-1>(0,-50)<1,0>} -%\Zbox(50,50)[t]{O}\Pall[2](50,50)\put(50,50){\Vector(45:50)}\Zbox(67,70)[tl]{R} -%\end{picture} -% -%\caption{\rule{0pt}{4ex}Several graphs drawn with quadratic Bézier splines} -%\label{fig:quadratic-arcs} -%\end{figure} -% -% Notice the green filled path: that result is not expected, but the filling -% operation is controlled by the inner workings of the typesetting program, -% where it fills what \emph{it} considers the interior of a path, not what -% \emph{we} think it is the interior of a path.Knowing this feature it is not -% difficult to fill the external lozenge with green, and then fill the internal -% path with white; the result would be to cover with white the external part of -% the interior path. Sort of odd way of getting the result, but this is not due -% to the quadratic splines but to the internal workings of |pdftex| and its -% companion typesetting engines, that consider ``interior'' the concave side of -% the closed path, not the convex one. -% -% Notice also that the inflexed line is made with two arcs that meet at the -% inflection point; the same is true for the line that resembles a sine wave. -% The cusps of the inner border of the green area are obtained with the usual -% optional argument already used also with the |\Curve| recursive macro. -% -% The ``circle'' inside the square frame is visibly different from a real -% circle, in spite of the fact that the maximum deviation from the true -% circle is just about 6\% relative to the radius; a quarter circle obtained -% with a single parabola is definitely a poor approximation of a real quarter -% circle; possibly by splitting each quarter circle in three or four partial -% arcs the approximation of a real quarter circle would be much better. On the -% right of figure~\ref{fig:quadratic-arcs} it is possible to compare a -% ``circle'' obtained with quadratic arcs with the the internal circle -% obtained with cubic arcs; the difference is easily seen even with a naked eye. -% -% With quadratic arcs we decided to avoid defining specific macros similar -% to |\CurveBetween| and |\CbezierBetween|; the first macro would not save -% any typing to the operator; furthermore it may be questionable if it was -% really useful even with cubic splines; the second macro with quadratic -% arcs is meaningless, since with quadratic arcs there is just one control -% point and there is no choice on its position. -% -% \section{Conclusion} -% I believe that the set of new macros provided by this package can really -% help the user to draw his/her diagrams with more agility; it will be the -% accumulated experience to decide if this is true. -%\iffalse -% -%\fi -% -%\iffalse -%<*manifest> -%\fi -% \begin{macrocode} -The package bundle curve2e is composed of the following files - -curve2e.dtx -curve2e.pdf -mainfest.txt -README.txt - -Manifest.txt is this file. - -curve2e.dtx is the documented TeX source file of file curve2e.sty; you get -both curve2e.sty and curve2e.pdf by running pdflatex on curve2e.dtx. - -README.txt contains general information. - -The package has the LPPL status of author maintained. - -According to the LPPL licence, you are entitled to modify this package, -as long as you fulfil the few conditions set forth by the Licence. - -Nevertheless this package is an extension to the standard LaTeX package pict2e -(2014). Therefore any change must be controlled against the parent package -pict2e so as to avoid redefining what has already been incorporated in the -official package. - -If you prefer sending me your modifications, as long as I will maintain this -package, I will possibly include every (documented) suggestion or modification -into this package. - -Claudio Beccari - -claudio.beccari@gmail.com -% \end{macrocode} -%\iffalse -% -%\fi -% -%\iffalse -%<*readme> -%\fi -% \begin{macrocode} -This file is an extension of the package pict2e.sty which extends the standard -picture LaTeX environment according to what Leslie Lamport specified in the -second edition of his LaTeX manual. - -This further extension allows to draw lines and vectors with any non integer -slope parameters, to draw dashed lined of any slope, to draw arcs and curved -vectors, to draw curves where just the interpolating nodes are specified -together with the slopes at the nodes; closed paths of any shape can be filled -with color; all coordinates are treated as ordered pairs, i.e. 'complex numbers'. -Some of these features have been incorporated in the 2011 version of pict2e; -therefore this package avoids any modification to the original pict2e commands. - - -Curve2e now accepts polar coordinates in addition to the usual cartesian ones; -several macros have been upgraded and a new macro for tracing cubic Bezier -splines with their control nodes specified in polar form is available. - -This version solves a conflict with package eso-pic. - -This version of curve2e is fully compatible with pict2e dated 2014/01/12 -version 0.2z. - -If you specify -\usepackage[]{curve2e} - -the package pict2e is automatically invoked with the specified options. % \end{macrocode} %\iffalse -% +% %\fi % \Finale % \endinput +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/Master/texmf-dist/source/latex/curve2e/ltxdoc.cfg b/Master/texmf-dist/source/latex/curve2e/ltxdoc.cfg new file mode 100644 index 00000000000..3593bb1e5fa --- /dev/null +++ b/Master/texmf-dist/source/latex/curve2e/ltxdoc.cfg @@ -0,0 +1,7 @@ +%% +%% This is file `ltxdoc.cfg', + +\AtBeginDocument{\OnlyDescription} + +%% +%% End of file `ltxdoc.cfg'. diff --git a/Master/texmf-dist/tex/latex/curve2e/curve2e-v161.sty b/Master/texmf-dist/tex/latex/curve2e/curve2e-v161.sty new file mode 100644 index 00000000000..509a3260119 --- /dev/null +++ b/Master/texmf-dist/tex/latex/curve2e/curve2e-v161.sty @@ -0,0 +1,904 @@ +%% +%% This is file `curve2e-v161.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% curve2e.dtx (with options: `v161') +%% +%% Copyright (C) 2005--2019 Claudio Beccari all rights reserved. +%% License information appended +%% + + + +\NeedsTeXFormat{LaTeX2e}[2016/01/01] +\ProvidesPackage{curve2e-v161}% + [2019/02/07 v.1.61 Extension package for pict2e] + +\RequirePackage{color} +\RequirePackageWithOptions{pict2e}[2014/01/01] +\RequirePackage{xparse} +\def\TRON{\tracingcommands\tw@ \tracingmacros\tw@}% +\def\TROF{\tracingcommands\z@ \tracingmacros\z@}% +\ifx\undefined\@tdA \newdimen\@tdA \fi +\ifx\undefined\@tdB \newdimen\@tdB \fi +\ifx\undefined\@tdC \newdimen\@tdC \fi +\ifx\undefined\@tdD \newdimen\@tdD \fi +\ifx\undefined\@tdE \newdimen\@tdE \fi +\ifx\undefined\@tdF \newdimen\@tdF \fi +\ifx\undefined\defaultlinewidth \newdimen\defaultlinewidth \fi +\gdef\linethickness#1{\@wholewidth#1\@halfwidth.5\@wholewidth\ignorespaces}% +\newcommand\defaultlinethickness[1]{\defaultlinewidth=#1\relax +\def\thicklines{\linethickness{\defaultlinewidth}}% +\def\thinlines{\linethickness{.5\defaultlinewidth}}% +\thinlines\ignorespaces} +\def\LIne(#1){{\GetCoord(#1)\@tX\@tY + \moveto(0,0) + \pIIe@lineto{\@tX\unitlength}{\@tY\unitlength}\strokepath}\ignorespaces}% +\def\segment(#1)(#2){\@killglue\polyline(#1)(#2)}% +\def\line(#1)#2{\begingroup + \@linelen #2\unitlength + \ifdim\@linelen<\z@\@badlinearg\else + \expandafter\DirOfVect#1to\Dir@line + \GetCoord(\Dir@line)\d@mX\d@mY + \ifdim\d@mX\p@=\z@\else + \DividE\ifdim\d@mX\p@<\z@-\fi\p@ by\d@mX\p@ to\sc@lelen + \@linelen=\sc@lelen\@linelen + \fi + \moveto(0,0) + \pIIe@lineto{\d@mX\@linelen}{\d@mY\@linelen}% + \strokepath + \fi +\endgroup\ignorespaces}% +\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 + \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 + \DividE\p@ by\NumA\p@ to \@tempa + \MultVect\V@ttC by\@tempa,0 to\V@ttB + \MultVect\V@ttB by 2,0 to\V@ttC + \advance\NumB\@ne + \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 +\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 +\AtBeginDocument{\@ifpackageloaded{eso-pic}{% +\renewcommand\LenToUnit[1]{\strip@pt\dimexpr#1*\p@/\unitlength}}{}} + +\def\GetCoord(#1)#2#3{% +\expandafter\SplitNod@\expandafter(#1)#2#3\ignorespaces} +\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(}%) + \def\vector(#1)#2{% + \begingroup + \GetCoord(#1)\d@mX\d@mY + \@linelen#2\unitlength + \ifdim\d@mX\p@=\z@\ifdim\d@mY\p@=\z@\@badlinearg\fi\fi + \ifdim\@linelen<\z@ \@linelen=-\@linelen\fi + \MakeVectorFrom\d@mX\d@mY to\@Vect + \DirOfVect\@Vect to\Dir@Vect + \YpartOfVect\Dir@Vect to\@ynum \@ydim=\@ynum\p@ + \XpartOfVect\Dir@Vect to\@xnum \@xdim=\@xnum\p@ + \ifdim\d@mX\p@=\z@ + \else\ifdim\d@mY\p@=\z@ + \else + \DividE\ifdim\@xnum\p@<\z@-\fi\p@ by\@xnum\p@ to\sc@lelen + \@linelen=\sc@lelen\@linelen + \fi + \fi + \@tdB=\@linelen +\pIIe@concat\@xdim\@ydim{-\@ydim}\@xdim{\@xnum\@linelen}{\@ynum\@linelen}% + \@linelen\z@ + \pIIe@vector + \fillpath + \@linelen=\@tdB + \@tdA=\pIIe@FAW\@wholewidth + \@tdA=\pIIe@FAL\@tdA + \advance\@linelen-\@tdA + \ifdim\@linelen>\z@ + \moveto(0,0) + \pIIe@lineto{\@xnum\@linelen}{\@ynum\@linelen}% + \strokepath\fi + \endgroup} +\def\Vector(#1){{% +\GetCoord(#1)\@tX\@tY +\ifdim\@tX\p@=\z@\vector(\@tX,\@tY){\@tY} +\else +\vector(\@tX,\@tY){\@tX}\fi}} +\def\VECTOR(#1)(#2){\begingroup +\SubVect#1from#2to\@tempa +\expandafter\put\expandafter(#1){\expandafter\Vector\expandafter(\@tempa)}% +\endgroup\ignorespaces} +\let\lp@r( \let\rp@r) +\renewcommand*\polyline[1][\beveljoin]{\p@lylin@[#1]} + +\def\p@lylin@[#1](#2){\@killglue#1\GetCoord(#2)\d@mX\d@mY + \pIIe@moveto{\d@mX\unitlength}{\d@mY\unitlength}% + \@ifnextchar\lp@r{\p@lyline}{% + \PackageWarning{curve2e}% + {Polylines require at least two vertices!\MessageBreak + Control your polyline specification\MessageBreak}% + \ignorespaces}} + +\def\p@lyline(#1){\GetCoord(#1)\d@mX\d@mY + \pIIe@lineto{\d@mX\unitlength}{\d@mY\unitlength}% + \@ifnextchar\lp@r{\p@lyline}{\strokepath\ignorespaces}} +\providecommand\polygon{} +\RenewDocumentCommand\polygon{s O{\beveljoin} }{\@killglue\begingroup +\IfBooleanTF{#1}{\@tempswatrue}{\@tempswafalse}% +\@polygon[#2]} + +\def\@polygon[#1](#2){\@killglue#1\GetCoord(#2)\d@mX\d@mY + \pIIe@moveto{\d@mX\unitlength}{\d@mY\unitlength}% + \@ifnextchar\lp@r{\@@polygon}{% + \PackageWarning{curve2e}% + {Polygons require at least two vertices!\MessageBreak + Control your polygon specification\MessageBreak}% + \ignorespaces}} + + \def\@@polygon(#1){\GetCoord(#1)\d@mX\d@mY + \pIIe@lineto{\d@mX\unitlength}{\d@mY\unitlength}% + \@ifnextchar\lp@r{\@@polygon}{\pIIe@closepath + \if@tempswa\pIIe@fillGraph\else\pIIe@strokeGraph\fi + \endgroup + \ignorespaces}} +\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}% +\egroup\ignorespaces} +\def\RoundUp#1modulo#2to#3{\expandafter\@tempcnta\Integer#1.??% +\count254\@tempcnta\divide\count254by#2\relax +\multiply\count254by#2\relax +\count252\@tempcnta\advance\count252-\count254 +\ifnum\count252>0\advance\count252-#2\relax +\advance\@tempcnta-\count252\fi\edef#3{\number\@tempcnta}\ignorespaces}% +\def\Integer#1.#2??{#1}% +\ifdefined\dimexpr + \unless\ifdefined\DividE +\def\DividE#1by#2to#3{\bgroup +\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 + \edef\x{% + \noexpand\egroup\noexpand\def\noexpand#3{% + \strip@pt\dimexpr\@DimA*\Num/\Den\relax}}% +\fi +\x\ignorespaces}% +\fi + \unless\ifdefined\DivideFN + \def\DivideFN#1by#2to#3{\DividE#1\p@ by#2\p@ to{#3}}% + \fi + \unless\ifdefined\MultiplY + \def\MultiplY#1by#2to#3{\bgroup + \dimendef\@DimA 2254 \dimendef\@DimB2255 + \@DimA=#1\p@\relax \@DimB=#2\p@\relax + \edef\x{% + \noexpand\egroup\noexpand\def\noexpand#3{% + \strip@pt\dimexpr\@DimA*\@DimB/\p@\relax}}% + \x\ignorespaces}% + \let\MultiplyFN\MultiplY + \fi +\fi + +\unless\ifdefined\Numero + \def\Numero#1#2{\bgroup\dimen3254=#2\relax + \edef\x{\noexpand\egroup\noexpand\edef\noexpand#1{% + \strip@pt\dimen3254}}\x\ignorespaces}% +\fi +\def\g@tTanCotanFrom#1to#2and#3{% +\DividE 114.591559\p@ by#1to\X@ \@tdB=\X@\p@ +\countdef\I=2546\def\Tan{0}\I=11\relax +\@whilenum\I>\z@\do{% + \@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\SinOf#1to#2{\bgroup% +\@tdA=#1\p@% +\ifdim\@tdA>\z@% + \@whiledim\@tdA>180\p@\do{\advance\@tdA -360\p@}% +\else% + \@whiledim\@tdA<-180\p@\do{\advance\@tdA 360\p@}% +\fi \ifdim\@tdA=\z@ + \def\@tempA{0}% +\else + \ifdim\@tdA>\z@ + \def\Segno{+}% + \else + \def\Segno{-}% + \@tdA=-\@tdA + \fi + \ifdim\@tdA>90\p@ + \@tdA=-\@tdA \advance\@tdA 180\p@ + \fi + \ifdim\@tdA=90\p@ + \def\@tempA{\Segno1}% + \else + \ifdim\@tdA=180\p@ + \def\@tempA{0}% + \else + \ifdim\@tdA<\p@ + \@tdA=\Segno0.0174533\@tdA + \DividE\@tdA by\p@ to \@tempA% + \else + \g@tTanCotanFrom\@tdA to\T and\Tp + \@tdA=\T\p@ \advance\@tdA \Tp\p@ + \DividE \Segno2\p@ by\@tdA to \@tempA% + \fi + \fi + \fi +\fi +\edef\endSinOf{\noexpand\egroup + \noexpand\def\noexpand#2{\@tempA}\noexpand\ignorespaces}% +\endSinOf}% +\def\CosOf#1to#2{\bgroup% +\@tdA=#1\p@% +\ifdim\@tdA>\z@% + \@whiledim\@tdA>360\p@\do{\advance\@tdA -360\p@}% +\else% + \@whiledim\@tdA<\z@\do{\advance\@tdA 360\p@}% +\fi +\ifdim\@tdA>180\p@ + \@tdA=-\@tdA \advance\@tdA 360\p@ +\fi +\ifdim\@tdA<90\p@ + \def\Segno{+}% +\else + \def\Segno{-}% + \@tdA=-\@tdA \advance\@tdA 180\p@ +\fi +\ifdim\@tdA=\z@ + \def\@tempA{\Segno1}% +\else + \ifdim\@tdA<\p@ + \@tdA=0.0174533\@tdA \Numero\@tempA\@tdA + \@tdA=\@tempA\@tdA \@tdA=-.5\@tdA + \advance\@tdA \p@ + \DividE\@tdA by\p@ to\@tempA% + \else + \ifdim\@tdA=90\p@ + \def\@tempA{0}% + \else + \g@tTanCotanFrom\@tdA to\T and\Tp + \@tdA=\Tp\p@ \advance\@tdA-\T\p@ + \@tdB=\Tp\p@ \advance\@tdB\T\p@ + \DividE\Segno\@tdA by\@tdB to\@tempA% + \fi + \fi +\fi +\edef\endCosOf{\noexpand\egroup + \noexpand\def\noexpand#2{\@tempA}\noexpand\ignorespaces}% +\endCosOf}% +\def\TanOf#1to#2{\bgroup% +\@tdA=#1\p@% +\ifdim\@tdA>90\p@% + \@whiledim\@tdA>90\p@\do{\advance\@tdA -180\p@}% +\else% + \@whiledim\@tdA<-90\p@\do{\advance\@tdA 180\p@}% +\fi% +\ifdim\@tdA=\z@% + \def\@tempA{0}% +\else + \ifdim\@tdA>\z@ + \def\Segno{+}% + \else + \def\Segno{-}% + \@tdA=-\@tdA + \fi + \ifdim\@tdA=90\p@ + \def\@tempA{\Segno16383.99999}% + \else + \ifdim\@tdA<\p@ + \@tdA=\Segno0.0174533\@tdA + \DividE\@tdA by\p@ to\@tempA% + \else + \g@tTanCotanFrom\@tdA to\T and\Tp + \@tdA\Tp\p@ \advance\@tdA -\T\p@ + \DividE\Segno2\p@ by\@tdA to\@tempA% + \fi + \fi +\fi +\edef\endTanOf{\noexpand\egroup + \noexpand\def\noexpand#2{\@tempA}\noexpand\ignorespaces}% +\endTanOf}% +\def\ArcTanOf#1to#2{\bgroup +\countdef\Inverti 4444\Inverti=0 +\def\Segno{} +\edef\@tF{#1}\@tdF=\@tF\p@ \@tdE=57.295778\p@ +\@tdD=\ifdim\@tdF<\z@ -\@tdF\def\Segno{-}\else\@tdF\fi +\ifdim\@tdD>\p@ +\Inverti=\@ne +\@tdD=\dimexpr\p@*\p@/\@tdD\relax +\fi +\unless\ifdim\@tdD>0.02\p@ + \def\@tX{\strip@pt\dimexpr57.295778\@tdD\relax}% +\else + \edef\@tX{45}\relax + \countdef\I 2523 \I=9\relax + \@whilenum\I>0\do{\TanOf\@tX to\@tG + \edef\@tG{\strip@pt\dimexpr\@tG\p@-\@tdD\relax}\relax + \MultiplY\@tG by57.295778to\@tG + \CosOf\@tX to\@tH + \MultiplY\@tH by\@tH to\@tH + \MultiplY\@tH by\@tG to \@tH + \edef\@tX{\strip@pt\dimexpr\@tX\p@ - \@tH\p@\relax}\relax + \advance\I\m@ne}% +\fi +\ifnum\Inverti=\@ne +\edef\@tX{\strip@pt\dimexpr90\p@-\@tX\p@\relax} +\fi +\edef\x{\egroup\noexpand\edef\noexpand#2{\Segno\@tX}}\x\ignorespaces}% +\def\MakeVectorFrom#1#2to#3{\edef#3{#1,#2}\ignorespaces}% +\def\CopyVect#1to#2{\edef#2{#1}\ignorespaces}% +\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=\z@ + \ifdim\@tempdimb=\z@ + \def\@T{0}\@tempdimc=\z@ + \else + \def\@T{0}\@tempdimc=\@tempdimb + \fi +\else + \ifdim\@tempdima>\@tempdimb + \DividE\@tempdimb by\@tempdima to\@T + \@tempdimc=\@tempdima + \else + \DividE\@tempdima by\@tempdimb to\@T + \@tempdimc=\@tempdimb + \fi +\fi +\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}% +\def\DirOfVect#1to#2{\GetCoord(#1)\t@X\t@Y +\ModOfVect#1to\@tempa +\unless\ifdim\@tempdimc=\z@ + \DividE\t@X\p@ by\@tempdimc to\t@X + \DividE\t@Y\p@ by\@tempdimc to\t@Y +\fi +\MakeVectorFrom\t@X\t@Y to#2\ignorespaces}% +\def\ModAndDirOfVect#1to#2and#3{% +\GetCoord(#1)\t@X\t@Y +\ModOfVect#1to#2% +\ifdim\@tempdimc=\z@\else + \DividE\t@X\p@ by\@tempdimc to\t@X + \DividE\t@Y\p@ by\@tempdimc to\t@Y +\fi +\MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% +\def\DistanceAndDirOfVect#1minus#2to#3and#4{% +\SubVect#2from#1to\@tempa +\ModAndDirOfVect\@tempa to#3and#4\ignorespaces}% +\def\XpartOfVect#1to#2{% +\GetCoord(#1)#2\@tempa\ignorespaces}% +\def\YpartOfVect#1to#2{% +\GetCoord(#1)\@tempa#2\ignorespaces}% +\def\DirFromAngle#1to#2{% +\CosOf#1to\t@X +\SinOf#1to\t@Y +\MakeVectorFrom\t@X\t@Y to#2\ignorespaces}% +\def\ArgOfVect#1to#2{\bgroup\GetCoord(#1){\t@X}{\t@Y}% +\def\s@gno{}\def\addflatt@ngle{0} +\ifdim\t@X\p@=\z@ + \ifdim\t@Y\p@=\z@ + \def\ArcTan{0}% + \else + \def\ArcTan{90}% + \ifdim\t@Y\p@<\z@\def\s@gno{-}\fi + \fi +\else + \ifdim\t@Y\p@=\z@ + \ifdim\t@X\p@<\z@ + \def\ArcTan{180}% + \else + \def\ArcTan{0}% + \fi + \else + \ifdim\t@X\p@<\z@% + \def\addflatt@ngle{180}% + \edef\t@X{\strip@pt\dimexpr-\t@X\p@}% + \edef\t@Y{\strip@pt\dimexpr-\t@Y\p@}% + \ifdim\t@Y\p@<\z@ + \def\s@gno{-}% + \edef\t@Y{-\t@Y}% + \fi + \fi + \DivideFN\t@Y by\t@X to \t@A + \ArcTanOf\t@A to\ArcTan + \fi +\fi +\edef\ArcTan{\unless\ifx\s@gno\empty\s@gno\fi\ArcTan}% +\unless\ifnum\addflatt@ngle=0\relax + \edef\ArcTan{% + \strip@pt\dimexpr\ArcTan\p@\ifx\s@gno\empty-\else+\fi + \addflatt@ngle\p@\relax}% +\fi +\edef\x{\noexpand\egroup\noexpand\edef\noexpand#2{\ArcTan}}% +\x\ignorespaces} +\def\ScaleVect#1by#2to#3{\GetCoord(#1)\t@X\t@Y +\@tempdima=\t@X\p@ \@tempdima=#2\@tempdima\Numero\t@X\@tempdima +\@tempdima=\t@Y\p@ \@tempdima=#2\@tempdima\Numero\t@Y\@tempdima +\MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% +\def\ConjVect#1to#2{\GetCoord(#1)\t@X\t@Y +\@tempdima=-\t@Y\p@\Numero\t@Y\@tempdima +\MakeVectorFrom\t@X\t@Y to#2\ignorespaces}% +\def\AddVect#1and#2to#3{\GetCoord(#1)\tu@X\tu@Y +\GetCoord(#2)\td@X\td@Y +\@tempdima\tu@X\p@\advance\@tempdima\td@X\p@ \Numero\t@X\@tempdima +\@tempdima\tu@Y\p@\advance\@tempdima\td@Y\p@ \Numero\t@Y\@tempdima +\MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% +\def\SubVect#1from#2to#3{\GetCoord(#1)\tu@X\tu@Y +\GetCoord(#2)\td@X\td@Y +\@tempdima\td@X\p@\advance\@tempdima-\tu@X\p@ \Numero\t@X\@tempdima +\@tempdima\td@Y\p@\advance\@tempdima-\tu@Y\p@ \Numero\t@Y\@tempdima +\MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% +\def\MultVect#1by{\@ifstar{\@ConjMultVect#1by}{\@MultVect#1by}}% +\def\@MultVect#1by#2to#3{\GetCoord(#1)\tu@X\tu@Y +\GetCoord(#2)\td@X\td@Y +\@tempdima\tu@X\p@ \@tempdimb\tu@Y\p@ +\@tempdimc=\td@X\@tempdima\advance\@tempdimc-\td@Y\@tempdimb +\Numero\t@X\@tempdimc +\@tempdimc=\td@Y\@tempdima\advance\@tempdimc\td@X\@tempdimb +\Numero\t@Y\@tempdimc +\MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% +\def\@ConjMultVect#1by#2to#3{\GetCoord(#1)\tu@X\tu@Y +\GetCoord(#2)\td@X\td@Y \@tempdima\tu@X\p@ \@tempdimb\tu@Y\p@ +\@tempdimc=\td@X\@tempdima\advance\@tempdimc+\td@Y\@tempdimb +\Numero\t@X\@tempdimc +\@tempdimc=\td@X\@tempdimb\advance\@tempdimc-\td@Y\@tempdima +\Numero\t@Y\@tempdimc +\MakeVectorFrom\t@X\t@Y to#3\ignorespaces} +\def\DivVect#1by#2to#3{\ModAndDirOfVect#2to\@Mod and\@Dir +\DividE\p@ by\@Mod\p@ to\@Mod \ConjVect\@Dir to\@Dir +\ScaleVect#1by\@Mod to\@tempa +\MultVect\@tempa by\@Dir to#3\ignorespaces}% +\def\Arc(#1)(#2)#3{\begingroup +\@tdA=#3\p@ +\unless\ifdim\@tdA=\z@ + \@Arc(#1)(#2)% +\fi +\endgroup\ignorespaces}% +\def\@Arc(#1)(#2){% +\ifdim\@tdA>\z@ + \let\Segno+% +\else + \@tdA=-\@tdA \let\Segno-% +\fi +\Numero\@gradi\@tdA +\ifdim\@tdA>360\p@ + \PackageWarning{curve2e}{The arc aperture is \@gradi\space degrees + and gets reduced\MessageBreak% + to the range 0--360 taking the sign into consideration}% + \@whiledim\@tdA>360\p@\do{\advance\@tdA-360\p@}% +\fi +\SubVect#2from#1to\@V \ModOfVect\@V to\@Raggio \CopyVect#2to\@pPun +\CopyVect#1to\@Cent \GetCoord(\@pPun)\@pPunX\@pPunY +\@@Arc +\strokepath\ignorespaces}% +\def\@@Arc{% +\pIIe@moveto{\@pPunX\unitlength}{\@pPunY\unitlength}% +\ifdim\@tdA>180\p@ + \advance\@tdA-180\p@ + \Numero\@gradi\@tdA + \SubVect\@pPun from\@Cent to\@V + \AddVect\@V and\@Cent to\@sPun + \MultVect\@V by0,-1.3333333to\@V \if\Segno-\ScaleVect\@V by-1to\@V\fi + \AddVect\@pPun and\@V to\@pcPun + \AddVect\@sPun and\@V to\@scPun + \GetCoord(\@pcPun)\@pcPunX\@pcPunY + \GetCoord(\@scPun)\@scPunX\@scPunY + \GetCoord(\@sPun)\@sPunX\@sPunY + \pIIe@curveto{\@pcPunX\unitlength}{\@pcPunY\unitlength}% + {\@scPunX\unitlength}{\@scPunY\unitlength}% + {\@sPunX\unitlength}{\@sPunY\unitlength}% + \CopyVect\@sPun to\@pPun +\fi +\ifdim\@tdA>\z@ + \DirFromAngle\@gradi to\@Dir \if\Segno-\ConjVect\@Dir to\@Dir \fi + \SubVect\@Cent from\@pPun to\@V + \MultVect\@V by\@Dir to\@V + \AddVect\@Cent and\@V to\@sPun + \@tdA=.5\@tdA \Numero\@gradi\@tdA + \DirFromAngle\@gradi to\@Phimezzi + \GetCoord(\@Phimezzi)\@cosphimezzi\@sinphimezzi + \@tdB=1.3333333\p@ \@tdB=\@Raggio\@tdB + \@tdC=\p@ \advance\@tdC -\@cosphimezzi\p@ \Numero\@tempa\@tdC + \@tdB=\@tempa\@tdB + \DividE\@tdB by\@sinphimezzi\p@ to\@cZ + \ScaleVect\@Phimezzi by\@cZ to\@Phimezzi + \ConjVect\@Phimezzi to\@mPhimezzi + \if\Segno-% + \let\@tempa\@Phimezzi + \let\@Phimezzi\@mPhimezzi + \let\@mPhimezzi\@tempa + \fi + \SubVect\@sPun from\@pPun to\@V + \DirOfVect\@V to\@V + \MultVect\@Phimezzi by\@V to\@Phimezzi + \AddVect\@sPun and\@Phimezzi to\@scPun + \ScaleVect\@V by-1to\@V + \MultVect\@mPhimezzi by\@V to\@mPhimezzi + \AddVect\@pPun and\@mPhimezzi to\@pcPun + \GetCoord(\@pcPun)\@pcPunX\@pcPunY + \GetCoord(\@scPun)\@scPunX\@scPunY + \GetCoord(\@sPun)\@sPunX\@sPunY + \pIIe@curveto{\@pcPunX\unitlength}{\@pcPunY\unitlength}% + {\@scPunX\unitlength}{\@scPunY\unitlength}% + {\@sPunX\unitlength}{\@sPunY\unitlength}% +\fi} +\def\VectorArc(#1)(#2)#3{\begingroup +\@tdA=#3\p@ \ifdim\@tdA=\z@\else + \@VArc(#1)(#2)% +\fi +\endgroup\ignorespaces}% +\def\VectorARC(#1)(#2)#3{\begingroup +\@tdA=#3\p@ +\ifdim\@tdA=\z@\else + \@VARC(#1)(#2)% +\fi +\endgroup\ignorespaces}% +\def\@VArc(#1)(#2){% +\ifdim\@tdA>\z@ + \let\Segno+% +\else + \@tdA=-\@tdA \let\Segno-% +\fi \Numero\@gradi\@tdA +\ifdim\@tdA>360\p@ + \PackageWarning{curve2e}{The arc aperture is \@gradi\space degrees + and gets reduced\MessageBreak% + to the range 0--360 taking the sign into consideration}% + \@whiledim\@tdA>360\p@\do{\advance\@tdA-360\p@}% +\fi +\SubVect#1from#2to\@V \ModOfVect\@V to\@Raggio \CopyVect#2to\@pPun +\@tdE=\pIIe@FAW\@wholewidth \@tdE=\pIIe@FAL\@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 +\DirFromAngle\@tempa to\@Dir +\MultVect\@V by\@Dir to\@sPun +\edef\@tempA{\ifx\Segno-\m@ne\else\@ne\fi}% +\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=.5\@tdD \Numero\DeltaGradi\@tdD +\DirFromAngle\DeltaGradi to\@Dird +\MultVect\@Dir by*\@Dird to\@Dir +\GetCoord(\@Dir)\@xnum\@ynum +\put(\@tdX,\@tdY){\vector(\@xnum,\@ynum){0}}% +\@tdE =\ifx\Segno--\fi\DeltaGradi\p@ +\advance\@tdA -\@tdE \Numero\@gradi\@tdA +\CopyVect#1to\@Cent \GetCoord(\@pPun)\@pPunX\@pPunY +\@@Arc +\strokepath\ignorespaces}% +\def\@VARC(#1)(#2){% +\ifdim\@tdA>\z@ + \let\Segno+% +\else + \@tdA=-\@tdA \let\Segno-% +\fi \Numero\@gradi\@tdA +\ifdim\@tdA>360\p@ + \PackageWarning{curve2e}{The arc aperture is \@gradi\space degrees + and gets reduced\MessageBreak% + to the range 0--360 taking the sign into consideration}% + \@whiledim\@tdA>360\p@\do{\advance\@tdA-360\p@}% +\fi +\SubVect#1from#2to\@V \ModOfVect\@V to\@Raggio \CopyVect#2to\@pPun +\@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=\if\Segno--\fi\@gradi\p@ \Numero\@tempa\@tdD +\DirFromAngle\@tempa to\@Dir +\MultVect\@V by\@Dir to\@sPun% corrects the end point +\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\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}}% 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{\if\Segno-\else-\fi\@ne}% +\MultVect\@V by0,\@tempa to\@vPun +\@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}}% 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 +\AddVect\@Cent and\@V to\@pPun +\GetCoord(\@pPun)\@pPunX\@pPunY +\@@Arc +\strokepath\ignorespaces}% +\def\CurveBetween#1and#2WithDirs#3and#4{% +\StartCurveAt#1WithDir{#3}\relax +\CurveTo#2WithDir{#4}\CurveFinish\ignorespaces}% +\def\StartCurveAt#1WithDir#2{% +\begingroup +\GetCoord(#1)\@tempa\@tempb +\CopyVect\@tempa,\@tempb to\@Pzero +\pIIe@moveto{\@tempa\unitlength}{\@tempb\unitlength}% +\GetCoord(#2)\@tempa\@tempb +\CopyVect\@tempa,\@tempb to\@Dzero +\DirOfVect\@Dzero to\@Dzero +\ignorespaces} +\def\ChangeDir<#1>{% +\GetCoord(#1)\@tempa\@tempb +\CopyVect\@tempa,\@tempb to\@Dzero +\DirOfVect\@Dzero to\@Dzero +\ignorespaces} +\def\CurveFinish{\strokepath\endgroup\ignorespaces}% +\def\FillCurve{\fillpath\endgroup\ignorespaces} +\def\CurveEnd{\fillstroke\endgroup\ignorespaces} +\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}% +\def\CbezierBetween#1And#2WithDirs#3And#4UsingDists#5And#6{% +\StartCurveAt#1WithDir{#3}\relax +\CbezierTo#2WithDir#4AndDists#5And{#6}\CurveFinish} + +\def\@isTension#1;#2!!{\def\@tempA{#1}% +\def\@tempB{#2}\unless\ifx\@tempB\empty\strip@semicolon#2\fi} +\def\strip@semicolon#1;{\def\@tempB{#1}} +\def\CurveTo#1WithDir#2{% +\def\@Tuno{1}\def\@Tzero{1}\relax +\edef\@Puno{#1}\@isTension#2;!!% +\expandafter\DirOfVect\@tempA to\@Duno +\bgroup\unless\ifx\@tempB\empty\GetCoord(\@tempB)\@Tzero\@Tuno\fi +\DistanceAndDirOfVect\@Puno minus\@Pzero to\@Chord and\@DirChord +\MultVect\@Dzero by*\@DirChord to \@Dpzero +\MultVect\@Duno by*\@DirChord to \@Dpuno +\GetCoord(\@Dpzero)\@DXpzero\@DYpzero +\GetCoord(\@Dpuno)\@DXpuno\@DYpuno +\DivideFN\@Chord by2 to\@semichord +\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 +\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@)\relax + \DividE\@KCzero\@tdA by\@SinDzero\p@ to \@KCzero + \fi +\fi +\MultiplyFN\@KCzero by \@Tzero to \@KCzero +\ScaleVect\@Dzero by\@KCzero to\@CPzero +\AddVect\@Pzero and\@CPzero to\@CPzero +\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@)\relax + \DividE\@KCuno\@tdA by\@SinDuno\p@ to \@KCuno + \fi +\fi +\MultiplyFN\@KCuno by \@Tuno to \@KCuno +\ScaleVect\@Duno by\@KCuno to\@CPuno +\AddVect\@Puno and\@CPuno to\@CPuno +\GetCoord(\@Puno)\@XPuno\@YPuno +\GetCoord(\@CPzero)\@XCPzero\@YCPzero +\GetCoord(\@CPuno)\@XCPuno\@YCPuno +\pIIe@curveto{\@XCPzero\unitlength}{\@YCPzero\unitlength}% + {\@XCPuno\unitlength}{\@YCPuno\unitlength}% + {\@XPuno\unitlength}{\@YPuno\unitlength}\egroup +\CopyVect\@Puno to\@Pzero +\CopyVect\@Duno to\@Dzero +\ignorespaces}% +\def\Curve{\@ifstar{\let\fillstroke\fillpath\Curve@}% +{\let\fillstroke\strokepath\Curve@}} +\def\Curve@(#1)<#2>{% + \StartCurveAt#1WithDir{#2}% + \@ifnextchar\lp@r\@Curve{% + \PackageWarning{curve2e}{% + Curve specifications must contain at least two nodes!\Messagebreak + Please, control your Curve specifications\MessageBreak}}} +\def\@Curve(#1)<#2>{% + \CurveTo#1WithDir{#2}% + \@ifnextchar\lp@r\@Curve{% + \@ifnextchar[\@ChangeDir\CurveEnd}} +\def\@ChangeDir[#1]{\ChangeDir<#1>\@Curve} +\def\Qurve{\@ifstar{\let\fillstroke\fillpath\Qurve@}% +{\let\fillstroke\strokepath\Qurve@}} + +\def\Qurve@(#1)<#2>{% + \StartCurveAt#1WithDir{#2}% + \@ifnextchar\lp@r\@Qurve{% + \PackageWarning{curve2e}{% + Quadratic curve specifications must contain at least + two nodes!\Messagebreak + Please, control your Qurve specifications\MessageBreak}}}% +\def\@Qurve(#1)<#2>{\QurveTo#1WithDir{#2}% + \@ifnextchar\lp@r\@Qurve{% + \@ifnextchar[\@ChangeQDir\CurveEnd}}% +\def\@ChangeQDir[#1]{\ChangeDir<#1>\@Qurve}% +\def\QurveTo#1WithDir#2{% +\edef\@Puno{#1}\DirOfVect#2to\@Duno\bgroup +\DistanceAndDirOfVect\@Puno minus\@Pzero to\@Chord and\@DirChord +\MultVect\@Dzero by*\@Duno to \@Scalar +\YpartOfVect\@Scalar to \@YScalar +\ifdim\@YScalar\p@=\z@ +\PackageWarning{curve2e}% + {Quadratic Bezier arcs cannot have their starting\MessageBreak + and ending directions parallel or antiparallel with\MessageBreak + each other. This arc is skipped and replaced with + a dotted line.\MessageBreak}% + \Dotline(\@Pzero)(\@Puno){2}\relax +\else +\MultVect\@Dzero by*\@DirChord to \@Dpzero +\MultVect\@Duno by*\@DirChord to \@Dpuno +\GetCoord(\@Dpzero)\@DXpzero\@DYpzero +\GetCoord(\@Dpuno)\@DXpuno\@DYpuno +\MultiplyFN\@DXpzero by\@DXpuno to\@XXD +\MultiplyFN\@DYpzero by\@DYpuno to\@YYD +\unless\ifdim\@YYD\p@<\z@\ifdim\@XXD\p@<\z@ +\PackageWarning{curve2e}% + {Quadratic Bezier arcs cannot have inflection points\MessageBreak + Therefore the tangents to the starting and ending arc\MessageBreak + points cannot be directed to the same half plane.\MessageBreak + This arc is skipped and replaced by a dotted line\MessageBreak}% + \Dotline(\@Pzero)(\@Puno){2}\fi +\else +\edef\@CDzero{\@DXpzero}\relax +\edef\@SDzero{\@DYpzero}\relax +\edef\@CDuno{\@DXpuno}\relax +\edef\@SDuno{\@DYpuno}\relax +\MultiplyFN\@SDzero by\@CDuno to\@tempA +\MultiplyFN\@SDuno by\@CDzero to\@tempB +\edef\@tempA{\strip@pt\dimexpr\@tempA\p@-\@tempB\p@}\relax +\@tdA=\@SDuno\p@ \@tdB=\@Chord\p@ \@tdC=\@tempA\p@ +\edef\@tempC{\strip@pt\dimexpr \@tdA*\@tdB/\@tdC}\relax +\MultiplyFN\@tempC by\@CDzero to \@XC +\MultiplyFN\@tempC by\@SDzero to \@YC +\ModOfVect\@XC,\@YC to\@KC +\ScaleVect\@Dzero by\@KC to\@CP +\AddVect\@Pzero and\@CP to\@CP +\GetCoord(\@Pzero)\@XPzero\@YPzero +\GetCoord(\@Puno)\@XPuno\@YPuno +\GetCoord(\@CP)\@XCP\@YCP +\@ovxx=\@XPzero\unitlength \@ovyy=\@YPzero\unitlength +\@ovdx=\@XCP\unitlength \@ovdy=\@YCP\unitlength +\@xdim=\@XPuno\unitlength \@ydim=\@YPuno\unitlength + \pIIe@bezier@QtoC\@ovxx\@ovdx\@ovro + \pIIe@bezier@QtoC\@ovyy\@ovdy\@ovri + \pIIe@bezier@QtoC\@xdim\@ovdx\@clnwd + \pIIe@bezier@QtoC\@ydim\@ovdy\@clnht + \pIIe@moveto\@ovxx\@ovyy + \pIIe@curveto\@ovro\@ovri\@clnwd\@clnht\@xdim\@ydim +\fi\fi\egroup +\CopyVect\@Puno to\@Pzero +\CopyVect\@Duno to\@Dzero +\ignorespaces} + + +%% +%% +%% Distributable under the LaTeX Project Public License, +%% version 1.3c or higher (your choice). The latest version of +%% this license is at: http://www.latex-project.org/lppl.txt +%% +%% This work is "author-maintained" +%% +%% This work consists of file curve2e.dtx, and the derived files +%% curve2e.sty and curve2e.pdf, plus the auxiliary derived files +%% README.txt and manifest.txt. +%% +%% +%% End of file `curve2e-v161.sty'. diff --git a/Master/texmf-dist/tex/latex/curve2e/curve2e.sty b/Master/texmf-dist/tex/latex/curve2e/curve2e.sty index 0224f13d05a..3edfbecf539 100644 --- a/Master/texmf-dist/tex/latex/curve2e/curve2e.sty +++ b/Master/texmf-dist/tex/latex/curve2e/curve2e.sty @@ -11,12 +11,30 @@ %% \NeedsTeXFormat{LaTeX2e}[2016/01/01] \ProvidesPackage{curve2e}% - [2019/02/07 v.1.61 Extension package for pict2e] + [2019-03-29 v.2.0.1 Extension package for pict2e] -\RequirePackage{color} -\RequirePackageWithOptions{pict2e}[2014/01/01] -\RequirePackage{xparse} + +\IfFileExists{xfp.sty}{% + \RequirePackage{color} + \RequirePackageWithOptions{pict2e}[2014/01/01] + \@ifl@aded{sty}{xparse}{}{\RequirePackage{xparse}} + \@ifl@aded{sty}{xfp}{}{\RequirePackage{xfp}}% +}{% + \RequirePackage{curve2e-v161}% + \PackageWarningNoLine{curve2e}{% + Package xfp is required, but apparently\MessageBreak% + such package cannot be found in this \MessageBreak% + TeX system installation\MessageBreak% + Either your installation is not complete \MessageBreak% + or it is older than 2018-10-17.\MessageBreak% + \MessageBreak% + ***************************************\MessageBreak% + Version 1.61 of curve2e has been loaded\MessageBreak% + instead of the current version\MessageBreak% + ***************************************\MessageBreak}% + \endinput +} \def\TRON{\tracingcommands\tw@ \tracingmacros\tw@}% \def\TROF{\tracingcommands\z@ \tracingmacros\z@}% \ifx\undefined\@tdA \newdimen\@tdA \fi @@ -26,14 +44,15 @@ \ifx\undefined\@tdE \newdimen\@tdE \fi \ifx\undefined\@tdF \newdimen\@tdF \fi \ifx\undefined\defaultlinewidth \newdimen\defaultlinewidth \fi -\gdef\linethickness#1{\@wholewidth#1\@halfwidth.5\@wholewidth\ignorespaces}% +\gdef\linethickness#1{% +\@wholewidth#1\@halfwidth.5\@wholewidth\ignorespaces}% \newcommand\defaultlinethickness[1]{\defaultlinewidth=#1\relax \def\thicklines{\linethickness{\defaultlinewidth}}% -\def\thinlines{\linethickness{.5\defaultlinewidth}}% -\thinlines\ignorespaces} +\def\thinlines{\linethickness{.5\defaultlinewidth}}\thinlines \ignorespaces}% \def\LIne(#1){{\GetCoord(#1)\@tX\@tY - \moveto(0,0) - \pIIe@lineto{\@tX\unitlength}{\@tY\unitlength}\strokepath}\ignorespaces}% + \moveto(0,0) + \pIIe@lineto{\@tX\unitlength}{\@tY\unitlength}\strokepath}\ignorespaces +}% \def\segment(#1)(#2){\@killglue\polyline(#1)(#2)}% \def\line(#1)#2{\begingroup \@linelen #2\unitlength @@ -41,7 +60,7 @@ \expandafter\DirOfVect#1to\Dir@line \GetCoord(\Dir@line)\d@mX\d@mY \ifdim\d@mX\p@=\z@\else - \DividE\ifdim\d@mX\p@<\z@-\fi\p@ by\d@mX\p@ to\sc@lelen + \edef\sc@lelen{\fpeval{1 / abs(\d@mX)}}\relax \@linelen=\sc@lelen\@linelen \fi \moveto(0,0) @@ -50,62 +69,62 @@ \fi \endgroup\ignorespaces}% \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 - \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 - \DividE\p@ by\NumA\p@ to \@tempa - \MultVect\V@ttC by\@tempa,0 to\V@ttB - \MultVect\V@ttB by 2,0 to\V@ttC - \advance\NumB\@ne - \edef\@mpt{\noexpand\egroup - \noexpand\multiput(\V@ttA)(\V@ttC){\number\NumB}% - {\noexpand\LIne(\V@ttB)}}% - \@mpt\ignorespaces}% -\let\Dline\Dashline + \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 + \DivideFN\DlineMod by#3 to\NumD + \NumA=\fpeval{trunc(\NumD,0)}\relax + \unless\ifodd\NumA\advance\NumA\@ne\fi + \NumB=\NumA \divide\NumB\tw@ + \DividE\DlineMod\p@ by\NumA\p@ to\D@shMod + \DividE\p@ by\NumA\p@ to \@tempa + \MultVect\V@ttC by\@tempa,0 to\V@ttB + \MultVect\V@ttB by 2,0 to\V@ttC + \advance\NumB\@ne + \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}}} + \def\Dashline@@(#1)(#2)#3{\put(#1){\Dashline@(0,0)(#2){#3}}} \fi \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{\@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=\fpeval{trunc(\NumD,0)}\relax + \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}}} + \def\Dotline@@(#1)(#2)#3{\put(#1){\Dotline@(0,0)(#2){#3}}}% \fi \AtBeginDocument{\@ifpackageloaded{eso-pic}{% -\renewcommand\LenToUnit[1]{\strip@pt\dimexpr#1*\p@/\unitlength}}{}} - +\renewcommand\LenToUnit[1]{\strip@pt\dimexpr#1*\p@/\unitlength}}{}}% \def\GetCoord(#1)#2#3{% \expandafter\SplitNod@\expandafter(#1)#2#3\ignorespaces} +\def\SplitNod@(#1)#2#3{\isnot@polar#1:!!(#1)#2#3}% \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 @@ -137,7 +156,7 @@ \ifdim\d@mX\p@=\z@ \else\ifdim\d@mY\p@=\z@ \else - \DividE\ifdim\@xnum\p@<\z@-\fi\p@ by\@xnum\p@ to\sc@lelen + \edef\sc@lelen{\fpeval{1 / abs(\@xnum)}}\relax \@linelen=\sc@lelen\@linelen \fi \fi @@ -157,13 +176,19 @@ \endgroup} \def\Vector(#1){{% \GetCoord(#1)\@tX\@tY -\ifdim\@tX\p@=\z@\vector(\@tX,\@tY){\@tY} +\ifdim\@tX\p@=\z@ + \vector(\@tX,\@tY){\@tY}% \else -\vector(\@tX,\@tY){\@tX}\fi}} + \vector(\@tX,\@tY){\@tX}% +\fi}} \def\VECTOR(#1)(#2){\begingroup \SubVect#1from#2to\@tempa \expandafter\put\expandafter(#1){\expandafter\Vector\expandafter(\@tempa)}% \endgroup\ignorespaces} +\def\VVECTOR(#1)(#2){{\SubVect#1from#2to\@tempb +\ScaleVect\@tempb by0.5to\@tempb +\AddVect\@tempb and#1to\@tempb +\VECTOR(\@tempb)(#2)\VECTOR(\@tempb)(#1)\ignorespaces}} \let\lp@r( \let\rp@r) \renewcommand*\polyline[1][\beveljoin]{\p@lylin@[#1]} @@ -197,6 +222,7 @@ \if@tempswa\pIIe@fillGraph\else\pIIe@strokeGraph\fi \endgroup \ignorespaces}} + \def\GraphGrid(#1,#2){\bgroup\textcolor{red}{\linethickness{.1\p@}% \RoundUp#1modulo10to\@GridWd \RoundUp#2modulo10to\@GridHt \@tempcnta=\@GridWd \divide\@tempcnta10\relax \advance\@tempcnta\@ne @@ -211,234 +237,65 @@ \ifnum\count252>0\advance\count252-#2\relax \advance\@tempcnta-\count252\fi\edef#3{\number\@tempcnta}\ignorespaces}% \def\Integer#1.#2??{#1}% -\ifdefined\dimexpr - \unless\ifdefined\DividE -\def\DividE#1by#2to#3{\bgroup -\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 - \edef\x{% - \noexpand\egroup\noexpand\def\noexpand#3{% - \strip@pt\dimexpr\@DimA*\Num/\Den\relax}}% -\fi -\x\ignorespaces}% -\fi - \unless\ifdefined\DivideFN - \def\DivideFN#1by#2to#3{\DividE#1\p@ by#2\p@ to{#3}}% - \fi - \unless\ifdefined\MultiplY - \def\MultiplY#1by#2to#3{\bgroup - \dimendef\@DimA 2254 \dimendef\@DimB2255 - \@DimA=#1\p@\relax \@DimB=#2\p@\relax - \edef\x{% - \noexpand\egroup\noexpand\def\noexpand#3{% - \strip@pt\dimexpr\@DimA*\@DimB/\p@\relax}}% - \x\ignorespaces}% - \let\MultiplyFN\MultiplY - \fi -\fi +\def\DividE#1by#2to#3{% + \edef#3{\fpeval{#1 / #2}}\relax +} +\let\DivideFN\DividE +\def\MultiplY#1by#2to#3{\edef#3{\fpeval{#1 * #2}}}\relax +\let\MultiplyFN\MultiplY \unless\ifdefined\Numero \def\Numero#1#2{\bgroup\dimen3254=#2\relax \edef\x{\noexpand\egroup\noexpand\edef\noexpand#1{% \strip@pt\dimen3254}}\x\ignorespaces}% \fi -\def\g@tTanCotanFrom#1to#2and#3{% -\DividE 114.591559\p@ by#1to\X@ \@tdB=\X@\p@ -\countdef\I=2546\def\Tan{0}\I=11\relax -\@whilenum\I>\z@\do{% - \@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\SinOf#1to#2{\bgroup% -\@tdA=#1\p@% -\ifdim\@tdA>\z@% - \@whiledim\@tdA>180\p@\do{\advance\@tdA -360\p@}% -\else% - \@whiledim\@tdA<-180\p@\do{\advance\@tdA 360\p@}% -\fi \ifdim\@tdA=\z@ - \def\@tempA{0}% -\else - \ifdim\@tdA>\z@ - \def\Segno{+}% - \else - \def\Segno{-}% - \@tdA=-\@tdA - \fi - \ifdim\@tdA>90\p@ - \@tdA=-\@tdA \advance\@tdA 180\p@ - \fi - \ifdim\@tdA=90\p@ - \def\@tempA{\Segno1}% +\def\SinOf#1to#2{\edef#2{\fpeval{round(sind#1,6)}}}\relax +\def\CosOf#1to#2{\edef#2{\fpeval{round(cosd#1,6)}}}\relax +\def\ArgOfVect#1to#2{\bgroup\GetCoord(#1){\t@X}{\t@Y}% +\def\s@gno{}% +\ifdim\t@X\p@=\z@ + \ifdim\t@Y\p@=\z@ + \def\ArcTan{0}% vettore nullo \else - \ifdim\@tdA=180\p@ - \def\@tempA{0}% - \else - \ifdim\@tdA<\p@ - \@tdA=\Segno0.0174533\@tdA - \DividE\@tdA by\p@ to \@tempA% - \else - \g@tTanCotanFrom\@tdA to\T and\Tp - \@tdA=\T\p@ \advance\@tdA \Tp\p@ - \DividE \Segno2\p@ by\@tdA to \@tempA% - \fi - \fi + \def\ArcTan{90}% vettore verticale + \ifdim\t@Y\p@<\z@\def\ArcTan{-90}\fi \fi -\fi -\edef\endSinOf{\noexpand\egroup - \noexpand\def\noexpand#2{\@tempA}\noexpand\ignorespaces}% -\endSinOf}% -\def\CosOf#1to#2{\bgroup% -\@tdA=#1\p@% -\ifdim\@tdA>\z@% - \@whiledim\@tdA>360\p@\do{\advance\@tdA -360\p@}% -\else% - \@whiledim\@tdA<\z@\do{\advance\@tdA 360\p@}% -\fi -\ifdim\@tdA>180\p@ - \@tdA=-\@tdA \advance\@tdA 360\p@ -\fi -\ifdim\@tdA<90\p@ - \def\Segno{+}% \else - \def\Segno{-}% - \@tdA=-\@tdA \advance\@tdA 180\p@ -\fi -\ifdim\@tdA=\z@ - \def\@tempA{\Segno1}% -\else - \ifdim\@tdA<\p@ - \@tdA=0.0174533\@tdA \Numero\@tempA\@tdA - \@tdA=\@tempA\@tdA \@tdA=-.5\@tdA - \advance\@tdA \p@ - \DividE\@tdA by\p@ to\@tempA% - \else - \ifdim\@tdA=90\p@ - \def\@tempA{0}% + \ifdim\t@Y\p@=\z@% vettore orizzontale + \ifdim\t@X\p@<\z@ + \def\ArcTan{180}% \else - \g@tTanCotanFrom\@tdA to\T and\Tp - \@tdA=\Tp\p@ \advance\@tdA-\T\p@ - \@tdB=\Tp\p@ \advance\@tdB\T\p@ - \DividE\Segno\@tdA by\@tdB to\@tempA% + \def\ArcTan{0}% \fi - \fi -\fi -\edef\endCosOf{\noexpand\egroup - \noexpand\def\noexpand#2{\@tempA}\noexpand\ignorespaces}% -\endCosOf}% -\def\TanOf#1to#2{\bgroup% -\@tdA=#1\p@% -\ifdim\@tdA>90\p@% - \@whiledim\@tdA>90\p@\do{\advance\@tdA -180\p@}% -\else% - \@whiledim\@tdA<-90\p@\do{\advance\@tdA 180\p@}% -\fi% -\ifdim\@tdA=\z@% - \def\@tempA{0}% -\else - \ifdim\@tdA>\z@ - \def\Segno{+}% - \else - \def\Segno{-}% - \@tdA=-\@tdA - \fi - \ifdim\@tdA=90\p@ - \def\@tempA{\Segno16383.99999}% - \else - \ifdim\@tdA<\p@ - \@tdA=\Segno0.0174533\@tdA - \DividE\@tdA by\p@ to\@tempA% - \else - \g@tTanCotanFrom\@tdA to\T and\Tp - \@tdA\Tp\p@ \advance\@tdA -\T\p@ - \DividE\Segno2\p@ by\@tdA to\@tempA% + \else % vettore qualsiasi + \edef\ArcTan{\fpeval{atand(\t@Y / \t@X)}}\relax + \ifdim\t@X\p@<\z@% vettore nei quadranti di sinistra + \ifdim\t@Y\p@<\z@ + \edef\ArcTan{\fpeval{\ArcTan - 180}}\relax + \else + \edef\ArcTan{\fpeval{\ArcTan + 180}}\relax + \fi \fi \fi \fi -\edef\endTanOf{\noexpand\egroup - \noexpand\def\noexpand#2{\@tempA}\noexpand\ignorespaces}% -\endTanOf}% -\def\ArcTanOf#1to#2{\bgroup -\countdef\Inverti 4444\Inverti=0 -\def\Segno{} -\edef\@tF{#1}\@tdF=\@tF\p@ \@tdE=57.295778\p@ -\@tdD=\ifdim\@tdF<\z@ -\@tdF\def\Segno{-}\else\@tdF\fi -\ifdim\@tdD>\p@ -\Inverti=\@ne -\@tdD=\dimexpr\p@*\p@/\@tdD\relax -\fi -\unless\ifdim\@tdD>0.02\p@ - \def\@tX{\strip@pt\dimexpr57.295778\@tdD\relax}% -\else - \edef\@tX{45}\relax - \countdef\I 2523 \I=9\relax - \@whilenum\I>0\do{\TanOf\@tX to\@tG - \edef\@tG{\strip@pt\dimexpr\@tG\p@-\@tdD\relax}\relax - \MultiplY\@tG by57.295778to\@tG - \CosOf\@tX to\@tH - \MultiplY\@tH by\@tH to\@tH - \MultiplY\@tH by\@tG to \@tH - \edef\@tX{\strip@pt\dimexpr\@tX\p@ - \@tH\p@\relax}\relax - \advance\I\m@ne}% -\fi -\ifnum\Inverti=\@ne -\edef\@tX{\strip@pt\dimexpr90\p@-\@tX\p@\relax} -\fi -\edef\x{\egroup\noexpand\edef\noexpand#2{\Segno\@tX}}\x\ignorespaces}% +\edef\x{\noexpand\egroup\noexpand\edef\noexpand#2{\ArcTan}}% +\x\ignorespaces} \def\MakeVectorFrom#1#2to#3{\edef#3{#1,#2}\ignorespaces}% \def\CopyVect#1to#2{\edef#2{#1}\ignorespaces}% \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=\z@ - \ifdim\@tempdimb=\z@ - \def\@T{0}\@tempdimc=\z@ - \else - \def\@T{0}\@tempdimc=\@tempdimb - \fi -\else - \ifdim\@tempdima>\@tempdimb - \DividE\@tempdimb by\@tempdima to\@T - \@tempdimc=\@tempdima - \else - \DividE\@tempdima by\@tempdimb to\@T - \@tempdimc=\@tempdimb - \fi -\fi -\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 +\edef#2{\fpeval{sqrt(\t@X*\t@X + \t@Y*\t@Y)}}\relax \ignorespaces}% \def\DirOfVect#1to#2{\GetCoord(#1)\t@X\t@Y \ModOfVect#1to\@tempa -\unless\ifdim\@tempdimc=\z@ - \DividE\t@X\p@ by\@tempdimc to\t@X - \DividE\t@Y\p@ by\@tempdimc to\t@Y +\unless\ifdim\@tempa\p@=\z@ + \DividE\t@X\p@ by\@tempa to\t@X + \DividE\t@Y\p@ by\@tempa to\t@Y \fi \MakeVectorFrom\t@X\t@Y to#2\ignorespaces}% \def\ModAndDirOfVect#1to#2and#3{% \GetCoord(#1)\t@X\t@Y \ModOfVect#1to#2% -\ifdim\@tempdimc=\z@\else - \DividE\t@X\p@ by\@tempdimc to\t@X - \DividE\t@Y\p@ by\@tempdimc to\t@Y -\fi -\MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% +\DirOfVect#1to#3\ignorespaces}% \def\DistanceAndDirOfVect#1minus#2to#3and#4{% \SubVect#2from#1to\@tempa \ModAndDirOfVect\@tempa to#3and#4\ignorespaces}% @@ -450,79 +307,37 @@ \CosOf#1to\t@X \SinOf#1to\t@Y \MakeVectorFrom\t@X\t@Y to#2\ignorespaces}% -\def\ArgOfVect#1to#2{\bgroup\GetCoord(#1){\t@X}{\t@Y}% -\def\s@gno{}\def\addflatt@ngle{0} -\ifdim\t@X\p@=\z@ - \ifdim\t@Y\p@=\z@ - \def\ArcTan{0}% - \else - \def\ArcTan{90}% - \ifdim\t@Y\p@<\z@\def\s@gno{-}\fi - \fi -\else - \ifdim\t@Y\p@=\z@ - \ifdim\t@X\p@<\z@ - \def\ArcTan{180}% - \else - \def\ArcTan{0}% - \fi - \else - \ifdim\t@X\p@<\z@% - \def\addflatt@ngle{180}% - \edef\t@X{\strip@pt\dimexpr-\t@X\p@}% - \edef\t@Y{\strip@pt\dimexpr-\t@Y\p@}% - \ifdim\t@Y\p@<\z@ - \def\s@gno{-}% - \edef\t@Y{-\t@Y}% - \fi - \fi - \DivideFN\t@Y by\t@X to \t@A - \ArcTanOf\t@A to\ArcTan - \fi -\fi -\edef\ArcTan{\unless\ifx\s@gno\empty\s@gno\fi\ArcTan}% -\unless\ifnum\addflatt@ngle=0\relax - \edef\ArcTan{% - \strip@pt\dimexpr\ArcTan\p@\ifx\s@gno\empty-\else+\fi - \addflatt@ngle\p@\relax}% -\fi -\edef\x{\noexpand\egroup\noexpand\edef\noexpand#2{\ArcTan}}% -\x\ignorespaces} \def\ScaleVect#1by#2to#3{\GetCoord(#1)\t@X\t@Y -\@tempdima=\t@X\p@ \@tempdima=#2\@tempdima\Numero\t@X\@tempdima -\@tempdima=\t@Y\p@ \@tempdima=#2\@tempdima\Numero\t@Y\@tempdima +\edef\t@X{\fpeval{#2 * \t@X}}\relax +\edef\t@Y{\fpeval{#2 * \t@Y}}\relax \MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% \def\ConjVect#1to#2{\GetCoord(#1)\t@X\t@Y -\@tempdima=-\t@Y\p@\Numero\t@Y\@tempdima +\edef\t@Y{-\t@Y}% \MakeVectorFrom\t@X\t@Y to#2\ignorespaces}% \def\AddVect#1and#2to#3{\GetCoord(#1)\tu@X\tu@Y \GetCoord(#2)\td@X\td@Y -\@tempdima\tu@X\p@\advance\@tempdima\td@X\p@ \Numero\t@X\@tempdima -\@tempdima\tu@Y\p@\advance\@tempdima\td@Y\p@ \Numero\t@Y\@tempdima +\edef\t@X{\fpeval{\tu@X + \td@X}}\relax +\edef\t@Y{\fpeval{\tu@Y + \td@Y}}\relax \MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% \def\SubVect#1from#2to#3{\GetCoord(#1)\tu@X\tu@Y \GetCoord(#2)\td@X\td@Y -\@tempdima\td@X\p@\advance\@tempdima-\tu@X\p@ \Numero\t@X\@tempdima -\@tempdima\td@Y\p@\advance\@tempdima-\tu@Y\p@ \Numero\t@Y\@tempdima +\edef\t@X{\fpeval{\td@X - \tu@X}}\relax +\edef\t@Y{\fpeval{\td@Y - \tu@Y}}\relax \MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% \def\MultVect#1by{\@ifstar{\@ConjMultVect#1by}{\@MultVect#1by}}% \def\@MultVect#1by#2to#3{\GetCoord(#1)\tu@X\tu@Y \GetCoord(#2)\td@X\td@Y -\@tempdima\tu@X\p@ \@tempdimb\tu@Y\p@ -\@tempdimc=\td@X\@tempdima\advance\@tempdimc-\td@Y\@tempdimb -\Numero\t@X\@tempdimc -\@tempdimc=\td@Y\@tempdima\advance\@tempdimc\td@X\@tempdimb -\Numero\t@Y\@tempdimc +\edef\t@X{\fpeval{\tu@X * \td@X - \tu@Y * \td@Y}}\relax +\edef\t@Y{\fpeval{\tu@Y * \td@X + \tu@X * \td@Y}}\relax \MakeVectorFrom\t@X\t@Y to#3\ignorespaces}% \def\@ConjMultVect#1by#2to#3{\GetCoord(#1)\tu@X\tu@Y -\GetCoord(#2)\td@X\td@Y \@tempdima\tu@X\p@ \@tempdimb\tu@Y\p@ -\@tempdimc=\td@X\@tempdima\advance\@tempdimc+\td@Y\@tempdimb -\Numero\t@X\@tempdimc -\@tempdimc=\td@X\@tempdimb\advance\@tempdimc-\td@Y\@tempdima -\Numero\t@Y\@tempdimc +\GetCoord(#2)\td@X\td@Y +\edef\t@X{\fpeval{\tu@X * \td@X + \tu@Y * \td@Y}}\relax +\edef\t@Y{\fpeval{\tu@Y * \td@X - \tu@X * \td@Y}}\relax \MakeVectorFrom\t@X\t@Y to#3\ignorespaces} \def\DivVect#1by#2to#3{\ModAndDirOfVect#2to\@Mod and\@Dir -\DividE\p@ by\@Mod\p@ to\@Mod \ConjVect\@Dir to\@Dir +\edef\@Mod{\fpeval{1 / \@Mod}}\relax +\ConjVect\@Dir to\@Dir \ScaleVect#1by\@Mod to\@tempa \MultVect\@tempa by\@Dir to#3\ignorespaces}% \def\Arc(#1)(#2)#3{\begingroup @@ -544,10 +359,10 @@ to the range 0--360 taking the sign into consideration}% \@whiledim\@tdA>360\p@\do{\advance\@tdA-360\p@}% \fi -\SubVect#2from#1to\@V \ModOfVect\@V to\@Raggio \CopyVect#2to\@pPun +\SubVect#2from#1to\@V \ModOfVect\@V to\@Raggio +\CopyVect#2to\@pPun \CopyVect#1to\@Cent \GetCoord(\@pPun)\@pPunX\@pPunY -\@@Arc -\strokepath\ignorespaces}% +\@@Arc\strokepath\ignorespaces}% \def\@@Arc{% \pIIe@moveto{\@pPunX\unitlength}{\@pPunY\unitlength}% \ifdim\@tdA>180\p@ @@ -555,7 +370,8 @@ \Numero\@gradi\@tdA \SubVect\@pPun from\@Cent to\@V \AddVect\@V and\@Cent to\@sPun - \MultVect\@V by0,-1.3333333to\@V \if\Segno-\ScaleVect\@V by-1to\@V\fi + \MultVect\@V by0,-1.3333333to\@V + \if\Segno-\ScaleVect\@V by-1to\@V\fi \AddVect\@pPun and\@V to\@pcPun \AddVect\@sPun and\@V to\@scPun \GetCoord(\@pcPun)\@pcPunX\@pcPunY @@ -697,8 +513,9 @@ \@@Arc \strokepath\ignorespaces}% \def\CurveBetween#1and#2WithDirs#3and#4{% -\StartCurveAt#1WithDir{#3}\relax -\CurveTo#2WithDir{#4}\CurveFinish\ignorespaces}% + \StartCurveAt#1WithDir{#3}\relax + \CurveTo#2WithDir{#4}\CurveFinish\ignorespaces +}% \def\StartCurveAt#1WithDir#2{% \begingroup \GetCoord(#1)\@tempa\@tempb @@ -737,6 +554,7 @@ \def\@isTension#1;#2!!{\def\@tempA{#1}% \def\@tempB{#2}\unless\ifx\@tempB\empty\strip@semicolon#2\fi} + \def\strip@semicolon#1;{\def\@tempB{#1}} \def\CurveTo#1WithDir#2{% \def\@Tuno{1}\def\@Tzero{1}\relax @@ -802,12 +620,13 @@ \ignorespaces}% \def\Curve{\@ifstar{\let\fillstroke\fillpath\Curve@}% {\let\fillstroke\strokepath\Curve@}} + \def\Curve@(#1)<#2>{% \StartCurveAt#1WithDir{#2}% \@ifnextchar\lp@r\@Curve{% \PackageWarning{curve2e}{% Curve specifications must contain at least two nodes!\Messagebreak - Please, control your Curve specifications\MessageBreak}}} + Please, control your \string\Curve\space specifications\MessageBreak}}} \def\@Curve(#1)<#2>{% \CurveTo#1WithDir{#2}% \@ifnextchar\lp@r\@Curve{% @@ -823,9 +642,11 @@ Quadratic curve specifications must contain at least two nodes!\Messagebreak Please, control your Qurve specifications\MessageBreak}}}% + \def\@Qurve(#1)<#2>{\QurveTo#1WithDir{#2}% \@ifnextchar\lp@r\@Qurve{% \@ifnextchar[\@ChangeQDir\CurveEnd}}% + \def\@ChangeQDir[#1]{\ChangeDir<#1>\@Qurve}% \def\QurveTo#1WithDir#2{% \edef\@Puno{#1}\DirOfVect#2to\@Duno\bgroup @@ -878,7 +699,6 @@ \pIIe@bezier@QtoC\@ovyy\@ovdy\@ovri \pIIe@bezier@QtoC\@xdim\@ovdx\@clnwd \pIIe@bezier@QtoC\@ydim\@ovdy\@clnht - \pIIe@moveto\@ovxx\@ovyy \pIIe@curveto\@ovro\@ovri\@clnwd\@clnht\@xdim\@ydim \fi\fi\egroup \CopyVect\@Puno to\@Pzero -- cgit v1.2.3