%% 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}}}%
}