diff options
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex')
-rw-r--r-- | Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex | 822 |
1 files changed, 822 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex new file mode 100644 index 00000000000..26e63666e02 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex @@ -0,0 +1,822 @@ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepoints.code.tex,v 1.1.1.1 2005/06/29 12:14:04 tantau Exp $ + +% Copyright 2005 by Till Tantau <tantau@cs.tu-berlin.de>. +% +% This program can be redistributed and/or modified under the terms +% of the GNU Public License, version 2. + +\newdimen\pgf@picminx +\newdimen\pgf@picmaxx +\newdimen\pgf@picminy +\newdimen\pgf@picmaxy + +\newdimen\pgf@pathminx +\newdimen\pgf@pathmaxx +\newdimen\pgf@pathminy +\newdimen\pgf@pathmaxy + +\newif\ifpgf@relevantforpicturesize + +\def\pgf@process#1{{#1\global\pgf@x=\pgf@x\global\pgf@y=\pgf@y}} + +\newdimen\pgf@tempdim +\def\pgf@setlength#1#2{% these will be used only when \nullfont is active + \begingroup% keep font setting local + \pgf@selectfontorig% restore font + \pgf@setlengthorig\pgf@tempdim{#2}% calculate dimension (possibly using calc) + \global\pgf@tempdim\pgf@tempdim% make dimension global + \endgroup% + #1=\pgf@tempdim\relax} +\def\pgf@addtolength#1#2{% + \begingroup% keep font setting local + \pgf@selectfontorig% restore font + \pgf@tempdim#1\relax% + \pgf@addtolengthorig\pgf@tempdim{#2}% calculate dimension (possibly using calc) + \global\pgf@tempdim\pgf@tempdim% make dimension global + \endgroup% + #1=\pgf@tempdim\relax} +\newcounter{pgf@tempcount} +\def\pgf@setcounter#1#2{% + \setcounter{pgf@tempcount}{#2}% makes change global! + \csname c@#1\endcsname=\c@pgf@tempcount\relax} +\def\pgf@selectfont{\pgf@selectfontorig\nullfont} + + + +% Return a point +% +% #1 = x-coordinate of the point +% #2 = y-coordinate of the point +% +% x = #1 +% y = #2 +% +% Example: +% +% \pgfpathmoveto{\pgfpoint{2pt}{3cm}} + +\def\pgfpoint#1#2{% + \setlength\pgf@x{#1}% + \setlength\pgf@y{#2}\ignorespaces} + +% Return the origin. +% +% x = 0 +% y = 0 +% +% Example: +% +% \pgfpathmoveto{\pgfpointorigin} + +\def\pgfpointorigin{\pgfpoint{0pt}{0pt}\ignorespaces} + + + +% Return a transformed point +% +% #1 = a point +% +% Description: +% +% This command applies pgf's current transformation matrix to the +% given point. Normally, this is done automatically by commands like +% lineto or moveto, but sometimes you may wish to access a transformed +% point yourself. For example, this command is useful for a low level +% coordinate system shift: +% +% Example: +% +% \begin{pgflowleveltransformshiftscope}{\pgfpointtransformed{\pgfpointorigin}} +% \pgfbox[center,center]{Hi!} +% \end{pgflowleveltransformshiftscope} + +\def\pgfpointtransformed#1{% + \pgf@process{% + #1% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + }% +} + + +% Return the difference vector of two points. +% +% #1 = start of vector +% #2 = end of vector +% +% x = x-component of difference +% y = y-component of difference +% +% Example: +% +% \pgfpathmoveto{\pgfpointdiff{\pgfpointxy{1}{1}}{\pgfpointxy{2}{3}}} + +\def\pgfpointdiff#1#2{% + \pgf@process{#1}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{#2}% + \advance\pgf@x by-\pgf@xa\relax% + \advance\pgf@y by-\pgf@ya\relax\ignorespaces} + +% Add two vectors. +% +% #1 = first vector +% #2 = second vector +% +% x = x-component of addition +% y = y-component of addition +% +% Example: +% +% \pgfpathmoveto{\pgfpointadd{\pgfpointxy{0}{1}}{\pgfpointxy{2}{3}}} + +\def\pgfpointadd#1#2{% + \pgf@process{#1}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{#2}% + \advance\pgf@x by\pgf@xa% + \advance\pgf@y by\pgf@ya} + + + +% Multiply a vector by a factor. +% +% #1 = factor +% #2 = vector +% +% Example: +% +% \pgfpointscale{2}{\pgfpointxy{0}{1}} + +\def\pgfpointscale#1#2{% + \pgf@process{#2}% + \pgf@x=#1\pgf@x% + \pgf@y=#1\pgf@y% +} + + +% The intersection of two lines +% +% #1 = point on first line +% #2 = another point on first line +% #3 = point on second line +% #4 = another point on second line +% +% Returns the intersection of the two lines. If there is no +% intersection or if the points #1 and #2 or the points #3 and #4 are +% identical, the behaviour is not specified. +% +% Example: +% +% \pgfpointintersectionoflines{\pgfpointxy{0}{1}}{\pgfpointxy{1}{0}}{\pgfpointxy{2}{2}}{\pgfpointxy{3}{4}} + +\def\pgfpointintersectionoflines#1#2#3#4{% + { + % + % Compute orthogonal vector to #1--#2 + % + \pgf@process{#2}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{#1}% + \advance\pgf@xa by-\pgf@x% + \advance\pgf@ya by-\pgf@y% + \pgf@ya=-\pgf@ya% + % Normalise a bit + \c@pgf@counta=\pgf@xa% + \ifnum\c@pgf@counta<0\relax% + \c@pgf@counta=-\c@pgf@counta\relax% + \fi% + \c@pgf@countb=\pgf@ya% + \ifnum\c@pgf@countb<0\relax% + \c@pgf@countb=-\c@pgf@countb\relax% + \fi% + \advance\c@pgf@counta by\c@pgf@countb\relax% + \divide\c@pgf@counta by 65536\relax% + \ifnum\c@pgf@counta>0\relax% + \divide\pgf@xa by\c@pgf@counta\relax% + \divide\pgf@ya by\c@pgf@counta\relax% + \fi% + % + % Compute projection + % + \pgf@xc=\pgf@sys@tonumber{\pgf@ya}\pgf@x% + \advance\pgf@xc by\pgf@sys@tonumber{\pgf@xa}\pgf@y% + % + % The orthogonal vector is (\pgf@ya,\pgf@xa) + % + % + % Compute orthogonal vector to #3--#4 + % + \pgf@process{#4}% + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + \pgf@process{#3}% + \advance\pgf@xb by-\pgf@x% + \advance\pgf@yb by-\pgf@y% + \pgf@yb=-\pgf@yb% + % Normalise a bit + \c@pgf@counta=\pgf@xb% + \ifnum\c@pgf@counta<0\relax% + \c@pgf@counta=-\c@pgf@counta\relax% + \fi% + \c@pgf@countb=\pgf@yb% + \ifnum\c@pgf@countb<0\relax% + \c@pgf@countb=-\c@pgf@countb\relax% + \fi% + \advance\c@pgf@counta by\c@pgf@countb\relax% + \divide\c@pgf@counta by 65536\relax% + \ifnum\c@pgf@counta>0\relax% + \divide\pgf@xb by\c@pgf@counta\relax% + \divide\pgf@yb by\c@pgf@counta\relax% + \fi% + % + % Compute projection + % + \pgf@yc=\pgf@sys@tonumber{\pgf@yb}\pgf@x% + \advance\pgf@yc by\pgf@sys@tonumber{\pgf@xb}\pgf@y% + % + % The orthogonal vector is (\pgf@yb,\pgf@xb) + % + % Setup transformation matrx (this is just to use the matrix + % inversion) + % + \pgfsettransform{{\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@yb}{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@xb}{0pt}{0pt}}% + \pgftransforminvert% + \pgf@process{\pgfpointtransformed{\pgfpoint{\pgf@xc}{\pgf@yc}}}% + }% +} + + +% Returns point on a line from #2 to #3 at time #1. +% +% #1 = a time, where 0 is the start and 1 is the end +% #2 = start point +% #3 = end point +% +% x = x-component of #1*start + (1-#1)*end +% y = y-component of #1*start + (1-#1)*end +% +% Example: +% +% % Middle of (1,1) and (2,3) +% \pgfpathmoveto{\pgfpointlineattime{0.5}{\pgfpointxy{0}{1}}{\pgfpointxy{2}{3}}} + +\def\pgfpointlineattime#1#2#3{% + \pgf@process{#3}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{#2}% + \advance\pgf@xa by-\pgf@x\relax% + \advance\pgf@ya by-\pgf@y\relax% + \advance\pgf@x by #1\pgf@xa\relax% + \advance\pgf@y by #1\pgf@ya\relax% + \ignorespaces} + + +% Move point #2 #1 many units in the direction of #3. +% +% #1 = a distance +% #2 = start point +% #3 = end point +% +% x = x-component of start + #1*(normalise(end-start)) +% y = y-component of start + #1*(normalise(end-start)) +% +% Example: +% +% +% \pgfpathmoveto{\pgfpointlineatdistance{2pt}{\pgfpointxy{0}{1}}{\pgfpointxy{2}{3}}} +% \pgfpathlineto{\pgfpointlineatdistance{3pt}{\pgfpointxy{2}{3}}{\pgfpointxy{0}{1}}} + +\def\pgfpointlineatdistance#1#2#3{% + \pgf@process{#2}% + \pgf@xb=\pgf@x\relax% xb/yb = start point + \pgf@yb=\pgf@y\relax% + \pgf@process{#3}% + \advance\pgf@x by-\pgf@xb\relax% + \advance\pgf@y by-\pgf@yb\relax% + \pgf@process{\pgfpointnormalised{}}% x/y = normalised vector + \setlength\pgf@xa{#1}% + \pgf@ya=\pgf@xa\relax% + \pgf@xa=\pgf@sys@tonumber{\pgf@x}\pgf@xa% + \pgf@ya=\pgf@sys@tonumber{\pgf@y}\pgf@ya% + \pgf@x=\pgf@xb\relax% + \pgf@y=\pgf@yb\relax% + \advance\pgf@x by\pgf@xa\relax% + \advance\pgf@y by\pgf@ya\relax% + \ignorespaces} + + +% Returns point on a curve from #2 to #5 with controls #3 and #4 at time #1. +% +% #1 = a time +% #2 = start point +% #3 = first control point +% #4 = second control point +% #5 = end point +% +% x = x-component of place on the curve at time t +% y = y-component of place on the curve at time t +% +% Additionally, (\pgf@xa,\pgf@ya) and (\pgf@xb,\pgf@yb) will be on a +% tangent to the point on the curve (this can be useful for computing +% a label rotation). +% +% Example: +% +% % Middle of (1,1) and (2,3) +% \pgfpathmoveto{\pgfpointcurveattime{0.5}{\pgfpointxy{0}{1}}{\pgfpointxy{1}{1}}{\pgfpointxy{1}{1}}{\pgfpointxy{2}{3}}} + +\def\pgfpointcurveattime#1#2#3#4#5{% + \def\pgf@time@s{#1}% + \pgf@x=#1pt% + \pgf@x=-\pgf@x% + \advance\pgf@x by 1pt% + \edef\pgf@time@t{\pgf@sys@tonumber{\pgf@x}}% + \pgf@process{#5}% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \pgf@process{#4}% + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + \pgf@process{#3}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{#2}% + % First iteration: + \pgf@x=\pgf@time@t\pgf@x\advance\pgf@x by\pgf@time@s\pgf@xa% + \pgf@y=\pgf@time@t\pgf@y\advance\pgf@y by\pgf@time@s\pgf@ya% + \pgf@xa=\pgf@time@t\pgf@xa\advance\pgf@xa by\pgf@time@s\pgf@xb% + \pgf@ya=\pgf@time@t\pgf@ya\advance\pgf@ya by\pgf@time@s\pgf@yb% + \pgf@xb=\pgf@time@t\pgf@xb\advance\pgf@xb by\pgf@time@s\pgf@xc% + \pgf@yb=\pgf@time@t\pgf@yb\advance\pgf@yb by\pgf@time@s\pgf@yc% + % Second iteration: + \pgf@x=\pgf@time@t\pgf@x\advance\pgf@x by\pgf@time@s\pgf@xa% + \pgf@y=\pgf@time@t\pgf@y\advance\pgf@y by\pgf@time@s\pgf@ya% + \pgf@xa=\pgf@time@t\pgf@xa\advance\pgf@xa by\pgf@time@s\pgf@xb% + \pgf@ya=\pgf@time@t\pgf@ya\advance\pgf@ya by\pgf@time@s\pgf@yb% + % Save x/y + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + % Third iteration: + \pgf@x=\pgf@time@t\pgf@x\advance\pgf@x by\pgf@time@s\pgf@xa% + \pgf@y=\pgf@time@t\pgf@y\advance\pgf@y by\pgf@time@s\pgf@ya% +} + + + + + + +% Internal registers +\newdimen\pgf@xx +\newdimen\pgf@xy +\newdimen\pgf@yx +\newdimen\pgf@yy +\newdimen\pgf@zx +\newdimen\pgf@zy + + + +% Store a value in polar-coordinates +% +% #1 = a degree +% #2 = a radius +% +% x = #2 * cos(#1) +% y = #2 * sin(#2) +% +% Example: +% +% % Create a slanted rectangle +% +% \pgfpathmoveto{\pgfpointpolar{30}{1cm}} + +\def\pgfpointpolar#1#2{% + \pgfsincos{#1}% + \in@/{#2}% + \ifin@% + \pgf@polar@#2\@@% + \else% + \pgf@polar@#2/#2\@@% + \fi% + \pgf@xa=\pgf@sys@tonumber{\pgf@x}\pgf@xa% + \pgf@ya=\pgf@sys@tonumber{\pgf@y}\pgf@ya% + \pgf@y=\pgf@xa\relax% + \pgf@x=\pgf@ya\ignorespaces} + +\def\pgf@polar@#1/#2\@@{% + \setlength{\pgf@xa}{#2}% + \setlength{\pgf@ya}{#1}% +} + + + +% Store the vector #1 * x-vec + #2 * y-vec +% +% #1 = a factor for the x-vector +% #2 = a factor fot the y-vector +% +% x = x-component of result vector +% y = y-component of result vector +% +% Description: +% +% This command can be used to create a new coordinate system +% without using the rotate/translate/scale commands. This +% may be useful, if you do not want arrows and line width to +% be scaled/transformed together with the coordinate system. +% +% Example: +% +% % Create a slanted rectangle +% +% \pgfsetxvec{\pgfpoint{1cm}{1cm}} +% \pgfsetyvec{\pgfpoint{0cm}{1cm}} +% +% \pgfpathmoveto{\pgfpointxy{0}{0}} +% \pgfpathlineto{\pgfpointxy{1}{0}} +% \pgfpathlineto{\pgfpointxy{1}{1}} +% \pgfpathlineto{\pgfpointxy{0}{1}} +% \pgfclosestroke + +\def\pgfpointxy#1#2{\pgf@x=#1\pgf@xx% + \advance\pgf@x by #2\pgf@yx% + \pgf@y=#1\pgf@xy% + \advance\pgf@y by #2\pgf@yy} + + +% Store the vector #1 * x-vec + #2 * y-vec + #3 * z-vec +% +% #1 = a factor for the x-vector +% #2 = a factor fot the y-vector +% #3 = a factor fot the z-vector +% +% x = x-component of result vector +% y = y-component of result vector +% +% +% Description: +% +% This command allows you to use a 3d coordinate system. +% +% +% Example: +% +% % Draw a cubus +% +% \pgfline{\pgfpointxyz{0}{0}{0}}{\pgfpointxyz{0}{0}{1}} +% \pgfline{\pgfpointxyz{0}{1}{0}}{\pgfpointxyz{0}{1}{1}} +% \pgfline{\pgfpointxyz{1}{0}{0}}{\pgfpointxyz{1}{0}{1}} +% \pgfline{\pgfpointxyz{1}{1}{0}}{\pgfpointxyz{1}{1}{1}} +% \pgfline{\pgfpointxyz{0}{0}{0}}{\pgfpointxyz{0}{1}{0}} +% \pgfline{\pgfpointxyz{0}{0}{1}}{\pgfpointxyz{0}{1}{1}} +% \pgfline{\pgfpointxyz{1}{0}{0}}{\pgfpointxyz{1}{1}{0}} +% \pgfline{\pgfpointxyz{1}{0}{1}}{\pgfpointxyz{1}{1}{1}} +% \pgfline{\pgfpointxyz{0}{0}{0}}{\pgfpointxyz{1}{0}{0}} +% \pgfline{\pgfpointxyz{0}{0}{1}}{\pgfpointxyz{1}{0}{1}} +% \pgfline{\pgfpointxyz{0}{1}{0}}{\pgfpointxyz{1}{1}{0}} +% \pgfline{\pgfpointxyz{0}{1}{1}}{\pgfpointxyz{1}{1}{1}} + +\def\pgfpointxyz#1#2#3{% + \pgf@x=#1\pgf@xx% + \advance\pgf@x by #2\pgf@yx% + \advance\pgf@x by #3\pgf@zx% + \pgf@y=#1\pgf@xy% + \advance\pgf@y by #2\pgf@yy% + \advance\pgf@y by #3\pgf@zy} + + + + +% Set the x-vector +% +% #1 = a point the is the new x-vector +% +% Example: +% +% \pgfsetxvec{\pgfpoint{1cm}{0cm}} + +\def\pgfsetxvec#1{% + \pgf@process{#1}% + \pgf@xx=\pgf@x% + \pgf@xy=\pgf@y% + \ignorespaces} + + +% Set the y-vector +% +% #1 = a point the is the new y-vector +% +% Example: +% +% \pgfsetyvec{\pgfpoint{0cm}{1cm}} + +\def\pgfsetyvec#1{% + \pgf@process{#1}% + \pgf@yx=\pgf@x% + \pgf@yy=\pgf@y% + \ignorespaces} + + +% Set the z-vector +% +% #1 = a point the is the new z-vector +% +% Example: +% +% \pgfsetzvec{\pgfpoint{-0.385cm}{-0.385cm}} + +\def\pgfsetzvec#1{% + \pgf@process{#1}% + \pgf@zx=\pgf@x% + \pgf@zy=\pgf@y% + \ignorespaces} + + + +% Default values +\pgfsetxvec{\pgfpoint{1cm}{0cm}} +\pgfsetyvec{\pgfpoint{0cm}{1cm}} +\pgfsetzvec{\pgfpoint{-0.385cm}{-0.385cm}} + + + + +% Normalise a point. +% +% #1 = point with coordinates (a,b) +% +% x = a/\sqrt(a*a+b*b) +% y = b/\sqrt(a*a+b*b) +% +% Example: +% +% \pgfpointnormalised{\pgfpointxy{2}{1}} + +\def\pgfpointnormalised#1{% + \pgf@process{#1}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \ifdim\pgf@x<0pt\relax% move into first quadrant + \pgf@x=-\pgf@x% + \fi% + \ifdim\pgf@y<0pt\relax% + \pgf@y=-\pgf@y% + \fi% + \ifdim\pgf@x>\pgf@y% x > y + % make point small + \c@pgf@counta=\pgf@x% + \divide\c@pgf@counta by 65536\relax% + \ifnum\c@pgf@counta=0\relax% + \c@pgf@counta=1\relax% + \fi% + \divide\pgf@x by\c@pgf@counta% + \divide\pgf@y by\c@pgf@counta% + \divide\pgf@xa by\c@pgf@counta% + \divide\pgf@ya by\c@pgf@counta% + % ok. + \pgf@x=.125\pgf@x% + \pgf@y=.125\pgf@y% + \c@pgf@counta=\pgf@x% + \c@pgf@countb=\pgf@y% + \multiply\c@pgf@countb by 100% + \ifnum\c@pgf@counta<64\relax% + \pgf@x=1pt\relax% + \pgf@y=0pt\relax% + \else% + \divide\c@pgf@countb by \c@pgf@counta% + \pgf@setmath{x}{\csname pgf@cosfrac\the\c@pgf@countb\endcsname}% + \pgf@xc=8192pt% + \divide\pgf@xc by\c@pgf@counta% + \pgf@y=\pgf@sys@tonumber{\pgf@xc}\pgf@ya% + \pgf@y=\pgf@sys@tonumber{\pgf@x}\pgf@y% + \fi% + \ifdim\pgf@xa<0pt% + \pgf@x=-\pgf@x% + \fi% + \else% x <= y + % make point small + \c@pgf@counta=\pgf@y% + \divide\c@pgf@counta by 65536\relax% + \ifnum\c@pgf@counta=0\relax% + \c@pgf@counta=1\relax% + \fi% + \divide\pgf@x by\c@pgf@counta% + \divide\pgf@y by\c@pgf@counta% + \divide\pgf@xa by\c@pgf@counta% + \divide\pgf@ya by\c@pgf@counta% + % ok. + \pgf@x=.125\pgf@x% + \pgf@y=.125\pgf@y% + \c@pgf@counta=\pgf@y% + \c@pgf@countb=\pgf@x% + \multiply\c@pgf@countb by 100% + \ifnum\c@pgf@counta<64\relax% + \pgf@y=1pt\relax% + \pgf@x=0pt\relax% + \else% + \divide\c@pgf@countb by \c@pgf@counta% + \pgf@setmath{y}{\csname pgf@cosfrac\the\c@pgf@countb\endcsname}% + \pgf@xc=8192pt% + \divide\pgf@xc by\c@pgf@counta% + \pgf@x=\pgf@sys@tonumber{\pgf@xc}\pgf@xa% + \pgf@x=\pgf@sys@tonumber{\pgf@y}\pgf@x% + \fi% + \ifdim\pgf@ya<0pt% + \pgf@y=-\pgf@y% + \fi% + \fi\ignorespaces} + + + + + +% A point on a rectangle in a certain direction. +% +% #1 = a point pointing in some direction (length should be about 1pt, +% but need not be exact) +% #2 = upper right corner of a rectangle centered at the origin +% +% Returns the intersection of a line starting at the origin going in +% the given direction and the rectangle's border. +% +% Example: +% +% \pgfpointborderrectangle{\pgfpointnormalised{\pgfpointxy{2}{1}} +% {\pgfpoint{1cm}{2cm}} + +\def\pgfpointborderrectangle#1#2{% + \pgf@process{#2}% + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + \pgf@process{#1}% + % Ok, let's find out about the direction: + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \ifnum\pgf@xa<0\relax% move into first quadrant + \pgf@x=-\pgf@x% + \fi% + \ifnum\pgf@ya<0\relax% + \pgf@y=-\pgf@y% + \fi% + \pgf@xc=.125\pgf@x% + \pgf@yc=.125\pgf@y% + \c@pgf@counta=\pgf@xc% + \c@pgf@countb=\pgf@yc% + \ifnum\c@pgf@countb<\c@pgf@counta% + \ifnum\c@pgf@counta<255\relax% + \pgf@y=\pgf@yb\relax% + \pgf@x=0pt\relax% + \else% + \pgf@xc=8192pt% + \divide\pgf@xc by\c@pgf@counta% \pgf@xc = 1/\pgf@x + \pgf@y=\pgf@sys@tonumber{\pgf@xc}\pgf@y% + \pgf@y=\pgf@sys@tonumber{\pgf@xb}\pgf@y% + \ifnum\pgf@y<\pgf@yb% + \pgf@x=\pgf@xb% + \else% rats, calculate intersection on upper side + \ifnum\c@pgf@countb<255\relax% + \pgf@x=\pgf@xb\relax% + \pgf@y=0pt\relax% + \else% + \pgf@yc=8192pt% + \divide\pgf@yc by\c@pgf@countb% \pgf@xc = 1/\pgf@x + \pgf@x=\pgf@sys@tonumber{\pgf@yc}\pgf@x% + \pgf@x=\pgf@sys@tonumber{\pgf@yb}\pgf@x% + \pgf@y=\pgf@yb% + \fi% + \fi% + \fi% + \else% + \ifnum\c@pgf@countb<255\relax% + \pgf@x=\pgf@xb\relax% + \pgf@y=0pt\relax% + \else% + \pgf@yc=8192pt% + \divide\pgf@yc by\c@pgf@countb% \pgf@xc = 1/\pgf@x + \pgf@x=\pgf@sys@tonumber{\pgf@yc}\pgf@x% + \pgf@x=\pgf@sys@tonumber{\pgf@yb}\pgf@x% + \ifnum\pgf@x<\pgf@xb% + \pgf@y=\pgf@yb% + \else% + \ifnum\c@pgf@counta<255\relax% + \pgf@y=\pgf@yb\relax% + \pgf@x=0pt\relax% + \else% + \pgf@xc=8192pt% + \divide\pgf@xc by\c@pgf@counta% \pgf@xc = 1/\pgf@x + \pgf@y=\pgf@sys@tonumber{\pgf@xc}\pgf@y% + \pgf@y=\pgf@sys@tonumber{\pgf@xb}\pgf@y% + \pgf@x=\pgf@xb% + \fi% + \fi% + \fi% + \fi% + \ifnum\pgf@xa<0\relax\pgf@x=-\pgf@x\fi% + \ifnum\pgf@ya<0\relax\pgf@y=-\pgf@y\fi% +} + + + + +% An approximation to a point on an ellipse in a certain +% direction. Will be exact only if the ellipse is a circle. +% +% #1 = a point pointing in some direction +% #2 = upper right corner of a bounding box for the ellipse +% +% Returns the intersection of a line starting at the origin going in +% the given direction and the ellipses border. +% +% Example: +% +% \pgfpointborderellipse{\pgfpointnormalised{\pgfpointxy{2}{1}} +% {\pgfpoint{1cm}{2cm}} + +\def\pgfpointborderellipse#1#2{% + \pgf@process{#2}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \ifdim\pgf@xa=\pgf@ya% circle. that's easy! + \pgf@process{\pgfpointnormalised{#1}}% + \pgf@x=\pgf@sys@tonumber{\pgf@xa}\pgf@x% + \pgf@y=\pgf@sys@tonumber{\pgf@xa}\pgf@y% + \else% + \ifdim\pgf@xa<\pgf@ya% + % Ok, first, let's compute x/y: + \c@pgf@countb=\pgf@ya% + \divide\c@pgf@countb by65536\relax% + \divide\pgf@x by\c@pgf@countb% + \divide\pgf@y by\c@pgf@countb% + \pgf@xc=\pgf@x% + \pgf@yc=8192pt% + \pgf@y=.125\pgf@y% + \c@pgf@countb=\pgf@y% + \divide\pgf@yc by\c@pgf@countb% + \pgf@process{#1}% + \pgf@y=\pgf@sys@tonumber{\pgf@yc}\pgf@y% + \pgf@y=\pgf@sys@tonumber{\pgf@xc}\pgf@y% + \pgf@process{\pgfpointnormalised{}}% + \pgf@x=\pgf@sys@tonumber{\pgf@xa}\pgf@x% + \pgf@y=\pgf@sys@tonumber{\pgf@ya}\pgf@y% + \else% + % Ok, now let's compute y/x: + \c@pgf@countb=\pgf@xa% + \divide\c@pgf@countb by65536\relax% + \divide\pgf@x by\c@pgf@countb% + \divide\pgf@y by\c@pgf@countb% + \pgf@yc=\pgf@y% + \pgf@xc=8192pt% + \pgf@x=.125\pgf@x% + \c@pgf@countb=\pgf@x% + \divide\pgf@xc by\c@pgf@countb% + \pgf@process{#1}% + \pgf@x=\pgf@sys@tonumber{\pgf@yc}\pgf@x% + \pgf@x=\pgf@sys@tonumber{\pgf@xc}\pgf@x% + \pgf@process{\pgfpointnormalised{}}% + \pgf@x=\pgf@sys@tonumber{\pgf@xa}\pgf@x% + \pgf@y=\pgf@sys@tonumber{\pgf@ya}\pgf@y% + \fi% + \fi% +} + + + + + +% Extract the x-coordinate of a point to a dimensions +% +% #1 = a TeX dimension +% #2 = a point +% +% Example: +% +% \newdimen\mydim +% \pgfextractx{\mydim}{\pgfpoint{2cm}{4pt}} +% % \mydim is now 2cm + +\def\pgfextractx#1#2{% + \pgf@process{#2}% + #1=1.00374\pgf@x\relax} + + +% Extract the y-coordinate of a point to a dimensions +% +% #1 = a TeX dimension +% #2 = a point +% +% Example: +% +% \newdimen\mydim +% \pgfextracty{\mydim}{\pgfpoint{2cm}{4pt}} +% % \mydim is now 4pt + +\def\pgfextracty#1#2{% + \pgf@process{#2}% + #1=1.00374\pgf@y\relax} + + +\endinput |