diff options
Diffstat (limited to 'graphics/pgf/base/tex/generic/math/pgfmathcalc.code.tex')
-rw-r--r-- | graphics/pgf/base/tex/generic/math/pgfmathcalc.code.tex | 537 |
1 files changed, 537 insertions, 0 deletions
diff --git a/graphics/pgf/base/tex/generic/math/pgfmathcalc.code.tex b/graphics/pgf/base/tex/generic/math/pgfmathcalc.code.tex new file mode 100644 index 0000000000..1e854864d8 --- /dev/null +++ b/graphics/pgf/base/tex/generic/math/pgfmathcalc.code.tex @@ -0,0 +1,537 @@ +% Copyright 2019 by Mark Wibrow +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +% This file loads all the parsing, functions and operator stuff +% +% Version 1.414213 29/9/2007 + +% \pgfmathsetlength, \pgfmathaddtolength +% +% #1 = dimension register +% #2 = expression +% +% Description: +% +% These functions work similar to \setlength and \addtolength. Only, +% they allow #2 to contain an expression, which is evaluated before +% assignment. Furthermore, the font is setup before the assignment is +% done, so that dimensions like 1em are evaluated correctly. +% +% If #2 starts with "+", then a simple assignment is done (but the +% font is still setup). This is orders of magnitude faster than a +% parsed assignment. + +\def\pgfmathsetlength#1#2{% + \expandafter\pgfmath@onquick#2\pgfmath@% + {% + % Ok, quick version: + \begingroup% + \pgfmath@selectfont% + #1#2\unskip% + \expandafter\endgroup% + \expandafter#1\the#1\relax% + }% + {% + \pgfmathparse{#2}% + \ifpgfmathmathunitsdeclared% + #1\pgfmathresult mu\relax% + \else% + #1\pgfmathresult pt\relax% + \fi% + }% + \ignorespaces% +} + +% \pgfmathaddtolength +% +% Add to #1 the result of evaluating #2. +% +% #1 - a dimension register +% #2 - an expression +% +\def\pgfmathaddtolength#1#2{% + \expandafter\pgfmath@onquick#2\pgfmath@% + {% + \begingroup% + \pgfmath@selectfont% + \advance#1#2\unskip% + \expandafter% + \endgroup% + \expandafter#1\the#1\relax% + }% + {% + \pgfmathparse{#2}% + \ifpgfmathmathunitsdeclared% + \advance#1\pgfmathresult mu\relax% + \else% + \advance#1\pgfmathresult pt\relax% + \fi% + }% + \ignorespaces% +} + +% \pgfmathsetcount +% +% Assign #1 the truncated evaluation of #2. +% +% #1 - a count register +% #2 - an expression +% +\def\pgfmathsetcount#1#2{% + \expandafter\pgfmath@onquick#2\pgfmath@% + {% + \afterassignment\pgfmath@gobbletilpgfmath@% + #1#2\relax\pgfmath@% + }% + {% + \pgfmathparse{#2}% + \afterassignment\pgfmath@gobbletilpgfmath@% + #1\pgfmathresult\relax\pgfmath@% + }% + \ignorespaces% +} + +% \pgfmathaddtocount +% +% Add to #1 the truncated evaluation of #2. +% +% #1 - a count register +% #2 - an expression +% +\def\pgfmathaddtocount#1#2{% + \expandafter\pgfmath@onquick#2\pgfmath@% + {% + \edef\pgfmath@addtocounttemp{\the#1}% + \afterassignment\pgfmath@gobbletilpgfmath@% + #1#2\relax\pgfmath@% + \advance#1\pgfmath@addtocounttemp\relax% + }% + {% + \edef\pgfmath@addtocounttemp{\the#1}% + \pgfmathparse{#2}% + \afterassignment\pgfmath@gobbletilpgfmath@% + #1\pgfmathresult\relax\pgfmath@% + \advance#1\pgfmath@addtocounttemp\relax% + }% + \ignorespaces% +} + +% \pgfmathnewcounter +% +% LaTeX style counter which also works in plain TeX. Defines +% \c@<name> as a count register and also defines \the<name>. +% +% #1 the name of the counter. +% +% Example: +% +% \pgfmathnewcounter{counter} +% \pgfmathsetcounter{counter}{12} +% \thecounter (same as \the\c@counter) +% +\def\pgfmathnewcounter#1{% + \expandafter\ifx\csname c@#1\endcsname\relax% + \def\pgfmath@marshal{\csname newcount\endcsname}% Ha! Who cares about \outer? + \expandafter\pgfmath@marshal\csname c@#1\endcsname% + \expandafter\def\csname the#1\endcsname{\expandafter\the\csname c@#1\endcsname}% + \fi% +} + +% \pgfmathsetcounter +% +% Set the counter #1 to the evaluation of #2. +% +% #1 - a counter name +% #2 - an expression +% +\def\pgfmathsetcounter#1#2{% + \expandafter\pgfmathsetcount\csname c@#1\endcsname{#2}% +} + +% \pgfmathaddtocounter +% +% Add the counter #1 to the evaluation of #2. +% +% #1 - a counter name +% #2 - an expression +% +\def\pgfmathaddtocounter#1#2{% + \expandafter\pgfmathaddtocount\csname c@#1\endcsname{#2}% +} + +% \pgfmathmakecounterglobal +% +% Make the current value of a counter globally defined. +% +% #1 - a (valid) counter name. +% +\def\pgfmath@pgftext{pgf} +\def\pgfmath@tikztext{tikz} +\def\pgfmathmakecounterglobal#1{% + \pgfmath@ifundefined{c@#1}{}{% + \expandafter\pgfmath@in@\expandafter{\pgfmath@pgftext}{#1}% + \ifpgfmath@in@% + \else% + \expandafter\pgfmath@in@\expandafter{\pgfmath@tikztext}{#1}% + \ifpgfmath@in@% + \else% + \expandafter\global\csname c@#1\endcsname\csname c@#1\endcsname\relax% + \fi% + \fi% + }% +} + +% \pgfmathsetmacro +% +% \edef#1 as the result of evaluating #2. +% +% #1 - a macro +% #2 - an expression +% +\def\pgfmathsetmacro#1#2{% + \begingroup% + \pgfmathparse{#2}% + \let#1=\pgfmathresult + \pgfmath@smuggleone{#1}% + \endgroup% +} + +% \pgfmathsetlengthmacro +% +% \edef#1 as the result of evaluating #2 with pt. +% +% #1 - a macro +% #2 - an expression +% +\def\pgfmathsetlengthmacro#1#2{% + \begingroup% + \pgfmathsetlength\pgfmath@x{#2}% + \edef#1{\the\pgfmath@x}% + \pgfmath@smuggleone{#1}% + \endgroup% +} + +% \pgfmathtruncatemacro +% +% \edef#1 as the truncated result of evaluating #2. +% +% #1 - a macro +% #2 - an expression +% +\def\pgfmathtruncatemacro#1#2{% + \begingroup% + \pgfmathsetcount\c@pgfmath@counta{#2}% + \edef#1{\the\c@pgfmath@counta}% + \pgfmath@smuggleone{#1}% + \endgroup% +} + +% Check whether a given parameter starts with quick. +% +% The command should be followed by nonempty text, ending with +% \pgfmath@ as a stop-token. Then should follow +% +% #1 - code to execute if text starts with + +% #2 - code to execute if text does not +% +% Example: +% +% \pgfmath@onquick+0pt\pgfmath@{is quick}{is slow} + +\def\pgfmath@onquick{% + \futurelet\pgfmath@next% + \pgfmath@@onquick} +\def\pgfmath@@onquick#1\pgfmath@{% + \ifx\pgfmath@next+% + \let\pgfmath@next=\pgfmath@firstoftwo% + \else% + \let\pgfmath@next=\pgfmath@secondoftwo% + \fi% + \pgfmath@next% +} + +% *** The following commands DO NOT WORK without the rest of PGF *** +% +% (a dumping ground for stuff that doesn't really belong anywhere else) + +% \pgfmathanglebetweenpoints +% +% Define \pgfmathresult as the angle between points #1 and #2 +% Should get the quadrants right as well. +% +\def\pgfmathanglebetweenpoints#1#2{% + \begingroup% + \pgf@process{\pgfpointdiff{#1}{#2}}% + \edef\pgf@marshall{\expandafter\noexpand\csname pgfmathatan2@\endcsname{\expandafter\Pgf@geT\the\pgf@y}{\expandafter\Pgf@geT\the\pgf@x}}% + \pgf@marshall% + \ifdim\pgfmathresult pt<0pt% + \pgfmathparse{\pgfmathresult+360}% + \fi% + \expandafter% + \endgroup\expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult}% +} + +% +% \pgfmathrotatepointaround +% +% Rotate point #1 about point #2 by #3 degrees. +% +\def\pgfmathrotatepointaround#1#2#3{% + \pgf@process{% + \pgf@process{#1}% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \pgf@process{#2}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgf@xb\pgf@x% + \pgf@yb\pgf@y% + \pgf@x=\pgf@xc% + \pgf@y=\pgf@yc% + \advance\pgf@x-\pgf@xa% + \advance\pgf@y-\pgf@ya% + \pgfmathsetmacro\angle{#3}% + \pgfmathsin@{\angle}% + \let\sineangle\pgfmathresult% + \pgfmathcos@{\angle}% + \let\cosineangle\pgfmathresult% + \pgf@xa\cosineangle\pgf@x% + \advance\pgf@xa-\sineangle\pgf@y% + \pgf@ya\sineangle\pgf@x% + \advance\pgf@ya\cosineangle\pgf@y% + \pgf@x\pgf@xb% + \pgf@y\pgf@yb% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% +} + +% \pgfmathanglebetweenlines +% +% Calculate the clockwise angle between a line from point #1 +% to point #2 and a line from #3 to point #4. +% +\def\pgfmathanglebetweenlines#1#2#3#4{% + \begingroup% + \pgfmathanglebetweenpoints{#1}{#2}% + \let\firstangle\pgfmathresult% + \pgfmathanglebetweenpoints{#3}{#4}% + \let\secondangle\pgfmathresult% + \ifdim\firstangle pt>\secondangle pt\relax% + \pgfmathadd@{\secondangle}{360}% + \let\secondangle\pgfmathresult% + \fi% + \pgfmathsubtract@{\secondangle}{\firstangle}% + \pgfmath@smuggleone\pgfmathresult% + \endgroup% +} + +% \pgfmathpointreflectalongaxis +% +% Reflects point #1 around an axis centered on #2 at an angle #3. +% +\def\pgfmathreflectpointalongaxis#1#2#3{% + \pgf@process{% + \pgfmathanglebetweenpoints{#2}{#1}% + \pgfmath@tempdima\pgfmathresult pt\relax% + \pgfmathparse{#3}% + \advance\pgfmath@tempdima-\pgfmathresult pt\relax% + \pgfmath@tempdima-2.0\pgfmath@tempdima% + \pgfmathrotatepointaround{#1}{#2}{\pgfmath@tonumber{\pgfmath@tempdima}}% + }% +} + + + +% \pgfmathpointintersectionoflineandarc +% +% A bit experimental at the moment: +% +% Locates the point where a line crosses an eliptical arc. If the line +% does not cross the arc, a meaningless point will result. +% +% #1 the point of the line on the "convex" side of the arc. +% #2 the point of the line on the "concave" side of the arc. +% #3 the center of the eliptical arc. +% #4 start angle of the arc. +% #5 end angle of the arc. +% #6 radii of the arc. +% +\def\pgfmathpointintersectionoflineandarc#1#2#3#4#5#6{% + \pgf@process{% + % + % Get the required angle. + % + \pgfmathanglebetweenpoints{#2}{#1}% + \let\x\pgfmathresult% + % + % Get the radii of the arc. + % + \pgfmath@in@{and }{#6}% + \ifpgfmath@in@% + \pgf@polar@#6\@@% + \else% + \pgf@polar@#6 and #6\@@% + \fi% + \edef\xarcradius{\the\pgf@x}% + \edef\yarcradius{\the\pgf@y}% + % + % Get the start and end angles of the arc... + % + \pgfmathsetmacro\s{#4}% + \pgfmathsetmacro\e{#5}% + % + % ...and also with rounding. + % + \pgfmathmod@{\s}{360}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\ss\pgfmathresult% + \pgfmathmod@{\e}{360}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\ee\pgfmathresult% + % + % Hackery for when arc straddles zero. + % + \ifdim\ee pt<\ss pt\relax% + \pgfmathadd@{\x}{180}% + \pgfmathmod@{\pgfmathresult}{360}% + \let\x\pgfmathresult% + \fi% + \def\m{360}% Measure of nearness. + \pgfmathadd@{\s}{\e}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\n\pgfmathresult% The best estimate (default to middle of arc). + \pgfmathloop% + \pgfmathadd@{\s}{\e}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\p\pgfmathresult% + \ifdim\p pt=\s pt\relax% + \else% + \pgfmathanglebetweenpoints{#2}{% + \pgfpointadd{#3}{% + \pgf@x\xarcradius\relax% + \pgfmathcos@{\p}% + \pgf@x\pgfmathresult\pgf@x% + \pgf@y\yarcradius\relax% + \pgfmathsin@{\p}% + \pgf@y\pgfmathresult\pgf@y% + }% + }% + % + % Hackery for when arc straddles zero. + % + \ifdim\ee pt<\ss pt\relax% + \pgfmathadd@{\pgfmathresult}{180}% + \pgfmathmod@{\pgfmathresult}{360}% + \fi% + \let\q\pgfmathresult% + % + % More hackery... + % + \ifdim\x pt>335pt\relax% + \ifdim\q pt<45pt\relax% + \pgfmathadd@{\q}{360}% + \let\q\pgfmathresult% + \fi% + \fi% + \ifdim\x pt=\q pt% Found it! + \pgfmathbreakloop% Breaks after current iteration is complete. + \else + \ifdim\x pt<\q pt\relax% + \let\e\p% + \else% + \let\s\p% + \fi% + \fi% + \pgfmathsubtract@{\x}{\q}% + \pgfmathabs@{\pgfmathresult}% + % + % Save the estimate if it is better than any previous estimate. + % + \ifdim\pgfmathresult pt<\m pt\relax% + \let\m\pgfmathresult% + \let\n\p% + \fi% + \repeatpgfmathloop% + \pgfpointadd{#3}{\pgfpointpolar{\n}{\xarcradius and \yarcradius}}% + }% +} + +% \pgfmathangleonellipse +% +% Find the angle corresponding to a point on the border of an ellispe. +% +% #1 - the point on the border. +% #2 - the radii of the ellipse. +% +\def\pgfmathangleonellipse#1#2{% + \begingroup% + \pgfmath@in@{and }{#2}% + \ifpgfmath@in@% + \pgf@polar@#2\@@% + \else% + \pgf@polar@#2 and #2\@@% + \fi% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgf@process{#1}% + \ifdim\pgf@x=0pt\relax% + \pgfutil@tempdima1pt\relax% + \else% + \pgfutil@tempdima\pgf@x% + \pgfmathdivide@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgfutil@tempdima}}% + \pgfutil@tempdima\pgfmathresult pt\relax% + \fi% + \ifdim\pgf@y=0pt\relax% + \pgfutil@tempdima1pt\relax% + \else% + \pgfmathdivide@{\pgfmath@tonumber{\pgf@y}}{\pgfmath@tonumber{\pgf@ya}}% + \pgfutil@tempdima\pgfmathresult\pgfutil@tempdima% + \pgfmathatan@{\pgfmath@tonumber{\pgfutil@tempdima}}% + \fi% + % + \pgfutil@tempdima\pgfmathresult pt\relax% + \ifdim\pgfutil@tempdima<0pt\relax% + \advance\pgfutil@tempdima360pt\relax% + \fi% + \ifdim\pgf@x<0pt\relax% + \ifdim\pgf@y=0pt\relax% + \pgfutil@tempdima180pt\relax% + \else% + \ifdim\pgf@y<0pt\relax% + \advance\pgfutil@tempdima180pt\relax% + \else% + \advance\pgfutil@tempdima-180pt\relax% + \fi% + \fi% + \else% + \ifdim\pgf@x=0pt\relax% + \ifdim\pgf@y<0pt\relax% + \pgfutil@tempdima270pt\relax% + \else% + \pgfutil@tempdima90pt\relax% + \fi% + \else% + \ifdim\pgf@y=0pt\relax% + \pgfutil@tempdima0pt\relax% + \fi% + \fi% + \fi% + \pgfmath@returnone\pgfutil@tempdima% + \endgroup% +} + + +% Local Variables: +% tab-width: 2 +% End: |