\usepackage{etoolbox}

\usetikzlibrary{math, 3d, calligraphy}

% --- styles ---

\definecolor{pwbeige}{RGB}{172, 146, 122}
\definecolor{pworange}{RGB}{245, 153, 30}

\tikzset{
  surf/.style={pwbeige!10},
  leaf/.style={thin, pwbeige!60},
  sing/.style={thick, pworange},
  ray/.style={thick}
}

% --- cotangent fibers ---

\newcommand{\setfiberscale}[1]{
  \pgfmathsetmacro{\rfiber}{#1}
  \pgfmathsetmacro{\rshade}{1.5*\rfiber}
}
\setfiberscale{1.5}
%%\newcommand{\rfiber}{1.5}
%%\pgfmathsetmacro{\rshade}{1.5*\rfiber}

\newcommand{\drawfiber}{
  \foreach \sgn in {-1, 1} {
    \calligraphy[scale=\sgn, copperplate, heavy, heavy line width=0.25mm]
      (\rfiber, \rfiber) -- (\rfiber, -\rfiber)
      (\rfiber, -\rfiber) -- (-\rfiber, -\rfiber);
  };
}

% set up PGF keys
\pgfkeys{
  /laplace/.cd,
  drop/.store in=\fiberdrop,   drop/.value required,
  shade/.store in=\fibershade, shade/.default=true,
  degree/.store in=\fiberdeg,  degree/.value required,
  phase/.store in=\fiberphase, phase/.value required,
  dis/.store in=\fiberdis,     phase/.value required,
  dual/.store in=\fiberdual,   dual/.default=true
}

\newcommand{\fiberdescender}[1]{
  \calligraphy[copperplate, light, thin] (0, -\rfiber) -- (0, -#1);
}

\newcommand{\fibershading}[2]{
  \tikzmath{
    \shadestart = (-90 - #1) / \fiberdeg;
    \shadeend = (90 - #1) / \fiberdeg;
  }
  \fill[pwbeige!30, draw=pwbeige!60] (0, 0) ++(-#1:#2) -- ++(\shadestart:\rshade) arc (\shadestart:\shadeend:\rshade) -- cycle;
}

\newenvironment{fiber}[1][]{%
  \pgfkeys{/laplace/.cd, drop=0, shade=false, degree=1, phase=0, dis=0, #1}
  \begin{scope}
    \fill[surf] (-\rfiber, -\rfiber) rectangle (\rfiber, \rfiber);
    \clip (-\rfiber, -\rfiber) rectangle (\rfiber, \rfiber);
    \tikzmath{
      if \fibershade then {
        print \fibershading{\fiberphase}{\fiberdis};
      };
    }
}{% ...
  \end{scope}
  % see TikZ docs for branching statements
  % https://tikz.dev/library-math#sec-58.5
  \tikzmath{
    if \fiberdrop > 0 then {
      print \fiberdescender{\fiberdrop};
    };
  }
  \drawfiber
}

\newcommand{\genfibercontent}[1][]{
  \pgfkeys{/laplace/.cd, dual=false, #1}
  \pgfmathsetmacro{\hatch}{\rfiber/8};
  \pgfmathsetmacro{\firsthatch}{-\rfiber+\hatch}
  \pgfmathsetmacro{\nexthatch}{-\rfiber+2*\hatch}
  \pgfmathsetmacro{\hatchstop}{\rfiber-\hatch/2}
  \foreach \y in {\firsthatch, \nexthatch, ..., \hatchstop} {
    \tikzmath{
      coordinate \drawfrom;
      coordinate \drawto;
      if \fiberdual then {
        \drawfrom = (\y, -\rfiber);
        \drawto = (\y, \rfiber);
      } else {
        \drawfrom = (-\rfiber, \y);
        \drawto = (\rfiber, \y);
      };
    }
    \draw[leaf] (\drawfrom) -- (\drawto);
  };
  \fill circle (\dotsize);
}

\newcommand{\singfibercontent}{
  % nonsingular leaves
  \foreach \sector in {30, 90, ..., 330} {
    \tikzmath{
      \farout = 45*floor((\sector + 59) / 45);
      \tfarout = 3*(\farout - \sector);
      \rfarout = \rfiber/sin(45+mod(\farout-45, 90));
    }
    \pgfmathsetmacro{\rmax}{sin(\tfarout) * pow(\rfarout, 3)}
    \foreach \r in {0.5, 1.0, ..., \rmax} {
      \pgfmathsetmacro{\win}{asin(\r/(2*\rmax))}
      \draw[leaf, rotate=\sector, domain=\win:{180-\win}, variable=\t] plot ({\t/3}:{(\r/sin(\t))^(1/3)});
    };
    
    % singular leaves
    \foreach \ang in {90, 210, 330} {
      \draw[sing] (\ang:{-sqrt(2)*\rfiber}) -- (\ang:{sqrt(2)*\rfiber});
    };
    \fill[sing] circle (\dotsize);
  };
}

% --- posititon plane ---

\pgfmathsetmacro{\hatch}{2/3}
\tikzmath{
  \phase = 15;
  \dotsize = 0.04;
  \drop = 3.5;
  \xsing = 2;
  \zsing = 4*\hatch;
  \xgen = 6;
  \zgen = 8*\hatch;
  \rcut = 1/5;
}

\newcommand{\ray}[2]{
  \draw[ray] (#1, #2) -- (8, {#2 + (8-#1)*tan(\phase)});
}

% local picture of the Laplace transform
\newcommand{\basicLaplace}{
\begin{tikzpicture}
\setfiberscale{2}

% position space
\begin{fiber}
  \genfibercontent
  \ray{-1}{0.4}
  \fill (-1, 0.4) circle (\dotsize);
  \node[anchor=north west, inner sep=2mm] at (-\rfiber, \rfiber) {$\zeta$};
\end{fiber}
\node[anchor=north, outer sep=1mm, font=\footnotesize]
  at (0, -\rfiber) {position space};

% frequency space
\begin{scope}[shift={(5.5, 0)}]
  \begin{fiber}[shade, phase=\phase, dis=0.6]
    \genfibercontent[dual]
    \node[anchor=north west, inner sep=2mm] at (-\rfiber, \rfiber) {$z$};
  \end{fiber}
  \node[anchor=north, outer sep=1mm, font=\footnotesize]
    at (0, -\rfiber) {frequency space};
\end{scope}
\end{tikzpicture}
} % \basicLaplace

% phase space picture of the Laplace transform
\newcommand{\phaseSpaceLaplace}{
\begin{tikzpicture}[z={(0.25cm, 0.2cm)}]
% position plane
\begin{scope}[canvas is xz plane at y=0]
  % surface
  \fill[surf]
    (0, 0) -- (0, \zsing-\rcut)
    -- ++(\xsing-\rcut, 0) arc (-90:90:\rcut) -- (0, {\zsing + \rcut})
    -- (0, 8) --(8, 8) -- (8, 0) -- cycle;
  
  % hatching
  \pgfmathsetmacro{\nexthatch}{2*\hatch}
  \pgfmathsetmacro{\singstop}{\zsing - \hatch/2}
  \foreach \z in {\hatch, \nexthatch, ..., \singstop} {
    \draw[leaf] (0, \z) -- (8, \z);
  };
  \pgfmathsetmacro{\singstart}{\zsing + \hatch}
  \pgfmathsetmacro{\singnext}{\zsing + 2*\hatch}
  \pgfmathsetmacro{\hatchstop}{8 - \hatch/2}
  \foreach \z in {\singstart, \singnext, ..., \hatchstop} {
    \draw[leaf] (0, \z) -- (8, \z);
  };
  
  % singular leaves
  \begin{scope}[sing]
    \draw (\xsing, \zsing) -- (8, \zsing);
    \draw (0, \zsing-\rcut) -- ++(\xsing-\rcut, 0) arc (-90:90:\rcut) -- (0, {\zsing + \rcut});
  \end{scope}
  
  % integration rays
  \ray{\xgen}{\zgen}
  \ray{\xsing}{\zsing}
  
  % outline
  \calligraphy[copperplate, heavy, heavy line width=0.25mm]
    (0, 0) -- (0, \zsing-\rcut)
    (0, \zsing+\rcut) -- (0, 8)
    (0, 8) -- (8, 8)
    (8, 8) -- (8, 0)
    (8, 0) -- (0, 0);
\end{scope}

% generic fiber
\begin{scope}[canvas is xy plane at z=\zgen, shift={(\xgen, \drop)}]
  \begin{fiber}[drop=\drop, shade, phase=\phase]
    \genfibercontent[dual]
  \end{fiber}
\end{scope}

% singular fiber
\begin{scope}[canvas is xy plane at z=\zsing, shift={(\xsing, \drop)}]
  \begin{fiber}[drop=\drop, shade, degree=3, phase=\phase]
    \singfibercontent
  \end{fiber}
\end{scope}

% generic point
\fill (\xgen, 0, \zgen) circle (\dotsize);

% singular point
\fill[sing] (\xsing, 0, \zsing) circle (\dotsize);

% labels
\begin{scope}[overlay]
  \node (surf label) at (9, 0, 4) {$B$};
  \path (surf label) ++(0, \drop, 0) node {$T^*B$};
  \node[outer sep=0.15mm, font=\footnotesize, align=left]
    (cut label) at (-1.25, 1.2, \zsing) {branch cut \\ at conical \\ singularity};
  \draw[->] (cut label) to[out=-75, in=180] (-0.25, 0, \zsing);
\end{scope}
\end{tikzpicture}
} % \phaseSpaceLaplace
