%% 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.7.0 (2026-09-30)
%% License : LPPL 1.3c
%% -----------------------------------------------------------

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

\makeatletter

\tikzphysics@declarehook{ramp}
\tikzphysics@declarehook{curved-ramp}

%% ============================================================
%% 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{3.75cm}
\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}%
    \ifdim\tikzphysics@ramps@sr@wallheight>\tikzphysics@ramps@sr@rise\relax
      \pgfmathsetlength{\pgf@y}{(\tikzphysics@ramps@sr@wallheight-\tikzphysics@ramps@sr@depth)/2}%
    \else
      \pgfmathsetlength{\pgf@y}{(\tikzphysics@ramps@sr@rise-\tikzphysics@ramps@sr@depth)/2}%
    \fi
  }
  \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{%
    \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
  %% Contact components and the remaining edges of the closed body.
  \tikzphysics@declareedgeanchors{floor}
    {0pt}{0pt}
    {\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@flat}{0pt}
  \tikzphysics@declareedgeanchors{incline}
    {\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@flat}{0pt}
    {\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@width}{\tikzphysics@ramps@sr@rise}
  \tikzphysics@declareedgeanchors{wall-surface}
    {0pt}{0pt}
    {0pt}{\tikzphysics@ramps@sr@wallheight}
  \tikzphysics@declareedgeanchors{wall-back}
    {-\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@wallwidth}{-\tikzphysics@ramps@sr@depth}
    {-\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@wallwidth}{\tikzphysics@ramps@sr@wallheight}
  \tikzphysics@declareedgeanchors{wall-tip}
    {-\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@wallwidth}{\tikzphysics@ramps@sr@wallheight}
    {0pt}{\tikzphysics@ramps@sr@wallheight}
  \tikzphysics@declareedgeanchors{base}
    {-\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@wallwidth}{-\tikzphysics@ramps@sr@depth}
    {\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@width}{-\tikzphysics@ramps@sr@depth}
  \tikzphysics@declareedgeanchors{end}
    {\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@width}{-\tikzphysics@ramps@sr@depth}
    {\tikzphysics@ramps@sr@dir*\tikzphysics@ramps@sr@width}{\tikzphysics@ramps@sr@rise}
}

%% ============================================================
%% 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{%
    \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
  \tikzphysics@declareedgeanchors{floor}
    {-\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@floor}{0pt}
    {0pt}{0pt}
  \tikzphysics@declareedgeanchors{start}
    {-\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@floor}{-\tikzphysics@ramps@cr@depth}
    {-\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@floor}{0pt}
  \tikzphysics@declareedgeanchors{base}
    {-\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@floor}{-\tikzphysics@ramps@cr@depth}
    {\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@backx}{-\tikzphysics@ramps@cr@depth}
  \tikzphysics@declareedgeanchors{back}
    {\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@backx}{-\tikzphysics@ramps@cr@depth}
    {\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@backx}{\tikzphysics@ramps@cr@endy}
  \tikzphysics@declareedgeanchors{top}
    {\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@endx}{\tikzphysics@ramps@cr@endy}
    {\tikzphysics@ramps@cr@dir*\tikzphysics@ramps@cr@backx}{\tikzphysics@ramps@cr@endy}
}

%% 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/3.75cm,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,
    physics logical 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,
    physics debug setup, every physics object, every ramp,
  },
  physicscurvedramp/.style={
    shape=physicscurvedramp, physics logical shape=physicscurvedramp,
    physics logical 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,
    physics debug setup, every physics object, every curved-ramp,
  },
  ramp/.style={physicsramp},
  curved-ramp/.style={physicscurvedramp},
  ramp-left/.style={physicsramp,ramp direction=left},
  curved-ramp-left/.style={physicscurvedramp,ramp direction=left},
}

\tikzset{
  ramp run/.value required,
  ramp rise/.value required,
  ramp angle/.value required,
  ramp depth/.value required,
  ramp wall height/.value required,
  ramp wall width/.value required,
  ramp guide length/.value required,
  curved ramp radius/.value required,
  curved ramp angle/.value required,
  curved ramp floor length/.value required,
  curved ramp back extension/.value required,
}
\tikzphysics@registerdisplayname{physicsramp}{ramp}
\tikzphysics@registerdisplayname{physicscurvedramp}{curved-ramp}




%% BEGIN NATIVE COMPONENT EXTENSIONS
%% Distance-parametrized three-section track. At a corner, use the outgoing
%% section's tangent. The final endpoint uses the final horizontal section.
\def\tikzphysics@component@trackpoint{%
 \pgfmathsetmacro\cs{\tikzphysics@percent*\ctotal}%
 \ifdim\cs pt<\cseg pt
  \pgfmathsetmacro\cx{-\cw/2+\cs}\pgfmathsetmacro\cy{-\ch/2}%
  \def\ctx{1}\def\cty{0}%
 \else
  \pgfmathsetmacro\cj{\cseg+\cdiag}%
  \ifdim\cs pt<\cj pt
   \pgfmathsetmacro\cu{(\cs-\cseg)/\cdiag}%
   \pgfmathsetmacro\cx{-\cw/6+\cu*\cw/3}%
   \pgfmathsetmacro\cy{-\ch/2+\cu*\ch}%
   \pgfmathsetmacro\ctx{\cw/(3*\cdiag)}\pgfmathsetmacro\cty{\ch/\cdiag}%
  \else
   \pgfmathsetmacro\cx{\cw/6+\cs-\cj}\pgfmathsetmacro\cy{\ch/2}%
   \def\ctx{1}\def\cty{0}%
  \fi
 \fi
}
%% track
\tikzset{
 track length/.initial=4cm,
 physics track length/.style={track length={#1}},
 track rise/.initial=1cm,
 physics track rise/.style={track rise={#1}},
 track rough start/.initial=0,
 physics track rough start/.style={track rough start={#1}},
 track rough end/.initial=0,
 physics track rough end/.style={track rough end={#1}},
}
\pgfdeclareshape{physicstracknode}{
 \savedmacro\tikzphysics@component@physicstracknodestate{%
  \tikzphysics@component@length\cw{track length}
  \tikzphysics@component@length\ch{track rise}
  \pgfmathsetmacro\croughstart{\pgfkeysvalueof{/tikz/track rough start}}
  \pgfmathsetmacro\croughend{\pgfkeysvalueof{/tikz/track rough end}}
\tikzphysics@component@check{\cw>0 && \ch>=0}{Track length must be positive and rise nonnegative}
\tikzphysics@component@check{\croughstart>=0 && \croughend<=100 && \croughstart<=\croughend}{Rough interval must satisfy 0 <= start <= end <= 100}
\pgfmathsetmacro\cseg{\cw/3}\pgfmathsetmacro\cdiag{sqrt(\cseg*\cseg+\ch*\ch)}\pgfmathsetmacro\ctotal{2*\cseg+\cdiag}
  \addtosavedmacro\cw
  \addtosavedmacro\ch
  \addtosavedmacro\croughstart
  \addtosavedmacro\croughend
  \addtosavedmacro\cseg
  \addtosavedmacro\cdiag
  \addtosavedmacro\ctotal
 }
 \anchor{center}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@point{0}{0}}
 \anchor{north}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@point{0}{\ch/2+.2}}
 \anchor{south}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@point{0}{-(\ch/2+.2)}}
 \anchor{east}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@point{\cw/2+.2}{0}}
 \anchor{west}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@point{-(\cw/2+.2)}{0}}
 \anchor{north east}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@point{\cw/2+.2}{\ch/2+.2}}
 \anchor{north west}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@point{-(\cw/2+.2)}{\ch/2+.2}}
 \anchor{south east}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@point{\cw/2+.2}{-(\ch/2+.2)}}
 \anchor{south west}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@point{-(\cw/2+.2)}{-(\ch/2+.2)}}
 \anchor{start}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@point{-\cw/2}{-\ch/2}}
 \anchor{end}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@point{\cw/2}{\ch/2}}
 \anchor{joint-left}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@point{-\cw/6}{-\ch/2}}
 \anchor{joint-right}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@point{\cw/6}{\ch/2}}
 \anchor{text}{\pgf@x=-.5\wd\pgfnodeparttextbox\pgf@y=-.5\ht\pgfnodeparttextbox\advance\pgf@y by.5\dp\pgfnodeparttextbox}
 \tikzphysics@declarepercentanchors{surface}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@trackpoint}{(\cx)*1cm}{(\cy)*1cm}
 \tikzphysics@declarepercentanchors{tangent-before}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@trackpoint}{((\cx)-.2*(\ctx))*1cm}{((\cy)-.2*(\cty))*1cm}
 \tikzphysics@declarepercentanchors{tangent-after}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@trackpoint}{((\cx)+.2*(\ctx))*1cm}{((\cy)+.2*(\cty))*1cm}
 \tikzphysics@declarepercentanchors{normal}{\tikzphysics@component@physicstracknodestate\tikzphysics@component@trackpoint}{((\cx)-.2*(\cty))*1cm}{((\cy)+.2*(\ctx))*1cm}
 \anchorborder{\edef\cpx{\the\pgf@x}\edef\cpy{\the\pgf@y}\tikzphysics@component@physicstracknodestate\pgfpointborderrectangle{\pgfpoint{\cpx}{\cpy}}{\tikzphysics@component@point{\cw/2+.2}{\ch/2+.2}}}
 \backgroundpath{\tikzphysics@component@physicstracknodestate
\tikzphysics@component@move{-\cw/2}{-\ch/2}
\tikzphysics@component@line{-\cw/6}{-\ch/2}
\tikzphysics@component@line{\cw/6}{\ch/2}
\tikzphysics@component@line{\cw/2}{\ch/2}
\ifdim\croughend pt>\croughstart pt\pgfmathtruncatemacro\chatches{max(1,ceil((\croughend-\croughstart)/5))}\foreach \ci in {0,...,\chatches}{\pgfmathsetmacro\crp{\croughstart+(\croughend-\croughstart)*\ci/\chatches}\def\tikzphysics@percent{\crp/100}\tikzphysics@component@trackpoint\tikzphysics@component@move{\cx}{\cy}
\tikzphysics@component@line{(\cx)-.12*(\ctx)+.12*(\cty)}{(\cy)-.12*(\cty)-.12*(\ctx)}
}\fi
 }
}
\tikzphysics@declarehook{track}
\tikzphysics@registerdisplayname{physicstracknode}{track}
\tikzphysics@registeranchors{physicstracknode}{center,north,south,east,west,start,end,joint-left,joint-right}
\tikzphysics@registerfamilies{physicstracknode}{surface,tangent-before,tangent-after,normal}
\tikzphysics@registerkeys{physicstracknode}{track length,track rise,track rough start,track rough end}
\tikzphysics@registerkeydefaults{physicstracknode}{track length/4cm,track rise/1cm,track rough start/0,track rough end/0}
\tikzset{physicstracknode/.style={shape=physicstracknode,physics logical shape=physicstracknode,anchor=center,draw=black,fill=none,inner sep=0pt,outer sep=0pt,physics debug setup,every physics object,every track},track/.style={physicstracknode}}
%% circular bowl
\tikzset{
 circular bowl radius/.initial=1.4cm,
 physics circular bowl radius/.style={circular bowl radius={#1}},
 circular bowl rough start/.initial=0,
 physics circular bowl rough start/.style={circular bowl rough start={#1}},
 circular bowl rough end/.initial=0,
 physics circular bowl rough end/.style={circular bowl rough end={#1}},
}
\pgfdeclareshape{physicscircularbowlnode}{
 \savedmacro\tikzphysics@component@physicscircularbowlnodestate{%
  \tikzphysics@component@length\cr{circular bowl radius}
  \pgfmathsetmacro\croughstart{\pgfkeysvalueof{/tikz/circular bowl rough start}}
  \pgfmathsetmacro\croughend{\pgfkeysvalueof{/tikz/circular bowl rough end}}
\tikzphysics@component@check{\cr>0}{Track radius must be positive}
\tikzphysics@component@check{\croughstart>=0 && \croughend<=100 && \croughstart<=\croughend}{Rough interval must satisfy 0 <= start <= end <= 100}
  \addtosavedmacro\cr
  \addtosavedmacro\croughstart
  \addtosavedmacro\croughend
 }
 \anchor{center}{\tikzphysics@component@physicscircularbowlnodestate\tikzphysics@component@point{0}{0}}
 \anchor{north}{\tikzphysics@component@physicscircularbowlnodestate\tikzphysics@component@point{0}{\cr+.2}}
 \anchor{south}{\tikzphysics@component@physicscircularbowlnodestate\tikzphysics@component@point{0}{-(\cr+.2)}}
 \anchor{east}{\tikzphysics@component@physicscircularbowlnodestate\tikzphysics@component@point{\cr+.2}{0}}
 \anchor{west}{\tikzphysics@component@physicscircularbowlnodestate\tikzphysics@component@point{-(\cr+.2)}{0}}
 \anchor{north east}{\tikzphysics@component@physicscircularbowlnodestate\tikzphysics@component@point{\cr+.2}{\cr+.2}}
 \anchor{north west}{\tikzphysics@component@physicscircularbowlnodestate\tikzphysics@component@point{-(\cr+.2)}{\cr+.2}}
 \anchor{south east}{\tikzphysics@component@physicscircularbowlnodestate\tikzphysics@component@point{\cr+.2}{-(\cr+.2)}}
 \anchor{south west}{\tikzphysics@component@physicscircularbowlnodestate\tikzphysics@component@point{-(\cr+.2)}{-(\cr+.2)}}
 \anchor{start}{\tikzphysics@component@physicscircularbowlnodestate\tikzphysics@component@point{-\cr}{0}}
 \anchor{end}{\tikzphysics@component@physicscircularbowlnodestate\tikzphysics@component@point{\cr}{0}}
 \anchor{text}{\pgf@x=-.5\wd\pgfnodeparttextbox\pgf@y=-.5\ht\pgfnodeparttextbox\advance\pgf@y by.5\dp\pgfnodeparttextbox}
 \tikzphysics@declarepercentanchors{surface}{\tikzphysics@component@physicscircularbowlnodestate\pgfmathsetmacro\ca{180+180*\tikzphysics@percent}}{(\cr*cos(\ca))*1cm}{(\cr*sin(\ca))*1cm}
 \tikzphysics@declarepercentanchors{tangent-before}{\tikzphysics@component@physicscircularbowlnodestate\pgfmathsetmacro\ca{180+180*\tikzphysics@percent}}{((\cr*cos(\ca))-.2*(-sin(\ca)))*1cm}{((\cr*sin(\ca))-.2*(cos(\ca)))*1cm}
 \tikzphysics@declarepercentanchors{tangent-after}{\tikzphysics@component@physicscircularbowlnodestate\pgfmathsetmacro\ca{180+180*\tikzphysics@percent}}{((\cr*cos(\ca))+.2*(-sin(\ca)))*1cm}{((\cr*sin(\ca))+.2*(cos(\ca)))*1cm}
 \tikzphysics@declarepercentanchors{normal}{\tikzphysics@component@physicscircularbowlnodestate\pgfmathsetmacro\ca{180+180*\tikzphysics@percent}}{((\cr*cos(\ca))-.2*(cos(\ca)))*1cm}{((\cr*sin(\ca))+.2*(-sin(\ca)))*1cm}
 \anchorborder{\edef\cpx{\the\pgf@x}\edef\cpy{\the\pgf@y}\tikzphysics@component@physicscircularbowlnodestate\pgfpointborderrectangle{\pgfpoint{\cpx}{\cpy}}{\tikzphysics@component@point{\cr+.2}{\cr+.2}}}
 \backgroundpath{\tikzphysics@component@physicscircularbowlnodestate
\tikzphysics@component@move{-\cr}{0}
\pgfpatharc{180}{360}{\cr cm}
\ifdim\croughend pt>\croughstart pt\pgfmathtruncatemacro\chatches{max(1,ceil((\croughend-\croughstart)/5))}\foreach \ci in {0,...,\chatches}{\pgfmathsetmacro\crp{\croughstart+(\croughend-\croughstart)*\ci/\chatches}\def\tikzphysics@percent{\crp/100}\pgfmathsetmacro\ca{180+180*\tikzphysics@percent}\tikzphysics@component@move{\cr*cos(\ca)}{\cr*sin(\ca)}
\tikzphysics@component@line{(\cr*cos(\ca))-.12*(-sin(\ca))+.12*(cos(\ca))}{(\cr*sin(\ca))-.12*(cos(\ca))-.12*(-sin(\ca))}
}\fi
 }
}
\tikzphysics@declarehook{circular bowl}
\tikzphysics@registerdisplayname{physicscircularbowlnode}{circular bowl}
\tikzphysics@registeranchors{physicscircularbowlnode}{center,north,south,east,west,start,end}
\tikzphysics@registerfamilies{physicscircularbowlnode}{surface,tangent-before,tangent-after,normal}
\tikzphysics@registerkeys{physicscircularbowlnode}{circular bowl radius,circular bowl rough start,circular bowl rough end}
\tikzphysics@registerkeydefaults{physicscircularbowlnode}{circular bowl radius/1.4cm,circular bowl rough start/0,circular bowl rough end/0}
\tikzset{physicscircularbowlnode/.style={shape=physicscircularbowlnode,physics logical shape=physicscircularbowlnode,anchor=center,draw=black,fill=none,inner sep=0pt,outer sep=0pt,physics debug setup,every physics object,every circular bowl},circular bowl/.style={physicscircularbowlnode}}
%% loop track
\tikzset{
 loop track radius/.initial=1.4cm,
 physics loop track radius/.style={loop track radius={#1}},
 loop track rough start/.initial=0,
 physics loop track rough start/.style={loop track rough start={#1}},
 loop track rough end/.initial=0,
 physics loop track rough end/.style={loop track rough end={#1}},
}
\pgfdeclareshape{physicslooptracknode}{
 \savedmacro\tikzphysics@component@physicslooptracknodestate{%
  \tikzphysics@component@length\cr{loop track radius}
  \pgfmathsetmacro\croughstart{\pgfkeysvalueof{/tikz/loop track rough start}}
  \pgfmathsetmacro\croughend{\pgfkeysvalueof{/tikz/loop track rough end}}
\tikzphysics@component@check{\cr>0}{Track radius must be positive}
\tikzphysics@component@check{\croughstart>=0 && \croughend<=100 && \croughstart<=\croughend}{Rough interval must satisfy 0 <= start <= end <= 100}
  \addtosavedmacro\cr
  \addtosavedmacro\croughstart
  \addtosavedmacro\croughend
 }
 \anchor{center}{\tikzphysics@component@physicslooptracknodestate\tikzphysics@component@point{0}{0}}
 \anchor{north}{\tikzphysics@component@physicslooptracknodestate\tikzphysics@component@point{0}{\cr+.2}}
 \anchor{south}{\tikzphysics@component@physicslooptracknodestate\tikzphysics@component@point{0}{-(\cr+.2)}}
 \anchor{east}{\tikzphysics@component@physicslooptracknodestate\tikzphysics@component@point{\cr+.2}{0}}
 \anchor{west}{\tikzphysics@component@physicslooptracknodestate\tikzphysics@component@point{-(\cr+.2)}{0}}
 \anchor{north east}{\tikzphysics@component@physicslooptracknodestate\tikzphysics@component@point{\cr+.2}{\cr+.2}}
 \anchor{north west}{\tikzphysics@component@physicslooptracknodestate\tikzphysics@component@point{-(\cr+.2)}{\cr+.2}}
 \anchor{south east}{\tikzphysics@component@physicslooptracknodestate\tikzphysics@component@point{\cr+.2}{-(\cr+.2)}}
 \anchor{south west}{\tikzphysics@component@physicslooptracknodestate\tikzphysics@component@point{-(\cr+.2)}{-(\cr+.2)}}
 \anchor{start}{\tikzphysics@component@physicslooptracknodestate\tikzphysics@component@point{0}{-\cr}}
 \anchor{end}{\tikzphysics@component@physicslooptracknodestate\tikzphysics@component@point{0}{-\cr}}
 \anchor{text}{\pgf@x=-.5\wd\pgfnodeparttextbox\pgf@y=-.5\ht\pgfnodeparttextbox\advance\pgf@y by.5\dp\pgfnodeparttextbox}
 \tikzphysics@declarepercentanchors{surface}{\tikzphysics@component@physicslooptracknodestate\pgfmathsetmacro\ca{270+360*\tikzphysics@percent}}{(\cr*cos(\ca))*1cm}{(\cr*sin(\ca))*1cm}
 \tikzphysics@declarepercentanchors{tangent-before}{\tikzphysics@component@physicslooptracknodestate\pgfmathsetmacro\ca{270+360*\tikzphysics@percent}}{((\cr*cos(\ca))-.2*(-sin(\ca)))*1cm}{((\cr*sin(\ca))-.2*(cos(\ca)))*1cm}
 \tikzphysics@declarepercentanchors{tangent-after}{\tikzphysics@component@physicslooptracknodestate\pgfmathsetmacro\ca{270+360*\tikzphysics@percent}}{((\cr*cos(\ca))+.2*(-sin(\ca)))*1cm}{((\cr*sin(\ca))+.2*(cos(\ca)))*1cm}
 \tikzphysics@declarepercentanchors{normal}{\tikzphysics@component@physicslooptracknodestate\pgfmathsetmacro\ca{270+360*\tikzphysics@percent}}{((\cr*cos(\ca))-.2*(cos(\ca)))*1cm}{((\cr*sin(\ca))+.2*(-sin(\ca)))*1cm}
 \anchorborder{\edef\cpx{\the\pgf@x}\edef\cpy{\the\pgf@y}\tikzphysics@component@physicslooptracknodestate\pgfpointborderrectangle{\pgfpoint{\cpx}{\cpy}}{\tikzphysics@component@point{\cr+.2}{\cr+.2}}}
 \backgroundpath{\tikzphysics@component@physicslooptracknodestate
\tikzphysics@component@ellipse{0}{0}{\cr}{\cr}
\ifdim\croughend pt>\croughstart pt\pgfmathtruncatemacro\chatches{max(1,ceil((\croughend-\croughstart)/5))}\foreach \ci in {0,...,\chatches}{\pgfmathsetmacro\crp{\croughstart+(\croughend-\croughstart)*\ci/\chatches}\def\tikzphysics@percent{\crp/100}\pgfmathsetmacro\ca{270+360*\tikzphysics@percent}\tikzphysics@component@move{\cr*cos(\ca)}{\cr*sin(\ca)}
\tikzphysics@component@line{(\cr*cos(\ca))-.12*(-sin(\ca))+.12*(cos(\ca))}{(\cr*sin(\ca))-.12*(cos(\ca))-.12*(-sin(\ca))}
}\fi
 }
}
\tikzphysics@declarehook{loop track}
\tikzphysics@registerdisplayname{physicslooptracknode}{loop track}
\tikzphysics@registeranchors{physicslooptracknode}{center,north,south,east,west,start,end}
\tikzphysics@registerfamilies{physicslooptracknode}{surface,tangent-before,tangent-after,normal}
\tikzphysics@registerkeys{physicslooptracknode}{loop track radius,loop track rough start,loop track rough end}
\tikzphysics@registerkeydefaults{physicslooptracknode}{loop track radius/1.4cm,loop track rough start/0,loop track rough end/0}
\tikzset{physicslooptracknode/.style={shape=physicslooptracknode,physics logical shape=physicslooptracknode,anchor=center,draw=black,fill=none,inner sep=0pt,outer sep=0pt,physics debug setup,every physics object,every loop track},loop track/.style={physicslooptracknode}}
%% END NATIVE COMPONENT EXTENSIONS
\makeatother
\endinput
%% End of file `tikzlibrarytikzphysics.ramps.code.tex'.
