\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 . % % 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