%% pgflibrarybezieroffset.code.tex
%% Copyright 2023 Jonathan Schulz
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% of this license or (at your option) any later version.
% The latest version of this license is in
%
http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2008-05-04 or later.
%
% This work has the LPPL maintenance status 'maintained'.
%
% The Current Maintainer of this work is Jonathan Schulz.
%
% This work consists of the files
% pgflibrarybezieroffset.code.tex, pgflibrarynfold.code.tex, pgflibraryoffsetpath.code.tex, tikz-nfold-doc.tex, tikzlibrarynfold.code.tex, tikz-nfold-doc.tex, and tikz-nfold-doc.pdf.
%
%
% A commented version of this file can be found on
https://github.com/jonschz/tikz-nfold .
%
\def\pgf@halfsplitbezier#1#2#3#4{%
\pgfextract@process\pgf@splitbezier@ii@iv{#4}%
\pgf@xc=\pgf@x%
\pgf@yc=\pgf@y%
\pgf@process{#3}%
\pgf@xb=\pgf@x%
\pgf@yb=\pgf@y%
\pgf@process{#2}%
\pgf@xa=\pgf@x%
\pgf@ya=\pgf@y%
\pgfextract@process\pgf@splitbezier@i@i{#1}%
\pgf@x=.5\pgf@x\advance\pgf@x by.5\pgf@xa%
\pgf@y=.5\pgf@y\advance\pgf@y by.5\pgf@ya%
\edef\pgf@splitbezier@i@ii{\pgf@x\the\pgf@x\pgf@y\the\pgf@y}%
\pgf@xa=.5\pgf@xa\advance\pgf@xa by.5\pgf@xb%
\pgf@ya=.5\pgf@ya\advance\pgf@ya by.5\pgf@yb%
\pgf@xb=.5\pgf@xb\advance\pgf@xb by.5\pgf@xc%
\pgf@yb=.5\pgf@yb\advance\pgf@yb by.5\pgf@yc%
\edef\pgf@splitbezier@ii@iii{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb}%
\pgf@x=.5\pgf@x\advance\pgf@x by.5\pgf@xa%
\pgf@y=.5\pgf@y\advance\pgf@y by.5\pgf@ya%
\edef\pgf@splitbezier@i@iii{\pgf@x\the\pgf@x\pgf@y\the\pgf@y}%
\pgf@xa=.5\pgf@xa\advance\pgf@xa by.5\pgf@xb%
\pgf@ya=.5\pgf@ya\advance\pgf@ya by.5\pgf@yb%
\edef\pgf@splitbezier@ii@ii{\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}%
\pgf@x=.5\pgf@x\advance\pgf@x by.5\pgf@xa%
\pgf@y=.5\pgf@y\advance\pgf@y by.5\pgf@ya%
\edef\pgf@splitbezier@i@iv{\pgf@x\the\pgf@x\pgf@y\the\pgf@y}%
\let\pgf@splitbezier@ii@i\pgf@splitbezier@i@iv
}
\def\pgfmathcrossproduct#1#2{%
\begingroup
\pgf@process{#1}%
\pgf@xa=\pgf@x%
\pgf@ya=\pgf@y%
\pgf@process{#2}%
\pgf@y=\pgf@sys@tonumber\pgf@xa\pgf@y
\advance\pgf@y by -\pgf@sys@tonumber\pgf@ya\pgf@x
\pgfmath@returnone\pgf@y
\endgroup
}
\def\pgfmathdotproduct#1#2{%
\begingroup
\pgf@process{#1}%
\pgf@xa=\pgf@x%
\pgf@ya=\pgf@y%
\pgf@process{#2}%
\pgf@x=\pgf@sys@tonumber\pgf@xa\pgf@x
\advance\pgf@x by \pgf@sys@tonumber\pgf@ya\pgf@y
\pgfmath@returnone\pgf@x
\endgroup
}
\def\pgfmathcrossdot#1#2{%
\begingroup
\pgf@process{#1}%
\pgf@xa=\pgf@x%
\pgf@ya=\pgf@y%
\pgf@process{#2}%
\pgf@xb=\pgf@sys@tonumber\pgf@xa\pgf@x
\pgf@yb=\pgf@sys@tonumber\pgf@xa\pgf@y
\advance\pgf@xb by \pgf@sys@tonumber\pgf@ya\pgf@y
\advance\pgf@yb by -\pgf@sys@tonumber\pgf@ya\pgf@x
\edef\pgf@temp{%
\edef\noexpand\pgf@tmp@dot{\pgf@sys@tonumber\pgf@xb}%
\edef\noexpand\pgf@tmp@cross{\pgf@sys@tonumber\pgf@yb}%
}%
\expandafter
\endgroup\pgf@temp
}
\def\pgfpointtaxicabnorm#1{%
\ifdim\pgf@x<0pt
#1=-\pgf@x
\else
#1=\pgf@x
\fi
\ifdim\pgf@y<0pt
\advance#1 by -\pgf@y
\else
\advance#1 by \pgf@y
\fi
}
\def\pgf@offset@compute@tangents#1#2#3#4{%
\pgf@process{\pgfpointdiff{#1}{#2}}%
\pgfpointtaxicabnorm\pgf@xa
\ifdim\pgf@xa<0.1pt\relax
\pgf@process{\pgfpointdiff{#1}{#3}}%
\pgfpointtaxicabnorm\pgf@xa
\ifdim\pgf@xa<0.1pt\relax
\pgf@process{\pgfpointdiff{#1}{#4}}%
\fi
\fi
\pgfextract@process\pgf@tmp@tang@i{%
\pgfpointnormalised{}%
\global\let\pgf@nfold@tmp\pgf@tmp%
}%
\let\pgf@tmp@angle@i\pgf@nfold@tmp%
\pgf@process{\pgfpointdiff{#3}{#4}}%
\pgfpointtaxicabnorm\pgf@xa
\ifdim\pgf@xa<0.1pt\relax
\pgf@process{\pgfpointdiff{#2}{#4}}%
\pgfpointtaxicabnorm\pgf@xa
\ifdim\pgf@xa<0.1pt\relax
\pgf@process{\pgfpointdiff{#1}{#4}}%
\fi
\fi
\pgfextract@process\pgf@tmp@tang@ii{\pgfpointnormalised{}\global\let\pgf@nfold@tmp\pgf@tmp}%
\let\pgf@tmp@angle@ii\pgf@nfold@tmp%
}
\def\pgf@offset@bezier@segment#1#2#3#4#5{%
\pgf@offset@compute@tangents{#1}{#2}{#3}{#4}%
\pgf@offset@bezier@segment@{#1}{#2}{#3}{#4}{#5}%
}
\def\pgf@offset@bezier@segment@#1#2#3#4#5{%
\pgf@tmp@tang@i
\edef\pgf@tmp@normal@i{\noexpand\pgfqpoint{-\the\pgf@y}{\the\pgf@x}}%
\pgfextract@process\pgf@bezier@offset@i
{\pgfpointadd{\pgfpointscale{#5}{\pgf@tmp@normal@i}}{#1}}%
\pgf@tmp@tang@ii
\edef\pgf@tmp@normal@ii{\noexpand\pgfqpoint{-\the\pgf@y}{\the\pgf@x}}%
\pgfextract@process\pgf@bezier@offset@iv
{\pgfpointadd{\pgfpointscale{#5}{\pgf@tmp@normal@ii}}{#4}}%
\pgf@process{\pgfpointdiff{#1}{#4}}%
\pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
\let\pgf@tmp@secantlen\pgfmathresult
\ifdim\pgf@tmp@secantlen pt<0.1pt\relax
\pgfutil@packagewarning{tikz-nfold}{first and last point are too close, expect glitches}%
\pgfextract@process\pgf@bezier@offset@ii
{\pgfpointadd{\pgf@bezier@offset@i}{\pgfpointdiff{#1}{#2}}}%
\pgfextract@process\pgf@bezier@offset@iii
{\pgfpointadd{\pgf@bezier@offset@iv}{\pgfpointdiff{#4}{#3}}}%
\else
\pgfextract@process\pgf@tmp@secant{\pgfpointnormalised{}}%
\pgfmathcrossdot{}{\pgf@tmp@tang@ii}%
\ifdim\pgf@tmp@dot pt<.5pt\relax%
\pgfutil@packagewarning{tikz-nfold}{cosine of \pgf@tmp@dot\space clamped to 0.5 in non-simple segment}%
\def\pgf@tmp@dot{.5}%
\fi%
\pgfmathdivide@{\pgf@tmp@cross}{\pgf@tmp@dot}%
\let\pgf@tmp@tanbeta\pgfmathresult
\pgfmathcrossdot{\pgf@tmp@secant}{\pgfpointnormalised{\pgfpointdiff{#1}{#2}}}
\pgfmath@offset@calculate@scale{\pgf@tmp@secantlen}{\pgf@tmp@cross}{\pgf@tmp@dot}{\pgf@tmp@tanbeta}{#5}%
\pgfextract@process\pgf@bezier@offset@ii{%
\pgfpointadd
{\pgf@bezier@offset@i}
{\pgfqpointscale{\pgfmathresult}{\pgfpointdiff{#1}{#2}}}%
}%
\pgfmathcrossdot{\pgf@tmp@secant}{\pgf@tmp@tang@i}%
\ifdim\pgf@tmp@dot pt<.5pt\relax
\pgfutil@packagewarning{tikz-nfold}{cosine of \pgf@tmp@dot\space clamped to 0.5 in non-simple segment}%
\def\pgf@tmp@dot{.5}%
\fi
\pgfmathdivide@{\pgf@tmp@cross}{\pgf@tmp@dot}%
\let\pgf@tmp@tanbeta\pgfmathresult
\pgfmathcrossdot{\pgf@tmp@secant}{\pgfpointnormalised{\pgfpointdiff{#4}{#3}}}%
\pgfmath@offset@calculate@scale{\pgf@tmp@secantlen}{\pgf@tmp@cross}{\pgf@tmp@dot}{\pgf@tmp@tanbeta}{#5}%
\pgfextract@process\pgf@bezier@offset@iii{%
\pgfpointadd
{\pgf@bezier@offset@iv}
{\pgfqpointscale{\pgfmathresult}{\pgfpointdiff{#4}{#3}}}%
}%
\fi
}
\def\pgfmath@offset@calculate@scale#1#2#3#4#5{%
\begingroup
\pgfmathmultiply@{#3}{#4}%
\pgfmathsubtract@{#2}{\pgfmathresult}%
\let\pgfmath@temp\pgfmathresult
\pgfmathreciprocal@{#1}%
\pgfmathmultiply@{\pgfmathresult}{\pgfmath@temp}%
\pgfmathmultiply{\pgfmathresult}{#5}%
\pgfmathadd@{\pgfmathresult}{1}%
\pgfmath@smuggleone\pgfmathresult
\endgroup
}
\newcount\pgf@offset@max@recursion
\pgf@offset@max@recursion=4
\def\pgfoffsetcurve#1#2#3#4#5{%
\pgfoffsetcurvecallback{#1}{#2}{#3}{#4}{#5}{\pgf@nfold@callback@move}%
}
\def\pgfoffsetcurvenomove#1#2#3#4#5{%
\pgfoffsetcurvecallback{#1}{#2}{#3}{#4}{#5}{\pgf@nfold@callback@nomove}%
}
\def\pgf@nfold@callback@move#1#2#3#4#5{%
\if#50\pgfpathmoveto{#1}\fi%
\pgfpathcurveto{#2}{#3}{#4}%
}
\def\pgf@nfold@callback@nomove#1#2#3#4#5{\pgfpathcurveto{#2}{#3}{#4}}
\def\pgfoffsetcurvecallback#1#2#3#4#5#6{%
\edef\pgf@offset@tmp@callback##1##2##3##4##5{%
\noexpand\pgf@offset@bezier@segment{##1}{##2}{##3}{##4}{#5}%
\noexpand#6{\noexpand\pgf@bezier@offset@i}{\noexpand\pgf@bezier@offset@ii}{\noexpand\pgf@bezier@offset@iii}{\noexpand\pgf@bezier@offset@iv}{##5}%
}
\pgf@subdividecurve{#1}{#2}{#3}{#4}{\pgf@offset@max@recursion}{0}{\pgf@offset@tmp@callback}%
}
\newif\ifpgf@offset@subdivide
\def\pgf@subdividecurve#1#2#3#4#5#6#7{%
\begingroup%
\pgfextract@process\pgf@ctrl@i{#1}%
\pgfextract@process\pgf@ctrl@ii{#2}%
\pgfextract@process\pgf@ctrl@iii{#3}%
\pgfextract@process\pgf@ctrl@iv{#4}%
\pgf@offset@compute@tangents{\pgf@ctrl@i}{\pgf@ctrl@ii}{\pgf@ctrl@iii}{\pgf@ctrl@iv}%
\pgf@subdividecurve@{#5}{#6}{#7}%
\endgroup%
}
\def\pgf@subdividecurve@#1#2#3{%
\pgf@offset@subdividefalse%
\c@pgf@counta=#1\relax
\advance\c@pgf@counta by -1
\pgfextract@process\pgf@itoiv{\pgfpointdiff{\pgf@ctrl@i}{\pgf@ctrl@iv}}%
\pgfmathcrossproduct{\pgf@itoiv}{\pgf@tmp@tang@i}%
\let\firstcross\pgfmathresult
\pgfmathcrossproduct{\pgf@itoiv}{\pgf@tmp@tang@ii}%
\ifnum
\ifdim \firstcross pt<0pt -1\else\ifdim \firstcross pt>0pt 1\else 2\fi\fi
=\ifdim\pgfmathresult pt<0pt -1\else\ifdim\pgfmathresult pt>0pt 1\else 3\fi\fi
\relax %
\pgf@offset@subdividetrue%
\else%
\pgfmathdotproduct{\pgf@tmp@tang@i}{\pgf@tmp@tang@ii}%
\ifdim\pgfmathresult pt<.5pt\relax%
\pgf@offset@subdividetrue%
\else
\pgf@itoiv
\pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
\pgf@xa=\pgfmathresult pt
\pgf@process{\pgfpointdiff{\pgf@ctrl@i}{\pgf@ctrl@ii}}%
\pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
\pgf@xb=\pgfmathresult pt
\pgf@process{\pgfpointdiff{\pgf@ctrl@iii}{\pgf@ctrl@iv}}%
\pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
\advance\pgf@xb by \pgfmathresult pt
\ifdim\pgf@xa<\pgf@xb
\pgf@offset@subdividetrue
\fi
\fi%
\fi%
\ifpgf@offset@subdivide%
\ifnum\c@pgf@counta<0%
\pgfutil@packagewarning{tikz-nfold}{Recursion limit reached, glitches may occur. %
Consider increasing \string\pgf@offset@max@recursion}%
#3{\pgf@ctrl@i}{\pgf@ctrl@ii}{\pgf@ctrl@iii}{\pgf@ctrl@iv}{#2}%
\else
\pgf@halfsplitbezier{\pgf@ctrl@i}{\pgf@ctrl@ii}{\pgf@ctrl@iii}{\pgf@ctrl@iv}%
\pgfextract@process\pgf@middletangent{%
\pgfpointnormalised{\pgfpointdiff{\pgf@splitbezier@i@iii}{\pgf@splitbezier@i@iv}}}%
\begingroup%
\let\pgf@tmp@tang@ii\pgf@middletangent%
\let\pgf@ctrl@i\pgf@splitbezier@i@i%
\let\pgf@ctrl@ii\pgf@splitbezier@i@ii%
\let\pgf@ctrl@iii\pgf@splitbezier@i@iii%
\let\pgf@ctrl@iv\pgf@splitbezier@i@iv%
\pgf@subdividecurve@{\c@pgf@counta}{#2}{#3}%
\endgroup%
\begingroup%
\let\pgf@tmp@tang@i\pgf@middletangent%
\let\pgf@ctrl@i\pgf@splitbezier@ii@i%
\let\pgf@ctrl@ii\pgf@splitbezier@ii@ii%
\let\pgf@ctrl@iii\pgf@splitbezier@ii@iii%
\let\pgf@ctrl@iv\pgf@splitbezier@ii@iv%
\pgf@subdividecurve@{\c@pgf@counta}{1}{#3}%
\endgroup%
\fi%
\else%
#3{\pgf@ctrl@i}{\pgf@ctrl@ii}{\pgf@ctrl@iii}{\pgf@ctrl@iv}{#2}%
\fi%
}
\def\pgfoffsetline#1#2#3{%
\pgfmathparse{#3}%
\pgfoffsetline@{#1}{#2}{\pgfmathresult}{\pgfpointnormalised{\pgfpointdiff{#1}{#2}}}%
}
\def\pgfoffsetline@#1#2#3#4{%
\pgfqpointscale{#3}{#4}%
\pgf@xc=-\pgf@y
\pgf@yc=\pgf@x
\pgfpathmoveto{\pgfpointadd{#1}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}%
\pgfpathlineto{\pgfpointadd{#2}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}%
}
\def\pgfoffsetlinenomove#1#2#3{%
\pgfoffsetlinenomove@{#1}{#2}{#3}{\pgfpointnormalised{\pgfpointdiff{#1}{#2}}}%
}
\def\pgfoffsetlinenomove@#1#2#3#4{%
\pgfqpointscale{#3}{#4}%
\pgf@xc=-\pgf@y
\pgf@yc=\pgf@x
\pgfpathlineto{\pgfpointadd{#2}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}%
}