diff options
author | Karl Berry <karl@freefriends.org> | 2014-02-27 00:01:50 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2014-02-27 00:01:50 +0000 |
commit | 90ae413a94da014dbf7a6a8ab584f7c668483a5a (patch) | |
tree | 4e0528a2b2fb2004988e7fc804ea2f1354f1f5d5 /Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex | |
parent | 800cc56380d1edfe567a6a66bef13e8950eb2b0c (diff) |
pgf 3.0.0
git-svn-id: svn://tug.org/texlive/trunk@33057 c570f23f-e606-0410-a88d-b1316a301751
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 | 78 |
1 files changed, 72 insertions, 6 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 698ec524ba8..b90e96c8b5a 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex @@ -7,6 +7,9 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. +% Note: at the time of this writing, the library has quadratic runtime. +% Experimentally, it performed well while computing ~12 intersections of two +% plots, each with 600 samples. It failed when the number of samples exceeded 700. \newcount\pgf@intersect@solutions @@ -23,6 +26,8 @@ \pgf@intersect@sort@by@second@pathtrue% } +% #1: the index. It starts at 1 and ends with \pgfintersectionsolutions (inclusive). +% Invalid values will implicitly result in the origin. \def\pgfpointintersectionsolution#1{% \ifnum#1<1\relax% \pgfpoint@intersect@solution@orgin% @@ -35,6 +40,31 @@ \fi% } +% Gets the segment 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 segment index of the first path which contains the solution +% #3: [output] a macro name which will contain the segment index of the second path which contains the solution +% +% Example: \pgfintersectiongetsolutionsegmentindices{0}{\first}{\second} +% +% -> \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 +\def\pgfintersectiongetsolutionsegmentindices#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% + \edef#2{\csname pgf@intersect@solution@segment@a@#1\endcsname}% + \edef#3{\csname pgf@intersect@solution@segment@b@#1\endcsname}% + \fi% + \fi% +}% + \def\pgfpoint@intersect@solution@orgin{% \begingroup% \pgftransforminvert% @@ -45,6 +75,11 @@ \endgroup% } +% #1 code which assigns the first path using \pgfsetpath. +% #2 code which assigns the second path using \pgfsetpath. +% +% On output, the points, their properties, and the number of points are set. +% Use \pgfintersectionsolutions which expands to the number of intersections \long\def\pgfintersectionofpaths#1#2{% \begingroup% \pgfinterruptpath% @@ -72,6 +107,10 @@ \let\pgf@intersect@path@a=\pgf@intersect@path@b% \let\pgf@intersect@path@b=\pgf@intersect@temp% \fi% + % + \pgfprocessround\pgf@intersect@path@a\pgf@intersect@path@a% + \pgfprocessround\pgf@intersect@path@b\pgf@intersect@path@b% + % \let\pgf@intersect@token@after=\pgf@intersect@path@process@a% \expandafter\pgf@intersectionofpaths\pgf@intersect@path@a\pgf@stop% \edef\pgfintersectionsolutions{\the\pgf@intersect@solutions}% @@ -80,6 +119,8 @@ \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}% + \pgf@marshal \ifpgf@intersect@sort% \pgfutil@namelet{pgf@intersect@solution@\pgfmathcounter @time@a}% {pgf@g@intersect@solution@\pgfmathcounter @time@a}% @@ -90,6 +131,17 @@ \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}% +}% + +% #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}}% +} + \def\pgf@intersectionofpaths#1{% \ifx#1\pgf@stop% \let\pgf@intersect@next=\relax% @@ -152,6 +204,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}% \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% @@ -173,6 +226,9 @@ \pgf@intersect@path@getpoints@b% \csname pgf@intersect@\pgf@intersect@type@a @and@\pgf@intersect@type@b\endcsname% \let\pgfpoint@intersect@start=\pgfpoint@intersect@end@b% + \c@pgf@counta=\pgf@intersect@time@offset@b\relax% + \advance\c@pgf@counta by1\relax% + \edef\pgf@intersect@time@offset@b{\the\c@pgf@counta}% \pgf@intersectionofpaths} \def\pgf@intersect@path@getpoints@b{% @@ -224,6 +280,8 @@ \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}% + % \ifpgf@intersect@sort% \pgf@xc=\pgf@x% \pgf@yc=\pgf@y% @@ -567,6 +625,7 @@ \pgf@ifsolution@duplicate\pgf@intersect@solution@candidate{}% {% \global\advance\pgf@intersect@solutions by1\relax% + \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% @@ -747,15 +806,16 @@ \csname pgf@intersect@solution@\the\pgfutil@tempcnta @time@a\endcsname pt\relax% \pgf@intersect@solutions@sortfinishfalse% % - \pgfutil@namelet{pgf@intersect@temp}{pgfpoint@intersect@solution@\pgfmathcounter}% - \pgfutil@namelet{pgfpoint@intersect@solution@\pgfmathcounter}% + \pgfintersectionsolutionsortbytime@swap{pgfpoint@intersect@solution@\pgfmathcounter}% {pgfpoint@intersect@solution@\the\pgfutil@tempcnta}% - \pgfutil@namelet{pgfpoint@intersect@solution@\the\pgfutil@tempcnta}{pgf@intersect@temp}% % - \pgfutil@namelet{pgf@intersect@temp}{pgf@intersect@solution@\pgfmathcounter @time@a}% - \pgfutil@namelet{pgf@intersect@solution@\pgfmathcounter @time@a}% + \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@\pgfmathcounter @time@a}% {pgf@intersect@solution@\the\pgfutil@tempcnta @time@a}% - \pgfutil@namelet{pgf@intersect@solution@\the\pgfutil@tempcnta @time@a}{pgf@intersect@temp}% + % + \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}% \fi% \repeatpgfmathloop% \ifpgf@intersect@solutions@sortfinish% @@ -764,4 +824,10 @@ \fi% } +\def\pgfintersectionsolutionsortbytime@swap#1#2{% + \pgfutil@namelet{pgf@intersect@temp}{#1}% + \pgfutil@namelet{#1}{#2}% + \pgfutil@namelet{#2}{pgf@intersect@temp}% +}% + \endinput |