%% tikzlibrarytikzphysics.ramps.code.tex
%% -----------------------------------------------------------
%% Continuous straight and circular ramps for tikzphysics.
%%
%% Public styles: ramp, curved-ramp
%% Safe styles  : physicsramp, physicscurvedramp
%%
%% Author  : Vaibhav Blayer
%% Version : v1.1.0 (2026-08-15)
%% License : LPPL 1.3c
%% -----------------------------------------------------------

\usetikzlibrary{patterns,calc,angles}
\usetikzlibrary{tikzphysics.core}

\makeatletter

%% ============================================================
%% STATE AND DIMENSION RESOLUTION
%% ============================================================

\newdimen\tikzphysics@ramps@width
\newdimen\tikzphysics@ramps@run
\newdimen\tikzphysics@ramps@rise
\newdimen\tikzphysics@ramps@flat
\newdimen\tikzphysics@ramps@slope
\newdimen\tikzphysics@ramps@depth
\newdimen\tikzphysics@ramps@wallheight
\newdimen\tikzphysics@ramps@wallwidth
\newdimen\tikzphysics@ramps@guide
\newdimen\tikzphysics@ramps@radius
\newdimen\tikzphysics@ramps@floor
\newdimen\tikzphysics@ramps@arclength
\newdimen\tikzphysics@ramps@back
\newdimen\tikzphysics@ramps@endx
\newdimen\tikzphysics@ramps@endy
\newdimen\tikzphysics@ramps@backx

\def\tikzphysics@ramps@direction{1}
\def\tikzphysics@ramps@angle{30}
\def\tikzphysics@ramps@angleflag{0}
\def\tikzphysics@ramps@risevalue{1.5cm}
\def\tikzphysics@ramps@riseflag{0}
\def\tikzphysics@ramps@runvalue{2.6cm}
\def\tikzphysics@ramps@depthvalue{0.25cm}
\def\tikzphysics@ramps@wallheightvalue{1.5cm}
\def\tikzphysics@ramps@wallwidthvalue{0.25cm}
\def\tikzphysics@ramps@guidevalue{0.5cm}
\def\tikzphysics@ramps@radiusvalue{4cm}
\def\tikzphysics@ramps@curveangle{90}
\def\tikzphysics@ramps@floorvalue{2cm}
\def\tikzphysics@ramps@backvalue{1cm}

\newcommand{\tikzphysics@ramps@setstraightdims}{%
  \pgfmathsetlength{\tikzphysics@ramps@width}{\pgfkeysvalueof{/pgf/minimum width}}%
  \tikzphysics@resolve@length{\tikzphysics@ramps@run}{\tikzphysics@ramps@runvalue}%
  \tikzphysics@resolve@length{\tikzphysics@ramps@depth}{\tikzphysics@ramps@depthvalue}%
  \tikzphysics@resolve@length{\tikzphysics@ramps@wallheight}{\tikzphysics@ramps@wallheightvalue}%
  \tikzphysics@resolve@length{\tikzphysics@ramps@wallwidth}{\tikzphysics@ramps@wallwidthvalue}%
  \tikzphysics@resolve@length{\tikzphysics@ramps@guide}{\tikzphysics@ramps@guidevalue}%
  \ifdim\tikzphysics@ramps@run<\tikzphysics@ramps@width\relax\else
    \PackageError{tikzphysics}{ramp run must be smaller than the overall ramp width}%
      {Increase minimum width or reduce ramp run.}%
  \fi
  \ifnum\tikzphysics@ramps@angleflag=1
    \ifdim\tikzphysics@ramps@angle pt>0pt\relax\else
      \PackageError{tikzphysics}{ramp angle must be greater than 0 degrees}%
        {Choose an angle strictly between 0 and 90 degrees.}%
    \fi
    \ifdim\tikzphysics@ramps@angle pt<90pt\relax\else
      \PackageError{tikzphysics}{ramp angle must be less than 90 degrees}%
        {Choose an angle strictly between 0 and 90 degrees.}%
    \fi
    \pgfmathsetlength{\tikzphysics@ramps@rise}%
      {\tikzphysics@ramps@run*tan(\tikzphysics@ramps@angle)}%
  \else
    \ifnum\tikzphysics@ramps@riseflag=1
      \tikzphysics@resolve@length{\tikzphysics@ramps@rise}{\tikzphysics@ramps@risevalue}%
      \pgfmathsetmacro{\tikzphysics@ramps@angle}%
        {atan(\tikzphysics@ramps@rise/\tikzphysics@ramps@run)}%
    \else
      \pgfmathsetlength{\tikzphysics@ramps@rise}%
        {\tikzphysics@ramps@run*tan(\tikzphysics@ramps@angle)}%
    \fi
  \fi
  \tikzphysics@ramps@flat=\dimexpr\tikzphysics@ramps@width-\tikzphysics@ramps@run\relax
  \pgfmathsetlength{\tikzphysics@ramps@slope}%
    {veclen(\tikzphysics@ramps@run,\tikzphysics@ramps@rise)}%
}

\newcommand{\tikzphysics@ramps@setcurveddims}{%
  \tikzphysics@resolve@length{\tikzphysics@ramps@radius}{\tikzphysics@ramps@radiusvalue}%
  \tikzphysics@resolve@length{\tikzphysics@ramps@floor}{\tikzphysics@ramps@floorvalue}%
  \tikzphysics@resolve@length{\tikzphysics@ramps@depth}{\tikzphysics@ramps@depthvalue}%
  \tikzphysics@resolve@length{\tikzphysics@ramps@back}{\tikzphysics@ramps@backvalue}%
  \tikzphysics@resolve@length{\tikzphysics@ramps@guide}{\tikzphysics@ramps@guidevalue}%
  \ifdim\tikzphysics@ramps@curveangle pt>0pt\relax\else
    \PackageError{tikzphysics}{curved ramp angle must be greater than 0 degrees}%
      {Choose an angle greater than 0 and at most 90 degrees.}%
  \fi
  \ifdim\tikzphysics@ramps@curveangle pt>90pt\relax
    \PackageError{tikzphysics}{curved ramp angle must not exceed 90 degrees}%
      {The filled monotone ramp body supports circular sweeps up to 90 degrees.}%
  \fi
  \pgfmathsetlength{\tikzphysics@ramps@endx}%
    {\tikzphysics@ramps@radius*sin(\tikzphysics@ramps@curveangle)}%
  \pgfmathsetlength{\tikzphysics@ramps@endy}%
    {\tikzphysics@ramps@radius*(1-cos(\tikzphysics@ramps@curveangle))}%
  \pgfmathsetmacro{\tikzphysics@ramps@@arcfactor}%
    {pi*\tikzphysics@ramps@curveangle/180}%
  \pgfmathsetlength{\tikzphysics@ramps@arclength}%
    {\tikzphysics@ramps@@arcfactor*\tikzphysics@ramps@radius}%
  \tikzphysics@ramps@backx=\dimexpr\tikzphysics@ramps@endx+\tikzphysics@ramps@back\relax
}

%% ============================================================
%% KEYS
%% ============================================================

\tikzset{
  ramp direction/.is choice,
  ramp direction/right/.code={\def\tikzphysics@ramps@direction{1}},
  ramp direction/left/.code={\def\tikzphysics@ramps@direction{-1}},
  ramp run/.code={\def\tikzphysics@ramps@runvalue{#1}},
  ramp rise/.code={\def\tikzphysics@ramps@risevalue{#1}\def\tikzphysics@ramps@riseflag{1}},
  ramp angle/.code={\def\tikzphysics@ramps@angle{#1}\def\tikzphysics@ramps@angleflag{1}},
  ramp depth/.code={\def\tikzphysics@ramps@depthvalue{#1}},
  ramp wall height/.code={\def\tikzphysics@ramps@wallheightvalue{#1}},
  ramp wall width/.code={\def\tikzphysics@ramps@wallwidthvalue{#1}},
  ramp guide length/.code={\def\tikzphysics@ramps@guidevalue{#1}},
  curved ramp radius/.code={\def\tikzphysics@ramps@radiusvalue{#1}},
  curved ramp angle/.code={\def\tikzphysics@ramps@curveangle{#1}},
  curved ramp floor length/.code={\def\tikzphysics@ramps@floorvalue{#1}},
  curved ramp back extension/.code={\def\tikzphysics@ramps@backvalue{#1}},
  physics ramp direction/.style={ramp direction={#1}},
  physics ramp run/.style={ramp run={#1}},
  physics ramp rise/.style={ramp rise={#1}},
  physics ramp angle/.style={ramp angle={#1}},
  physics ramp depth/.style={ramp depth={#1}},
  physics ramp wall height/.style={ramp wall height={#1}},
  physics ramp wall width/.style={ramp wall width={#1}},
  physics ramp guide length/.style={ramp guide length={#1}},
  physics curved ramp radius/.style={curved ramp radius={#1}},
  physics curved ramp angle/.style={curved ramp angle={#1}},
  physics curved ramp floor length/.style={curved ramp floor length={#1}},
  physics curved ramp back extension/.style={curved ramp back extension={#1}},
}

%% ============================================================
%% PARAMETRIC ANCHOR DECLARERS
%% ============================================================

\def\tikzphysics@ramps@straightpoint#1{%
  \ifnum#1=0\relax
    \pgf@x=0pt \pgf@y=0pt
  \else\ifnum#1=100\relax
    \pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@width}%
    \pgf@y=\tikzphysics@ramps@sr@rise\relax
  \else
    \pgfmathsetlength{\@tempdima}%
      {(#1/100)*(\tikzphysics@ramps@sr@flat+\tikzphysics@ramps@sr@slope)}%
    \ifdim\@tempdima<\tikzphysics@ramps@sr@flat\relax
      \pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@sr@dir*\@tempdima}%
      \pgf@y=0pt
    \else
      \advance\@tempdima by -\tikzphysics@ramps@sr@flat\relax
      \pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@sr@dir*(\tikzphysics@ramps@sr@flat+\@tempdima*\tikzphysics@ramps@sr@run/\tikzphysics@ramps@sr@slope)}%
      \pgfmathsetlength{\pgf@y}{\@tempdima*\tikzphysics@ramps@sr@rise/\tikzphysics@ramps@sr@slope}%
    \fi
  \fi\fi
}

\def\tikzphysics@ramps@straightvector#1#2{%
  \pgfmathsetlength{\@tempdima}%
    {(#1/100)*(\tikzphysics@ramps@sr@flat+\tikzphysics@ramps@sr@slope)}%
  \ifdim\@tempdima<\tikzphysics@ramps@sr@flat\relax
    \def\tikzphysics@ramps@@theta{0}%
  \else
    \edef\tikzphysics@ramps@@theta{\tikzphysics@ramps@sr@angle}%
  \fi
  \tikzphysics@ramps@straightpoint{#1}%
  \@tempdima=\pgf@x \@tempdimb=\pgf@y
  \def\tikzphysics@ramps@@before{before}%
  \def\tikzphysics@ramps@@after{after}%
  \def\tikzphysics@ramps@@normal{normal}%
  \def\tikzphysics@ramps@@kind{#2}%
  \ifx\tikzphysics@ramps@@kind\tikzphysics@ramps@@before
    \pgfmathsetlength{\pgf@x}{\@tempdima-0.5*\tikzphysics@ramps@sr@guide*\tikzphysics@ramps@sr@dir*cos(\tikzphysics@ramps@@theta)}%
    \pgfmathsetlength{\pgf@y}{\@tempdimb-0.5*\tikzphysics@ramps@sr@guide*sin(\tikzphysics@ramps@@theta)}%
  \else\ifx\tikzphysics@ramps@@kind\tikzphysics@ramps@@after
    \pgfmathsetlength{\pgf@x}{\@tempdima+0.5*\tikzphysics@ramps@sr@guide*\tikzphysics@ramps@sr@dir*cos(\tikzphysics@ramps@@theta)}%
    \pgfmathsetlength{\pgf@y}{\@tempdimb+0.5*\tikzphysics@ramps@sr@guide*sin(\tikzphysics@ramps@@theta)}%
  \else
    \pgfmathsetlength{\pgf@x}{\@tempdima-\tikzphysics@ramps@sr@guide*\tikzphysics@ramps@sr@dir*sin(\tikzphysics@ramps@@theta)}%
    \pgfmathsetlength{\pgf@y}{\@tempdimb+\tikzphysics@ramps@sr@guide*cos(\tikzphysics@ramps@@theta)}%
  \fi\fi
}

\def\tikzphysics@ramps@declarestraight@one#1{%
  \anchor{surface-#1}{\tikzphysics@ramps@straightpoint{#1}}%
  \anchor{#1}{\tikzphysics@ramps@straightpoint{#1}}%
  \anchor{tangent-before-#1}{\tikzphysics@ramps@straightvector{#1}{before}}%
  \anchor{tangent-after-#1}{\tikzphysics@ramps@straightvector{#1}{after}}%
  \anchor{normal-#1}{\tikzphysics@ramps@straightvector{#1}{normal}}%
}

\def\tikzphysics@ramps@declarestraightanchors{%
  \foreach \tikzphysics@@t in {0,1,...,100}{%
    \edef\tikzphysics@@partial{\noexpand\tikzphysics@ramps@declarestraight@one{\tikzphysics@@t}}%
    \tikzphysics@@partial
  }%
}

%% Point at a fraction of the circular portion only.
\def\tikzphysics@ramps@curvearcpoint#1{%
  \pgfmathsetmacro{\tikzphysics@ramps@@phi}{(#1/100)*\tikzphysics@ramps@cr@angle}%
  \pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@radius*sin(\tikzphysics@ramps@@phi)}%
  \pgfmathsetlength{\pgf@y}{\tikzphysics@ramps@cr@radius*(1-cos(\tikzphysics@ramps@@phi))}%
}

%% Point at a fraction of the complete floor-plus-arc contact surface.
%% Parameterization is by physical arc length, matching the straight ramp.
\def\tikzphysics@ramps@curvepoint#1{%
  \ifnum#1=0\relax
    \pgfmathsetlength{\pgf@x}{-\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@floor}%
    \pgf@y=0pt
  \else\ifnum#1=100\relax
    \pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@endx}%
    \pgf@y=\tikzphysics@ramps@cr@endy\relax
  \else
    \pgfmathsetlength{\@tempdima}%
      {(#1/100)*(\tikzphysics@ramps@cr@floor+\tikzphysics@ramps@cr@arclength)}%
    \ifdim\@tempdima<\tikzphysics@ramps@cr@floor\relax
      \pgfmathsetlength{\pgf@x}%
        {\tikzphysics@ramps@cr@dir*(-\tikzphysics@ramps@cr@floor+\@tempdima)}%
      \pgf@y=0pt
    \else
      \advance\@tempdima by -\tikzphysics@ramps@cr@floor\relax
      \pgfmathsetmacro{\tikzphysics@ramps@@phi}%
        {\@tempdima/\tikzphysics@ramps@cr@arclength*\tikzphysics@ramps@cr@angle}%
      \pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@radius*sin(\tikzphysics@ramps@@phi)}%
      \pgfmathsetlength{\pgf@y}{\tikzphysics@ramps@cr@radius*(1-cos(\tikzphysics@ramps@@phi))}%
    \fi
  \fi\fi
}

\def\tikzphysics@ramps@curvevector#1#2{%
  \pgfmathsetlength{\@tempdima}%
    {(#1/100)*(\tikzphysics@ramps@cr@floor+\tikzphysics@ramps@cr@arclength)}%
  \ifdim\@tempdima<\tikzphysics@ramps@cr@floor\relax
    \def\tikzphysics@ramps@@phi{0}%
  \else
    \advance\@tempdima by -\tikzphysics@ramps@cr@floor\relax
    \pgfmathsetmacro{\tikzphysics@ramps@@phi}%
      {min(\tikzphysics@ramps@cr@angle,\@tempdima/\tikzphysics@ramps@cr@arclength*\tikzphysics@ramps@cr@angle)}%
  \fi
  \tikzphysics@ramps@curvepoint{#1}%
  \@tempdima=\pgf@x \@tempdimb=\pgf@y
  \def\tikzphysics@ramps@@before{before}%
  \def\tikzphysics@ramps@@after{after}%
  \def\tikzphysics@ramps@@kind{#2}%
  \ifx\tikzphysics@ramps@@kind\tikzphysics@ramps@@before
    \pgfmathsetlength{\pgf@x}{\@tempdima-0.5*\tikzphysics@ramps@cr@guide*\tikzphysics@ramps@cr@dir*cos(\tikzphysics@ramps@@phi)}%
    \pgfmathsetlength{\pgf@y}{\@tempdimb-0.5*\tikzphysics@ramps@cr@guide*sin(\tikzphysics@ramps@@phi)}%
  \else\ifx\tikzphysics@ramps@@kind\tikzphysics@ramps@@after
    \pgfmathsetlength{\pgf@x}{\@tempdima+0.5*\tikzphysics@ramps@cr@guide*\tikzphysics@ramps@cr@dir*cos(\tikzphysics@ramps@@phi)}%
    \pgfmathsetlength{\pgf@y}{\@tempdimb+0.5*\tikzphysics@ramps@cr@guide*sin(\tikzphysics@ramps@@phi)}%
  \else
    \pgfmathsetlength{\pgf@x}{\@tempdima-\tikzphysics@ramps@cr@guide*\tikzphysics@ramps@cr@dir*sin(\tikzphysics@ramps@@phi)}%
    \pgfmathsetlength{\pgf@y}{\@tempdimb+\tikzphysics@ramps@cr@guide*cos(\tikzphysics@ramps@@phi)}%
  \fi\fi
}

%% Orientation helpers at a fraction of the circular portion only.
\def\tikzphysics@ramps@curvearcvector#1#2{%
  \pgfmathsetmacro{\tikzphysics@ramps@@phi}{(#1/100)*\tikzphysics@ramps@cr@angle}%
  \tikzphysics@ramps@curvearcpoint{#1}%
  \@tempdima=\pgf@x \@tempdimb=\pgf@y
  \def\tikzphysics@ramps@@before{before}%
  \def\tikzphysics@ramps@@after{after}%
  \def\tikzphysics@ramps@@kind{#2}%
  \ifx\tikzphysics@ramps@@kind\tikzphysics@ramps@@before
    \pgfmathsetlength{\pgf@x}{\@tempdima-0.5*\tikzphysics@ramps@cr@guide*\tikzphysics@ramps@cr@dir*cos(\tikzphysics@ramps@@phi)}%
    \pgfmathsetlength{\pgf@y}{\@tempdimb-0.5*\tikzphysics@ramps@cr@guide*sin(\tikzphysics@ramps@@phi)}%
  \else\ifx\tikzphysics@ramps@@kind\tikzphysics@ramps@@after
    \pgfmathsetlength{\pgf@x}{\@tempdima+0.5*\tikzphysics@ramps@cr@guide*\tikzphysics@ramps@cr@dir*cos(\tikzphysics@ramps@@phi)}%
    \pgfmathsetlength{\pgf@y}{\@tempdimb+0.5*\tikzphysics@ramps@cr@guide*sin(\tikzphysics@ramps@@phi)}%
  \else
    \pgfmathsetlength{\pgf@x}{\@tempdima-\tikzphysics@ramps@cr@guide*\tikzphysics@ramps@cr@dir*sin(\tikzphysics@ramps@@phi)}%
    \pgfmathsetlength{\pgf@y}{\@tempdimb+\tikzphysics@ramps@cr@guide*cos(\tikzphysics@ramps@@phi)}%
  \fi\fi
}

\def\tikzphysics@ramps@declarecurve@one#1{%
  \anchor{surface-#1}{\tikzphysics@ramps@curvepoint{#1}}%
  \anchor{#1}{\tikzphysics@ramps@curvepoint{#1}}%
  \anchor{curve-#1}{\tikzphysics@ramps@curvearcpoint{#1}}%
  \anchor{curve-tangent-before-#1}{\tikzphysics@ramps@curvearcvector{#1}{before}}%
  \anchor{curve-tangent-after-#1}{\tikzphysics@ramps@curvearcvector{#1}{after}}%
  \anchor{curve-normal-#1}{\tikzphysics@ramps@curvearcvector{#1}{normal}}%
  \anchor{tangent-before-#1}{\tikzphysics@ramps@curvevector{#1}{before}}%
  \anchor{tangent-after-#1}{\tikzphysics@ramps@curvevector{#1}{after}}%
  \anchor{normal-#1}{\tikzphysics@ramps@curvevector{#1}{normal}}%
}

\def\tikzphysics@ramps@declarecurveanchors{%
  \foreach \tikzphysics@@t in {0,1,...,100}{%
    \edef\tikzphysics@@partial{\noexpand\tikzphysics@ramps@declarecurve@one{\tikzphysics@@t}}%
    \tikzphysics@@partial
  }%
}

%% A PGF point whose x coordinate is mirrored by the current saved direction.
%% This helper is important: concatenating the token `1' with a dimension such
%% as `8cm' would mean 18cm to TeX, not 1 times 8cm.
\def\tikzphysics@ramps@straightpathpoint#1#2{%
  \pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@sr@dir*(#1)}%
  \pgfmathsetlength{\pgf@y}{#2}%
}
\def\tikzphysics@ramps@curvepathpoint#1#2{%
  \pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@cr@dir*(#1)}%
  \pgfmathsetlength{\pgf@y}{#2}%
}

%% ============================================================
%% STRAIGHT RAMP
%% ============================================================

\pgfdeclareshape{physicsramp}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchorborder[from=rectangle]
  \savedmacro{\tikzphysics@ramps@sr@width}{\tikzphysics@ramps@setstraightdims\edef\tikzphysics@ramps@sr@width{\the\tikzphysics@ramps@width}}
  \savedmacro{\tikzphysics@ramps@sr@run}{\tikzphysics@ramps@setstraightdims\edef\tikzphysics@ramps@sr@run{\the\tikzphysics@ramps@run}}
  \savedmacro{\tikzphysics@ramps@sr@rise}{\tikzphysics@ramps@setstraightdims\edef\tikzphysics@ramps@sr@rise{\the\tikzphysics@ramps@rise}}
  \savedmacro{\tikzphysics@ramps@sr@flat}{\tikzphysics@ramps@setstraightdims\edef\tikzphysics@ramps@sr@flat{\the\tikzphysics@ramps@flat}}
  \savedmacro{\tikzphysics@ramps@sr@slope}{\tikzphysics@ramps@setstraightdims\edef\tikzphysics@ramps@sr@slope{\the\tikzphysics@ramps@slope}}
  \savedmacro{\tikzphysics@ramps@sr@depth}{\tikzphysics@ramps@setstraightdims\edef\tikzphysics@ramps@sr@depth{\the\tikzphysics@ramps@depth}}
  \savedmacro{\tikzphysics@ramps@sr@wallheight}{\tikzphysics@ramps@setstraightdims\edef\tikzphysics@ramps@sr@wallheight{\the\tikzphysics@ramps@wallheight}}
  \savedmacro{\tikzphysics@ramps@sr@wallwidth}{\tikzphysics@ramps@setstraightdims\edef\tikzphysics@ramps@sr@wallwidth{\the\tikzphysics@ramps@wallwidth}}
  \savedmacro{\tikzphysics@ramps@sr@guide}{\tikzphysics@ramps@setstraightdims\edef\tikzphysics@ramps@sr@guide{\the\tikzphysics@ramps@guide}}
  \savedmacro{\tikzphysics@ramps@sr@angle}{\tikzphysics@ramps@setstraightdims\edef\tikzphysics@ramps@sr@angle{\tikzphysics@ramps@angle}}
  \savedmacro{\tikzphysics@ramps@sr@dir}{\edef\tikzphysics@ramps@sr@dir{\tikzphysics@ramps@direction}}

  \anchor{center}{\pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@sr@dir*(\tikzphysics@ramps@sr@width-\tikzphysics@ramps@sr@wallwidth)/2}\pgfmathsetlength{\pgf@y}{(\tikzphysics@ramps@sr@rise-\tikzphysics@ramps@sr@depth)/2}}
  \anchor{surface-start}{\pgf@x=0pt\pgf@y=0pt}
  \anchor{surface-mid}{\tikzphysics@ramps@straightpoint{50}}
  \anchor{surface-end}{\pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@width}\pgf@y=\tikzphysics@ramps@sr@rise}
  \anchor{floor-start}{\pgf@x=0pt\pgf@y=0pt}
  \anchor{floor-mid}{\pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@sr@dir*0.5*\tikzphysics@ramps@sr@flat}\pgf@y=0pt}
  \anchor{floor-end}{\pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@flat}\pgf@y=0pt}
  \anchor{ramp-foot}{\pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@flat}\pgf@y=0pt}
  \anchor{ramp-mid}{\pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@sr@dir*(\tikzphysics@ramps@sr@flat+0.5*\tikzphysics@ramps@sr@run)}\pgfmathsetlength{\pgf@y}{0.5*\tikzphysics@ramps@sr@rise}}
  \anchor{ramp-top}{\pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@width}\pgf@y=\tikzphysics@ramps@sr@rise}
  \anchor{wall-top}{\pgf@x=0pt\pgf@y=\tikzphysics@ramps@sr@wallheight}
  \anchor{wall-mid}{\pgf@x=0pt\pgfmathsetlength{\pgf@y}{0.5*\tikzphysics@ramps@sr@wallheight}}
  \anchor{wall-bottom}{\pgf@x=0pt\pgf@y=0pt}
  \anchor{base-start}{\pgfmathsetlength{\pgf@x}{-\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@wallwidth}\pgf@y=-\tikzphysics@ramps@sr@depth}
  \anchor{base-end}{\pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@width}\pgf@y=-\tikzphysics@ramps@sr@depth}
  %% Angle-mark helpers.  The first/second ordering always selects the acute
  %% angle, including on a left-facing mirrored ramp.
  \anchor{angle-baseline}{\pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@sr@dir*(\tikzphysics@ramps@sr@flat+1.2cm)}\pgf@y=0pt}
  \anchor{angle-label}{\pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@sr@dir*(\tikzphysics@ramps@sr@flat+1.05cm*cos(0.5*\tikzphysics@ramps@sr@angle))}\pgfmathsetlength{\pgf@y}{1.05cm*sin(0.5*\tikzphysics@ramps@sr@angle)}}
  \anchor{angle-first}{%
    \ifnum\tikzphysics@ramps@sr@dir=1
      \pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@sr@flat+1.2cm}\pgf@y=0pt
    \else
      \pgf@x=-\tikzphysics@ramps@sr@width\pgf@y=\tikzphysics@ramps@sr@rise
    \fi}
  \anchor{angle-second}{%
    \ifnum\tikzphysics@ramps@sr@dir=1
      \pgf@x=\tikzphysics@ramps@sr@width\pgf@y=\tikzphysics@ramps@sr@rise
    \else
      \pgfmathsetlength{\pgf@x}{-(\tikzphysics@ramps@sr@flat+1.2cm)}\pgf@y=0pt
    \fi}

  \backgroundpath{%
    \pgfpathmoveto{\pgfpoint{0pt}{\tikzphysics@ramps@sr@wallheight}}%
    \pgfpathlineto{\pgfpoint{0pt}{0pt}}%
    \pgfpathlineto{\tikzphysics@ramps@straightpathpoint{\tikzphysics@ramps@sr@flat}{0pt}}%
    \pgfpathlineto{\tikzphysics@ramps@straightpathpoint{\tikzphysics@ramps@sr@width}{\tikzphysics@ramps@sr@rise}}%
    \pgfpathlineto{\tikzphysics@ramps@straightpathpoint{\tikzphysics@ramps@sr@width}{-\tikzphysics@ramps@sr@depth}}%
    \pgfpathlineto{\tikzphysics@ramps@straightpathpoint{-\tikzphysics@ramps@sr@wallwidth}{-\tikzphysics@ramps@sr@depth}}%
    \pgfpathlineto{\tikzphysics@ramps@straightpathpoint{-\tikzphysics@ramps@sr@wallwidth}{\tikzphysics@ramps@sr@wallheight}}%
    \pgfpathclose
  }
  \foregroundpath{%
    \pgfsetlinewidth{0.5pt}%
    \pgfpathmoveto{\pgfpoint{0pt}{\tikzphysics@ramps@sr@wallheight}}%
    \pgfpathlineto{\pgfpoint{0pt}{0pt}}%
    \pgfpathlineto{\tikzphysics@ramps@straightpathpoint{\tikzphysics@ramps@sr@flat}{0pt}}%
    \pgfpathlineto{\tikzphysics@ramps@straightpathpoint{\tikzphysics@ramps@sr@width}{\tikzphysics@ramps@sr@rise}}%
    \pgfusepath{stroke}%
  }
  \tikzphysics@ramps@declarestraightanchors
}

%% ============================================================
%% CIRCULAR CURVED RAMP
%% ============================================================

\pgfdeclareshape{physicscurvedramp}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchorborder[from=rectangle]
  \savedmacro{\tikzphysics@ramps@cr@radius}{\tikzphysics@ramps@setcurveddims\edef\tikzphysics@ramps@cr@radius{\the\tikzphysics@ramps@radius}}
  \savedmacro{\tikzphysics@ramps@cr@floor}{\tikzphysics@ramps@setcurveddims\edef\tikzphysics@ramps@cr@floor{\the\tikzphysics@ramps@floor}}
  \savedmacro{\tikzphysics@ramps@cr@arclength}{\tikzphysics@ramps@setcurveddims\edef\tikzphysics@ramps@cr@arclength{\the\tikzphysics@ramps@arclength}}
  \savedmacro{\tikzphysics@ramps@cr@depth}{\tikzphysics@ramps@setcurveddims\edef\tikzphysics@ramps@cr@depth{\the\tikzphysics@ramps@depth}}
  \savedmacro{\tikzphysics@ramps@cr@back}{\tikzphysics@ramps@setcurveddims\edef\tikzphysics@ramps@cr@back{\the\tikzphysics@ramps@back}}
  \savedmacro{\tikzphysics@ramps@cr@endx}{\tikzphysics@ramps@setcurveddims\edef\tikzphysics@ramps@cr@endx{\the\tikzphysics@ramps@endx}}
  \savedmacro{\tikzphysics@ramps@cr@endy}{\tikzphysics@ramps@setcurveddims\edef\tikzphysics@ramps@cr@endy{\the\tikzphysics@ramps@endy}}
  \savedmacro{\tikzphysics@ramps@cr@backx}{\tikzphysics@ramps@setcurveddims\edef\tikzphysics@ramps@cr@backx{\the\tikzphysics@ramps@backx}}
  \savedmacro{\tikzphysics@ramps@cr@guide}{\tikzphysics@ramps@setcurveddims\edef\tikzphysics@ramps@cr@guide{\the\tikzphysics@ramps@guide}}
  \savedmacro{\tikzphysics@ramps@cr@angle}{\edef\tikzphysics@ramps@cr@angle{\tikzphysics@ramps@curveangle}}
  \savedmacro{\tikzphysics@ramps@cr@dir}{\edef\tikzphysics@ramps@cr@dir{\tikzphysics@ramps@direction}}

  \anchor{center}{\pgfmathsetlength{\pgf@x}{0.5*\tikzphysics@ramps@cr@dir*(\tikzphysics@ramps@cr@backx-\tikzphysics@ramps@cr@floor)}\pgfmathsetlength{\pgf@y}{0.5*(\tikzphysics@ramps@cr@endy-\tikzphysics@ramps@cr@depth)}}
  \anchor{surface-start}{\pgfmathsetlength{\pgf@x}{-\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@floor}\pgf@y=0pt}
  \anchor{surface-mid}{\tikzphysics@ramps@curvepoint{50}}
  \anchor{surface-end}{\pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@endx}\pgf@y=\tikzphysics@ramps@cr@endy}
  \anchor{curve-center}{\pgf@x=0pt\pgf@y=\tikzphysics@ramps@cr@radius}
  \anchor{curve-start}{\pgf@x=0pt\pgf@y=0pt}
  \anchor{curve-mid}{\tikzphysics@ramps@curvearcpoint{50}}
  \anchor{curve-end}{\pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@endx}\pgf@y=\tikzphysics@ramps@cr@endy}
  \anchor{floor-start}{\pgfmathsetlength{\pgf@x}{-\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@floor}\pgf@y=0pt}
  \anchor{floor-mid}{\pgfmathsetlength{\pgf@x}{-0.5*\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@floor}\pgf@y=0pt}
  \anchor{floor-end}{\pgf@x=0pt\pgf@y=0pt}
  \anchor{base-start}{\pgfmathsetlength{\pgf@x}{-\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@floor}\pgf@y=-\tikzphysics@ramps@cr@depth}
  \anchor{base-end}{\pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@backx}\pgf@y=-\tikzphysics@ramps@cr@depth}
  \anchor{back-top}{\pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@backx}\pgf@y=\tikzphysics@ramps@cr@endy}
  \anchor{back-bottom}{\pgfmathsetlength{\pgf@x}{\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@backx}\pgf@y=-\tikzphysics@ramps@cr@depth}

  \backgroundpath{%
    \pgfpathmoveto{\tikzphysics@ramps@curvepathpoint{-\tikzphysics@ramps@cr@floor}{0pt}}%
    \pgfpathlineto{\pgfpoint{0pt}{0pt}}%
    \ifnum\tikzphysics@ramps@cr@dir=1
      \pgfpatharc{-90}{-90+\tikzphysics@ramps@cr@angle}{\tikzphysics@ramps@cr@radius}%
    \else
      \pgfpatharc{270}{270-\tikzphysics@ramps@cr@angle}{\tikzphysics@ramps@cr@radius}%
    \fi
    \pgfpathlineto{\tikzphysics@ramps@curvepathpoint{\tikzphysics@ramps@cr@backx}{\tikzphysics@ramps@cr@endy}}%
    \pgfpathlineto{\tikzphysics@ramps@curvepathpoint{\tikzphysics@ramps@cr@backx}{-\tikzphysics@ramps@cr@depth}}%
    \pgfpathlineto{\tikzphysics@ramps@curvepathpoint{-\tikzphysics@ramps@cr@floor}{-\tikzphysics@ramps@cr@depth}}%
    \pgfpathclose
  }
  \foregroundpath{%
    \pgfsetlinewidth{0.5pt}%
    \pgfpathmoveto{\tikzphysics@ramps@curvepathpoint{-\tikzphysics@ramps@cr@floor}{0pt}}%
    \pgfpathlineto{\pgfpoint{0pt}{0pt}}%
    \ifnum\tikzphysics@ramps@cr@dir=1
      \pgfpatharc{-90}{-90+\tikzphysics@ramps@cr@angle}{\tikzphysics@ramps@cr@radius}%
    \else
      \pgfpatharc{270}{270-\tikzphysics@ramps@cr@angle}{\tikzphysics@ramps@cr@radius}%
    \fi
    \pgfusepath{stroke}%
  }
  \tikzphysics@ramps@declarecurveanchors
}

%% Draw the acute incline angle at a named straight-ramp node.
%% Usage: \physicsrampangle[<pic options>]{<node>}{<label>}
\newcommand{\physicsrampangle}[3][]{%
  \draw[dashed] (#2.ramp-foot) -- (#2.angle-baseline);%
  \coordinate (tikzphysics-angle-first-#2) at (#2.angle-first);%
  \coordinate (tikzphysics-angle-foot-#2) at (#2.ramp-foot);%
  \coordinate (tikzphysics-angle-second-#2) at (#2.angle-second);%
  \pic[draw,->,angle radius=8mm,#1]
    {angle=tikzphysics-angle-first-#2--tikzphysics-angle-foot-#2--tikzphysics-angle-second-#2};%
  \node[ramp angle label style] at (#2.angle-label) {#3};%
}

%% Debug data intentionally lists the native sizing key first.
\tikzphysics@registeranchors{physicsramp}{center,surface-start,surface-mid,surface-end,floor-start,floor-mid,floor-end,ramp-foot,ramp-mid,ramp-top,wall-top,wall-mid,wall-bottom,angle-baseline,angle-label,surface-25,surface-50,surface-75,tangent-before-50,tangent-after-50,normal-50}
\tikzphysics@registerkeys{physicsramp}{minimum width,ramp run,ramp rise,ramp angle,ramp depth,ramp wall height,ramp wall width,ramp direction,ramp guide length}
\tikzphysics@registerkeydefaults{physicsramp}{minimum width/8.6cm,ramp run/2.6cm,ramp rise/derived,ramp angle/30,ramp depth/0.25cm,ramp wall height/1.5cm,ramp wall width/0.25cm,ramp direction/right,ramp guide length/0.5cm}
\tikzphysics@registeranchors{physicscurvedramp}{center,surface-start,surface-mid,surface-end,floor-start,floor-mid,floor-end,curve-start,curve-mid,curve-end,curve-center,base-start,base-end,back-top,back-bottom,surface-25,surface-50,surface-75,curve-25,curve-50,curve-75,tangent-before-50,tangent-after-50,normal-50,curve-tangent-before-50,curve-tangent-after-50,curve-normal-50}
\tikzphysics@registerkeys{physicscurvedramp}{curved ramp floor length,curved ramp radius,curved ramp angle,curved ramp back extension,ramp depth,ramp direction,ramp guide length}
\tikzphysics@registerkeydefaults{physicscurvedramp}{curved ramp floor length/2cm,curved ramp radius/4cm,curved ramp angle/90,curved ramp back extension/1cm,ramp depth/0.25cm,ramp direction/right,ramp guide length/0.5cm}

\tikzset{
  ramp angle label style/.style={fill=white,inner sep=1pt,outer sep=0pt},
  physicsramp/.style={
    shape=physicsramp, physics logical shape=physicsramp,
    anchor=surface-start, draw=none, fill=white,
    pattern=north east lines, pattern color=black,
    inner sep=0pt, outer sep=0pt, minimum width=8.6cm,
  },
  physicscurvedramp/.style={
    shape=physicscurvedramp, physics logical shape=physicscurvedramp,
    anchor=surface-start, draw=none, fill=white,
    pattern=north east lines, pattern color=black,
    inner sep=0pt, outer sep=0pt,
  },
  ramp/.style={physicsramp},
  curved-ramp/.style={physicscurvedramp},
  ramp-left/.style={physicsramp,ramp direction=left},
  curved-ramp-left/.style={physicscurvedramp,ramp direction=left},
}

\makeatother
\endinput
%% End of file `tikzlibrarytikzphysics.ramps.code.tex'.
