diff options
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex')
-rw-r--r-- | Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex | 331 |
1 files changed, 245 insertions, 86 deletions
diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex index b90e96c8b5a..41c0d1cdc19 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex @@ -11,6 +11,8 @@ % Experimentally, it performed well while computing ~12 intersections of two % plots, each with 600 samples. It failed when the number of samples exceeded 700. +\usepgflibrary{fpu} + \newcount\pgf@intersect@solutions \newif\ifpgf@intersect@sort @@ -50,6 +52,9 @@ % % -> \first may be 0 if point #0 is in the 0'th segment % -> \second may be 42 if point #0 is in the 42'th segment +% +% The "segment index" is actually close to the "time" of the solution. +% If a solution is at "time" 42.2, it will have segment index 42. \def\pgfintersectiongetsolutionsegmentindices#1#2#3{% \ifnum#1<1\relax% \let#2=\pgfutil@empty @@ -59,8 +64,56 @@ \let#2=\pgfutil@empty \let#3=\pgfutil@empty \else% - \edef#2{\csname pgf@intersect@solution@segment@a@#1\endcsname}% - \edef#3{\csname pgf@intersect@solution@segment@b@#1\endcsname}% + \def\pgf@temp##1##2##3##4{% + \edef#2{##1}% + \edef#3{##2}% + }% + \expandafter\let\expandafter\pgf@tempb\csname pgf@intersect@solution@props@#1\endcsname + \expandafter\pgf@temp\pgf@tempb + \fi% + \fi% +}% + +% Gets the time indices of solution #1. +% +% #1: the solution index (i.e. the same argument as in \pgfpointintersectionsolution) +% #2: [output] a macro name which will contain the time of the first path which contains the solution +% It will never be empty. +% #3: [output] a macro name which will contain the time of the second path which contains the solution +% It will never be empty. +% +% Example: \pgfintersectiongetsolutiontimes{0}{\first}{\second} +% +% -> \first may be 0.5 if point #0 is in just in the middle of the path +% -> \second may be 42.8 if point #0 is in the 42'th segment (compare +% \pgfintersectiongetsolutionsegmentindices) and is at 80% of the +% 42'th segment +% +% Note that the precise time inside of a segment may be unavailable +% (currently, it is only computed for curveto paths and not +% necessarily for lineto). If the precise time is unavailable, this +% call will return the value of +% \pgfintersectiongetsolutionsegmentindices (which is a +% "coarse-grained" time). +\def\pgfintersectiongetsolutiontimes#1#2#3{% + \ifnum#1<1\relax% + \let#2=\pgfutil@empty + \let#3=\pgfutil@empty + \else% + \ifnum#1>\pgfintersectionsolutions\relax% + \let#2=\pgfutil@empty + \let#3=\pgfutil@empty + \else% + \def\pgf@temp##1##2##3##4{% + \edef#2{##3}% + \edef#3{##4}% + % + % check for fallback to segment indices: + \ifx#2\pgfutil@empty \edef#2{##1}\fi + \ifx#3\pgfutil@empty \edef#3{##2}\fi + }% + \expandafter\let\expandafter\pgf@tempb\csname pgf@intersect@solution@props@#1\endcsname + \expandafter\pgf@temp\pgf@tempb \fi% \fi% }% @@ -100,7 +153,7 @@ \let\pgf@intersect@path@b=\pgf@intersect@path@temp% % \pgf@intersect@solutions=0\relax% - \def\pgf@intersect@time@offset{0}% + \pgf@intersect@path@reset@a % \ifpgf@intersect@sort@by@second@path% \let\pgf@intersect@temp=\pgf@intersect@path@a% @@ -119,7 +172,7 @@ \else% \pgfutil@namelet{pgfpoint@intersect@solution@\pgfmathcounter}% {pgfpoint@g@intersect@solution@\pgfmathcounter}% - \edef\pgf@marshal{\noexpand\pgf@intersection@set@properties\csname pgfpoint@g@intersect@solution@\pgfmathcounter @props\endcsname}% + \edef\pgf@marshal{\noexpand\pgf@intersection@set@properties{\csname pgfpoint@g@intersect@solution@\pgfmathcounter @props\endcsname}}% \pgf@marshal \ifpgf@intersect@sort% \pgfutil@namelet{pgf@intersect@solution@\pgfmathcounter @time@a}% @@ -131,15 +184,28 @@ \fi% } -\def\pgf@intersection@set@properties#1#2{% - \pgfutil@namedef{pgf@intersect@solution@segment@a@\pgfmathcounter}{#1}% - \pgfutil@namedef{pgf@intersect@solution@segment@b@\pgfmathcounter}{#2}% +\def\pgf@intersection@set@properties#1{% + \pgfutil@namedef{pgf@intersect@solution@props@\pgfmathcounter}{#1}% }% % #1 a global name prefix to store properties. \def\pgf@intersection@store@properties#1{% % we store the time offsets as well and make them available programmatically: - \expandafter\xdef\csname #1@props\endcsname{{\pgf@intersect@time@offset}{\pgf@intersect@time@offset@b}}% + % note that \pgf@intersect@time@a and \pgf@intersect@time@b may be empty. + % + % However, \pgf@intersect@time@offset and + % \pgf@intersect@time@offset@b are *always* valid. In fact,they + % resemble a part of the time: it holds + % 0 <= \pgf@intersect@time@a < 1 + % and \pgf@intersect@time@offset > 0. + % + % If we have an intersection in segment 42 of path A, + % \pgf@intersect@time@offset will be 42. The time inside of that + % segment is given as number in the interval [0,1]. If it is 0.3, + % the total time will be 42.3 and that number will be stored as + % \pgf@intersect@time@a. + % + \expandafter\xdef\csname #1@props\endcsname{{\pgf@intersect@time@offset}{\pgf@intersect@time@offset@b}{\pgf@intersect@time@a}{\pgf@intersect@time@b}}% } \def\pgf@intersectionofpaths#1{% @@ -204,7 +270,7 @@ \def\pgf@intersect@path@process@a{% \pgf@intersect@path@getpoints@a% \let\pgf@intersect@token@after=\pgf@intersect@path@process@b% - \def\pgf@intersect@time@offset@b{0}% + \pgf@intersect@path@reset@b \expandafter\pgf@intersectionofpaths\pgf@intersect@path@b\pgf@stop% \let\pgfpoint@intersect@start=\pgfpoint@intersect@end@a% \let\pgf@intersect@token@after=\pgf@intersect@path@process@a% @@ -214,6 +280,16 @@ \pgf@intersectionofpaths% } +\def\pgf@intersect@path@reset@a{% + \def\pgf@intersect@time@offset{0}% + \def\pgf@intersect@time@a{}% +}% + +\def\pgf@intersect@path@reset@b{% + \def\pgf@intersect@time@offset@b{0}% + \def\pgf@intersect@time@b{}% +}% + \def\pgf@intersect@path@getpoints@a{% \let\pgfpoint@intersect@start@a=\pgfpoint@intersect@start% \let\pgfpoint@intersect@end@a=\pgfpoint@intersect@end% @@ -275,33 +351,43 @@ \def\pgf@intersectionoflines#1#2#3#4{% \pgf@iflinesintersect{#1}{#2}{#3}{#4}% {% - \global\advance\pgf@intersect@solutions by1\relax% - \expandafter\pgfextract@process\csname pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions\endcsname{% + \pgfextract@process\pgf@intersect@solution@candidate{% \pgfpointintersectionoflines{\pgfpoint@intersect@start@a}{\pgfpoint@intersect@end@a}% {\pgfpoint@intersect@start@b}{\pgfpoint@intersect@end@b}% }% - \pgf@intersection@store@properties{pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions}% + \pgf@ifsolution@duplicate{\pgf@intersect@solution@candidate}{% + % ah - we a duplicate. Apparently, we have a hit on an + % endpoint. + }{% + \global\advance\pgf@intersect@solutions by1\relax% + \expandafter\global\expandafter\let\csname pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions\endcsname=\pgf@intersect@solution@candidate + \ifpgf@intersect@sort% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \pgf@process{\pgfpointdiff{\pgfpoint@intersect@start@a}{\pgfpoint@intersect@end@a}}% + \edef\pgf@marshal{% + \noexpand\pgfmathveclen@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@ya}}% + }% + \pgf@marshal% + \let\pgf@intersect@length@a=\pgfmathresult% + \pgf@process{\pgfpointdiff{\pgfpoint@intersect@start@a}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}% + \edef\pgf@marshal{% + \noexpand\pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% + }% + \pgf@marshal% + \pgfmathdivide@{\pgfmathresult}{\pgf@intersect@length@a}% + \pgf@x=\pgfmathresult pt\relax% + \advance\pgf@x by\pgf@intersect@time@offset pt\relax% + \edef\pgf@intersect@time@a{\pgfmath@tonumber{\pgf@x}}% + \expandafter\global\expandafter\let\csname pgf@g@intersect@solution@\the\pgf@intersect@solutions @time@a\endcsname= + \pgf@intersect@time@a + \else + \let\pgf@intersect@time@a=\pgfutil@empty + \fi% + \let\pgf@intersect@time@b=\pgfutil@empty + \pgf@intersection@store@properties{pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions}% + }% % - \ifpgf@intersect@sort% - \pgf@xc=\pgf@x% - \pgf@yc=\pgf@y% - \pgf@process{\pgfpointdiff{\pgfpoint@intersect@start@a}{\pgfpoint@intersect@end@a}}% - \edef\pgf@marshal{% - \noexpand\pgfmathveclen@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@ya}}% - }% - \pgf@marshal% - \let\pgf@intersect@length@a=\pgfmathresult% - \pgf@process{\pgfpointdiff{\pgfpoint@intersect@start@a}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}% - \edef\pgf@marshal{% - \noexpand\pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% - }% - \pgf@marshal% - \pgfmathdivide@{\pgfmathresult}{\pgf@intersect@length@a}% - \pgf@x=\pgfmathresult pt\relax% - \advance\pgf@x by\pgf@intersect@time@offset pt\relax% - \expandafter\xdef\csname pgf@g@intersect@solution@\the\pgf@intersect@solutions @time@a\endcsname% - {\pgfmath@tonumber{\pgf@x}}% - \fi% }{}% } @@ -572,6 +658,8 @@ \pgf@intersect@boundingbox@update{#2}% \pgf@intersect@boundingbox@update{#3}% \pgf@intersect@boundingbox@update{#4}% + % (\pgf@xa, \pgf@ya) is lower-left + % (\pgf@xb, \pgf@yb) is upper-right \edef\pgf@intersect@boundingbox@b{% \noexpand\pgf@x=\the\pgf@xa% \noexpand\pgf@y=\the\pgf@ya% @@ -591,6 +679,7 @@ }% \pgf@intersect@boundingbox@a% \pgf@intersect@boundingbox@b% + % check if the two bounding boxes overlap: \ifdim\pgf@xa<\pgf@xb% \else% \ifdim\pgf@x>\pgf@xc% @@ -599,16 +688,21 @@ \else% \ifdim\pgf@y>\pgf@yc% \else% + % compute DIFFERENCE vectors: \advance\pgf@xc by-\pgf@xb% \advance\pgf@yc by-\pgf@yb% \advance\pgf@xa by-\pgf@x% \advance\pgf@ya by-\pgf@y% \let\pgf@intersect@subdivde=\relax% + % check if both difference vectors are point wise + % less than tolerance (i.e. |v|_infty < eps ). + % That means that both bounding boxes are "small enough" \ifdim\pgf@xc<\pgfintersectiontolerance\relax% \ifdim\pgf@xa<\pgfintersectiontolerance\relax% \ifdim\pgf@yc<\pgfintersectiontolerance\relax% \ifdim\pgf@ya<\pgfintersectiontolerance\relax% \pgfextract@process\pgf@intersect@solution@candidate{% + % set (x,y) = mean(the 4 points of the two bounding boxes): \pgf@intersect@boundingbox@a% \pgf@intersect@boundingbox@b% \pgf@x=0.25\pgf@x% @@ -625,20 +719,27 @@ \pgf@ifsolution@duplicate\pgf@intersect@solution@candidate{}% {% \global\advance\pgf@intersect@solutions by1\relax% + \begingroup + \advance\pgf@time@a by\pgf@time@aa% + \divide\pgf@time@a by2\relax% + \advance\pgf@time@a by\pgf@intersect@time@offset pt\relax% + \edef\pgf@intersect@time@a{\pgfmath@tonumber{\pgf@time@a}}% + % + \advance\pgf@time@b by\pgf@time@bb% + \divide\pgf@time@b by2\relax% + \advance\pgf@time@b by\pgf@intersect@time@offset@b pt\relax% + \edef\pgf@intersect@time@b{\pgfmath@tonumber{\pgf@time@b}}% + % \pgf@intersection@store@properties{pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions}% \expandafter\global\expandafter\let% \csname pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions\endcsname=% \pgf@intersect@solution@candidate% - {% - \ifpgf@intersect@sort% - \advance\pgf@time@a by\pgf@time@aa% - \divide\pgf@time@a by2\relax% - \advance\pgf@time@a by\pgf@intersect@time@offset pt\relax% - \expandafter\xdef% - \csname pgf@g@intersect@solution@\the\pgf@intersect@solutions @time@a\endcsname% - {\pgfmath@tonumber{\pgf@time@a}}% - \fi% - }% + \ifpgf@intersect@sort% + \expandafter\xdef% + \csname pgf@g@intersect@solution@\the\pgf@intersect@solutions @time@a\endcsname% + {\pgf@intersect@time@a}% + \fi% + \endgroup }% \fi% \fi% @@ -699,33 +800,74 @@ \ifdim\pgf@y>\pgf@yb\pgf@yb=\pgf@y\fi% } +% The following subroutines are part of a conversion from pgfbasic +% math to FPU. This transition is necessary due to the restricted +% accuracy of pgfbasic. In order to limit the error rate of the +% transition pgfbasic -> FPU, I chose to +% keep the old "pattern" of sorts \advance\pgf@xa by0.5\pgf@y etc and +% simply adapt to some FPU call. +% +% The following routines constitute the "adapter": + +\def\pgf@float@adapter@setxy{% + \pgfmathfloatparsenumber{\pgf@sys@tonumber\pgf@x}\let\pgf@fpu@x=\pgfmathresult + \pgfmathfloatparsenumber{\pgf@sys@tonumber\pgf@y}\let\pgf@fpu@y=\pgfmathresult +}% +\def\pgf@float@adapter@mult#1=#2*#3{% + \pgfmathfloatmultiplyfixed@{#3}{#2}% + \let#1=\pgfmathresult +}% +\def\pgf@float@adapter@advance#1by#2*#3{% + \pgfmathfloatmultiplyfixed@{#3}{#2}% + \let\pgfutil@temp=\pgfmathresult + \pgfmathfloatadd@{#1}{\pgfutil@temp}% + \let#1=\pgfmathresult +}% + +\def\pgf@float@adapter@tostring#1{% + \pgfmathfloattofixed{#1}\edef#1{\pgfmathresult pt }% +}% \def\pgf@curve@subdivide@left#1#2#3#4{% % % The left curve (from t=0 to t=.5) % + \begingroup #1\relax% \pgfutil@tempdima=\pgf@x% \pgfutil@tempdimb=\pgf@y% - \pgf@xa=.5\pgf@x\pgf@ya=.5\pgf@y% - \pgf@xb=.25\pgf@x\pgf@yb=.25\pgf@y% - \pgf@xc=.125\pgf@x\pgf@yc=.125\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@mult\pgf@fpu@xa=.5*\pgf@fpu@x \pgf@float@adapter@mult\pgf@fpu@ya=.5*\pgf@fpu@y% + \pgf@float@adapter@mult\pgf@fpu@xb=.25*\pgf@fpu@x \pgf@float@adapter@mult\pgf@fpu@yb=.25*\pgf@fpu@y% + \pgf@float@adapter@mult\pgf@fpu@xc=.125*\pgf@fpu@x\pgf@float@adapter@mult\pgf@fpu@yc=.125*\pgf@fpu@y% #2\relax% - \advance\pgf@xa by.5\pgf@x\advance\pgf@ya by.5\pgf@y% - \advance\pgf@xb by.5\pgf@x\advance\pgf@yb by.5\pgf@y% - \advance\pgf@xc by.375\pgf@x\advance\pgf@yc by.375\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@fpu@xa by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@ya by.5*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xb by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yb by.5*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xc by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yc by.375*\pgf@fpu@y% #3\relax% - \advance\pgf@xb by.25\pgf@x\advance\pgf@yb by.25\pgf@y% - \advance\pgf@xc by.375\pgf@x\advance\pgf@yc by.375\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@fpu@xb by.25*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yb by.25*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xc by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yc by.375*\pgf@fpu@y% #4\relax% - \advance\pgf@xc by.125\pgf@x\advance\pgf@yc by.125\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@fpu@xc by.125*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yc by.125*\pgf@fpu@y% + % + \pgf@float@adapter@tostring\pgf@fpu@xa + \pgf@float@adapter@tostring\pgf@fpu@ya + \pgf@float@adapter@tostring\pgf@fpu@xb + \pgf@float@adapter@tostring\pgf@fpu@yb + \pgf@float@adapter@tostring\pgf@fpu@xc + \pgf@float@adapter@tostring\pgf@fpu@yc \edef\pgf@marshal{% \noexpand\pgf@curve@subdivde@after% {\noexpand\pgf@x=\the\pgfutil@tempdima\noexpand\pgf@y=\the\pgfutil@tempdimb}% - {\noexpand\pgf@x=\the\pgf@xa\noexpand\pgf@y\the\pgf@ya}% - {\noexpand\pgf@x=\the\pgf@xb\noexpand\pgf@y=\the\pgf@yb} - {\noexpand\pgf@x=\the\pgf@xc\noexpand\pgf@y=\the\pgf@yc}% + {\noexpand\pgf@x=\pgf@fpu@xa\noexpand\pgf@y=\pgf@fpu@ya}% + {\noexpand\pgf@x=\pgf@fpu@xb\noexpand\pgf@y=\pgf@fpu@yb} + {\noexpand\pgf@x=\pgf@fpu@xc\noexpand\pgf@y=\pgf@fpu@yc}% }% + \expandafter + \endgroup \pgf@marshal% } @@ -733,26 +875,43 @@ % % The right curve (from t=0.5 to t=1) % + \begingroup #1\relax% - \pgfutil@tempdima=.125\pgf@x\pgfutil@tempdimb=.125\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@mult\pgf@float@tmpa=.125*\pgf@fpu@x\pgf@float@adapter@mult\pgf@float@tmpb=.125*\pgf@fpu@y% #2\relax% - \advance\pgfutil@tempdima by.375\pgf@x\advance\pgfutil@tempdimb by.375\pgf@y% - \pgf@xa=.25\pgf@x\pgf@ya=.25\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@float@tmpa by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@float@tmpb by.375*\pgf@fpu@y% + \pgf@float@adapter@mult\pgf@fpu@xa=.25*\pgf@fpu@x\pgf@float@adapter@mult\pgf@fpu@ya=.25*\pgf@fpu@y% #3\relax% - \advance\pgfutil@tempdima by.375\pgf@x\advance\pgfutil@tempdimb by.375\pgf@y% - \advance\pgf@xa by.5\pgf@x\advance\pgf@ya by.5\pgf@y% - \pgf@xb=.5\pgf@x\pgf@yb=.5\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@float@tmpa by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@float@tmpb by.375*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xa by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@ya by.5*\pgf@fpu@y% + \pgf@float@adapter@mult\pgf@fpu@xb=.5*\pgf@fpu@x\pgf@float@adapter@mult\pgf@fpu@yb=.5*\pgf@fpu@y% #4\relax% - \advance\pgfutil@tempdima by.125\pgf@x\advance\pgfutil@tempdimb by.125\pgf@y% - \advance\pgf@xa by.25\pgf@x\advance\pgf@ya by.25\pgf@y% - \advance\pgf@xb by.5\pgf@x\advance\pgf@yb by.5\pgf@y% - \pgf@xc=\pgf@x\pgf@yc=\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@float@tmpa by.125*\pgf@fpu@x\pgf@float@adapter@advance\pgf@float@tmpb by.125*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xa by.25*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@ya by.25*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xb by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yb by.5*\pgf@fpu@y% + \let\pgf@fpu@xc=\pgf@fpu@x\let\pgf@fpu@yc=\pgf@fpu@y% + % + \pgf@float@adapter@tostring\pgf@float@tmpa + \pgf@float@adapter@tostring\pgf@float@tmpb + \pgf@float@adapter@tostring\pgf@fpu@xa + \pgf@float@adapter@tostring\pgf@fpu@ya + \pgf@float@adapter@tostring\pgf@fpu@xb + \pgf@float@adapter@tostring\pgf@fpu@yb + \pgf@float@adapter@tostring\pgf@fpu@xc + \pgf@float@adapter@tostring\pgf@fpu@yc \edef\pgf@marshal{% \noexpand\pgf@curve@subdivde@after% - {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% - {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} - {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% + {\noexpand\pgf@x=\pgf@float@tmpa\noexpand\pgf@y=\pgf@float@tmpb}% + {\noexpand\pgf@x=\pgf@fpu@xa\noexpand\pgf@y=\pgf@fpu@ya} + {\noexpand\pgf@x=\pgf@fpu@xb\noexpand\pgf@y=\pgf@fpu@yb} + {\noexpand\pgf@x=\pgf@fpu@xc\noexpand\pgf@y=\pgf@fpu@yc}% }% + \expandafter + \endgroup \pgf@marshal% } @@ -773,23 +932,26 @@ \pgfmathloop% \ifnum\pgfmathcounter>\pgf@intersect@solutions\relax% \else% - \pgf@process{\csname pgfpoint@g@intersect@solution@\pgfmathcounter\endcsname}% - \advance\pgf@x by-\pgf@xa% - \advance\pgf@y by-\pgf@ya% - \ifdim\pgf@x<0pt\relax\pgf@x=-\pgf@x\fi% - \ifdim\pgf@y<0pt\relax\pgf@y=-\pgf@y\fi% - % - \pgf@x=\pgfintersectiontolerancefactor\pgf@x% - \pgf@y=\pgfintersectiontolerancefactor\pgf@y% - \ifdim\pgf@x<\pgfintersectiontolerance\relax% - \ifdim\pgf@y<\pgfintersectiontolerance\relax% - \let\pgf@intersect@next=\pgfutil@firstoftwo% - \fi% - \fi% + \pgf@ifsolution@duplicate@{\pgfmathcounter}% \repeatpgfmathloop% \pgf@intersect@next% } +\def\pgf@ifsolution@duplicate@#1{% + \pgf@process{\csname pgfpoint@g@intersect@solution@#1\endcsname}% + \advance\pgf@x by-\pgf@xa% + \advance\pgf@y by-\pgf@ya% + \ifdim\pgf@x<0pt\relax\pgf@x=-\pgf@x\fi% + \ifdim\pgf@y<0pt\relax\pgf@y=-\pgf@y\fi% + % + \pgf@x=\pgfintersectiontolerancefactor\pgf@x% + \pgf@y=\pgfintersectiontolerancefactor\pgf@y% + \ifdim\pgf@x<\pgfintersectiontolerance\relax% + \ifdim\pgf@y<\pgfintersectiontolerance\relax% + \let\pgf@intersect@next=\pgfutil@firstoftwo% + \fi% + \fi% +}% \newif\ifpgf@intersect@solutions@sortfinish @@ -798,8 +960,7 @@ \def\pgfintersectionsolutionsortbytime{% \pgf@intersect@solutions@sortfinishtrue% \pgfmathloop% - \ifnum\pgfmathcounter=\pgfintersectionsolutions\relax% - \else% + \ifnum\pgfmathcounter<\pgfintersectionsolutions\relax% \pgfutil@tempcnta=\pgfmathcounter% \advance\pgfutil@tempcnta by1\relax% \ifdim\csname pgf@intersect@solution@\pgfmathcounter @time@a\endcsname pt>% @@ -812,10 +973,8 @@ \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@\pgfmathcounter @time@a}% {pgf@intersect@solution@\the\pgfutil@tempcnta @time@a}% % - \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@segment@a@\pgfmathcounter}% - {pgf@intersect@solution@segment@a@\the\pgfutil@tempcnta}% - \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@segment@b@\pgfmathcounter}% - {pgf@intersect@solution@segment@b@\the\pgfutil@tempcnta}% + \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@props@\pgfmathcounter}% + {pgf@intersect@solution@props@\the\pgfutil@tempcnta}% \fi% \repeatpgfmathloop% \ifpgf@intersect@solutions@sortfinish% |