%% tikzlibrarytikzphysics.surface.code.tex
%% -----------------------------------------------------------
%% Surface module for tikzphysics.
%% Provides shapes for contact geometry used in mechanics problems:
%%   - physicsplatformleft, physicsplatformright, physicsplatformboth
%%   - physicswedge
%% and the user-facing styles physicsplatform-left/right/both and physicswedge.
%%
%% Internal namespace : \tikzphysics@surface@...
%% Requires           : tikz, patterns, calc, tikzphysics.core
%%
%% Design notes:
%%
%%  * All shapes use a single "dims bundle" \savedmacro that runs
%%    \tikzphysics@surface@set<shape>dims ONCE at node-declaration and caches
%%    all derived dimensions together.  Anchors unpack the bundle
%%    with one macro call and then read per-dim values directly.
%%    No anchor re-reads pgfkeys at access time.
%%
%%  * Precedence for physicswedge geometry (width w, height h, angle a):
%%       1. user set `physics wedge angle`  -> a wins, h derived from w,a
%%       2. user set `physics wedge height` (no angle) -> h wins, a derived
%%       3. neither                  -> mode-specific default angle
%%    See \tikzphysics@surface@setwedgedims below.
%%
%%  * `physics wedge right angle at' is a pgfkeys `.is choice' key.  No
%%    \ifx cascades on strings.
%%
%%  * For all three right-angle-at modes, the apex x-offset is
%%    stored in \tikzphysics@surface@tx.  Anchors use a single formula
%%    regardless of mode (e.g. centroid = (tx/3, -hy/3) always).
%%
%% Author  : Vaibhav Blayer
%% Version : v1.3.0 (2026-09-13)
%% License : LPPL 1.3c
%% -----------------------------------------------------------

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

\makeatletter

\tikzphysics@declarehook{platform}
\tikzphysics@declarehook{wedge}
\tikzphysics@declarehook{ground}
\tikzphysics@declarehook{ceiling}
\tikzphysics@declarehook{wall-left}
\tikzphysics@declarehook{wall-right}

%% ============================================================
%%  INTERNAL DIMENSIONS AND STATE
%% ============================================================

\newdimen\tikzphysics@surface@dx    %% full width
\newdimen\tikzphysics@surface@dy    %% full height
\newdimen\tikzphysics@surface@hx    %% half width
\newdimen\tikzphysics@surface@hy    %% half height
\newdimen\tikzphysics@surface@tx    %% apex x-offset from node centre (all modes)
\newdimen\tikzphysics@surface@sw    %% platform strip width
\newdimen\tikzphysics@surface@wi    %% wall inset from the floor tip
\newdimen\tikzphysics@surface@wd    %% wall drop before the wall begins

%% Angled wall corners (used by physicsplatformleft/right/both).
%% A = outer-near, B = inner-near, C = inner-far, D = outer-far
%% where "near" means near the platform corner and "far" means at the
%% free end of the wall. With zero inset/drop and the default wall angle
%% (-90 deg), wA/wB sit on y=+hy and wC/wD on y=-hy. A nonzero inset/drop
%% inserts the continuous straight segment from the floor tip to wA.
\newdimen\tikzphysics@surface@wAx  \newdimen\tikzphysics@surface@wAy
\newdimen\tikzphysics@surface@wBx  \newdimen\tikzphysics@surface@wBy
\newdimen\tikzphysics@surface@wCx  \newdimen\tikzphysics@surface@wCy
\newdimen\tikzphysics@surface@wDx  \newdimen\tikzphysics@surface@wDy
%% Second wall (physicsplatformboth's right wall)
\newdimen\tikzphysics@surface@rwAx \newdimen\tikzphysics@surface@rwAy
\newdimen\tikzphysics@surface@rwBx \newdimen\tikzphysics@surface@rwBy
\newdimen\tikzphysics@surface@rwCx \newdimen\tikzphysics@surface@rwCy
\newdimen\tikzphysics@surface@rwDx \newdimen\tikzphysics@surface@rwDy

\def\tikzphysics@surface@wedgeangle{45}
\def\tikzphysics@surface@wedgeraq{br}
\def\tikzphysics@surface@angleflag{0}     %% 1 iff user set `physics wedge angle'
\def\tikzphysics@surface@heightflag{0}    %% 1 iff user set `physics wedge height'
\def\tikzphysics@surface@ang{45}          %% working angle (degrees)

\def\tikzphysics@surface@stripwidth{0.25cm}   %% default 0.25cm

%% Wall-angle state.  Shared between physicsplatformleft/right (they
%% use \tikzphysics@surface@wallangle); physicsplatformboth additionally reads
%% \tikzphysics@surface@leftwallangle and \tikzphysics@surface@rightwallangle.
%% Default -90 degrees = wall points straight down. Angle is measured
%% from +x axis, CCW positive, and
%% describes the direction the wall extends from the platform corner.
\def\tikzphysics@surface@wallangle{-90}
\def\tikzphysics@surface@leftwallangle{-90}
\def\tikzphysics@surface@rightwallangle{-90}
\def\tikzphysics@surface@wallinset{0cm}
\def\tikzphysics@surface@leftwallinset{0cm}
\def\tikzphysics@surface@rightwallinset{0cm}
\def\tikzphysics@surface@walldrop{0cm}
\def\tikzphysics@surface@leftwalldrop{0cm}
\def\tikzphysics@surface@rightwalldrop{0cm}

%% ---- mode-specific default angles (used when neither angle nor
%%                                    explicit height is given) ----
\def\tikzphysics@surface@defaultangle@bl {30}
\def\tikzphysics@surface@defaultangle@br {30}
\def\tikzphysics@surface@defaultangle@top{45}

%% ============================================================
%%  GEOMETRY HELPERS
%% ============================================================

%% dims for a rectangular platform: just hx, hy, sw
\newcommand{\tikzphysics@surface@setplatformdims}{%
  \pgfmathsetlength{\tikzphysics@surface@dx}{\pgfkeysvalueof{/pgf/minimum width}}%
  \pgfmathsetlength{\tikzphysics@surface@dy}{\pgfkeysvalueof{/pgf/minimum height}}%
  \tikzphysics@surface@hx=.5\tikzphysics@surface@dx
  \tikzphysics@surface@hy=.5\tikzphysics@surface@dy
  \tikzphysics@resolve@length{\tikzphysics@surface@sw}{\tikzphysics@surface@stripwidth}%
  \ifdim\tikzphysics@surface@sw<\tikzphysics@surface@dx\relax\else
    \PackageError{tikzphysics}{strip width must be smaller than platform width}%
      {Reduce strip width or increase platform width.}%
  \fi
  \ifdim\tikzphysics@surface@sw<\tikzphysics@surface@dy\relax\else
    \PackageError{tikzphysics}{strip width must be smaller than platform depth}%
      {Reduce strip width or increase platform depth.}%
  \fi
}

%% dims for a flat strip shape (physicsground, physicsceiling, physicswall*): hx, hy.
%% No strip-within-strip, so no `sw' here.
\newcommand{\tikzphysics@surface@setflatdims}{%
  \pgfmathsetlength{\tikzphysics@surface@dx}{\pgfkeysvalueof{/pgf/minimum width}}%
  \pgfmathsetlength{\tikzphysics@surface@dy}{\pgfkeysvalueof{/pgf/minimum height}}%
  \tikzphysics@surface@hx=.5\tikzphysics@surface@dx
  \tikzphysics@surface@hy=.5\tikzphysics@surface@dy
}

%% ============================================================
%%  WALL GEOMETRY HELPER
%%
%%  Computes a wall strip of thickness sw and length 2*hy. The fixed floor
%%  corner IC is the end of the horizontal contact surface. The wall begins
%%  at A after an optional inward/downward transition from IC.
%%  The inner-near point B is the exact intersection of the wall's inner
%%  edge and the floor's inner edge. This miter makes the complete platform
%%  one sharply bent polygon, rather than separately joined components.
%%
%%  Corner labels:
%%    A = outer-near,  B = inner-near,
%%    C = inner-far,   D = outer-far.
%%    IC = fixed platform corner (retained as an internal storage name).
%%
%%  Depends on \tikzphysics@surface@hx, @hy, @sw being set.
%% ============================================================

%% Fixed platform-corner dimensions. The IC names are retained internally to
%% keep the saved-dimension plumbing compact.
\newdimen\tikzphysics@surface@ICx  \newdimen\tikzphysics@surface@ICy
%% Second IC for physicsplatformboth's right wall
\newdimen\tikzphysics@surface@rICx \newdimen\tikzphysics@surface@rICy

\newcommand{\tikzphysics@surface@setwall}[4]{%
  \tikzphysics@resolve@nonnegative{\tikzphysics@surface@wi}{#3}%
  \tikzphysics@resolve@nonnegative{\tikzphysics@surface@wd}{#4}%
  \ifdim\tikzphysics@surface@wi<\tikzphysics@surface@dx\relax\else
    \PackageError{tikzphysics}{wall inset must be smaller than platform width}%
      {Reduce wall inset or increase platform width.}%
  \fi
  \csname tikzphysics@surface@setwall@#1\endcsname{#2}%
}

\def\tikzphysics@surface@setwall@left#1{%
  \pgfmathsetmacro{\tikzphysics@surface@@c}{cos(#1)}%
  \pgfmathsetmacro{\tikzphysics@surface@@s}{sin(#1)}%
  %% IC is the fixed floor tip. A is the wall root after the transition.
  %% The wall's inward normal is n=(-sin(theta),cos(theta)).
  \tikzphysics@surface@ICx=-\tikzphysics@surface@hx
  \tikzphysics@surface@ICy= \tikzphysics@surface@hy
  \tikzphysics@surface@wAx=\dimexpr\tikzphysics@surface@ICx+\tikzphysics@surface@wi\relax
  \tikzphysics@surface@wAy=\dimexpr\tikzphysics@surface@ICy-\tikzphysics@surface@wd\relax
  %% Intersect the offset wall edge with y=hy-sw. At 180 degrees the
  %% result is the straight continuation. A 0-degree left wall folds back
  %% over the floor and has no finite miter.
  \pgfmathsetmacro{\tikzphysics@surface@@abss}{abs(\tikzphysics@surface@@s)}%
  \ifdim\tikzphysics@surface@@abss pt<0.0001pt\relax
    \ifdim\tikzphysics@surface@wi=0pt\relax
      \ifdim\tikzphysics@surface@wd=0pt\relax\else
        \PackageError{tikzphysics}{wall drop needs a non-horizontal wall angle}%
          {Use a non-horizontal wall angle, or set wall drop=0.}%
      \fi
    \else
      \PackageError{tikzphysics}{wall inset needs a non-horizontal wall angle}%
        {Use a non-horizontal wall angle, or set wall inset=0.}%
    \fi
    \ifdim\tikzphysics@surface@@c pt<0pt\relax
      \tikzphysics@surface@wBx=\tikzphysics@surface@wAx
    \else
      \PackageError{tikzphysics}{wall angle cannot fold a left wall back over the floor}%
        {Use an angle other than 0 degrees modulo 360.}%
      \tikzphysics@surface@wBx=\tikzphysics@surface@wAx
    \fi
  \else
    \pgfmathsetlength{\tikzphysics@surface@wBx}%
      {\tikzphysics@surface@wAx-\tikzphysics@surface@sw*\tikzphysics@surface@@s
       +\tikzphysics@surface@@c*(\tikzphysics@surface@wd-\tikzphysics@surface@sw*(1+\tikzphysics@surface@@c))/\tikzphysics@surface@@s}%
  \fi
  \tikzphysics@surface@wBy=\dimexpr\tikzphysics@surface@hy-\tikzphysics@surface@sw\relax
  \pgfmathsetlength{\tikzphysics@surface@wDx}{\tikzphysics@surface@wAx+2*\tikzphysics@surface@hy*\tikzphysics@surface@@c}%
  \pgfmathsetlength{\tikzphysics@surface@wDy}{\tikzphysics@surface@wAy+2*\tikzphysics@surface@hy*\tikzphysics@surface@@s}%
  \pgfmathsetlength{\tikzphysics@surface@wCx}{\tikzphysics@surface@wDx-\tikzphysics@surface@sw*\tikzphysics@surface@@s}%
  \pgfmathsetlength{\tikzphysics@surface@wCy}{\tikzphysics@surface@wDy+\tikzphysics@surface@sw*\tikzphysics@surface@@c}%
}

\def\tikzphysics@surface@setwall@right#1{%
  \pgfmathsetmacro{\tikzphysics@surface@@c}{cos(#1)}%
  \pgfmathsetmacro{\tikzphysics@surface@@s}{sin(#1)}%
  %% IC is the fixed floor tip. A is the wall root after the transition.
  %% The wall's inward normal is n=(sin(theta),-cos(theta)).
  \tikzphysics@surface@ICx=\tikzphysics@surface@hx
  \tikzphysics@surface@ICy=\tikzphysics@surface@hy
  \tikzphysics@surface@wAx=\dimexpr\tikzphysics@surface@ICx-\tikzphysics@surface@wi\relax
  \tikzphysics@surface@wAy=\dimexpr\tikzphysics@surface@ICy-\tikzphysics@surface@wd\relax
  %% Mirror of the left-wall miter. A 0-degree right wall is a straight
  %% continuation; a 180-degree right wall is the non-finite folded case.
  \pgfmathsetmacro{\tikzphysics@surface@@abss}{abs(\tikzphysics@surface@@s)}%
  \ifdim\tikzphysics@surface@@abss pt<0.0001pt\relax
    \ifdim\tikzphysics@surface@wi=0pt\relax
      \ifdim\tikzphysics@surface@wd=0pt\relax\else
        \PackageError{tikzphysics}{wall drop needs a non-horizontal wall angle}%
          {Use a non-horizontal wall angle, or set wall drop=0.}%
      \fi
    \else
      \PackageError{tikzphysics}{wall inset needs a non-horizontal wall angle}%
        {Use a non-horizontal wall angle, or set wall inset=0.}%
    \fi
    \ifdim\tikzphysics@surface@@c pt>0pt\relax
      \tikzphysics@surface@wBx=\tikzphysics@surface@wAx
    \else
      \PackageError{tikzphysics}{wall angle cannot fold a right wall back over the floor}%
        {Use an angle other than 180 degrees modulo 360.}%
      \tikzphysics@surface@wBx=\tikzphysics@surface@wAx
    \fi
  \else
    \pgfmathsetlength{\tikzphysics@surface@wBx}%
      {\tikzphysics@surface@wAx+\tikzphysics@surface@sw*\tikzphysics@surface@@s
       +\tikzphysics@surface@@c*(\tikzphysics@surface@wd-\tikzphysics@surface@sw*(1-\tikzphysics@surface@@c))/\tikzphysics@surface@@s}%
  \fi
  \tikzphysics@surface@wBy=\dimexpr\tikzphysics@surface@hy-\tikzphysics@surface@sw\relax
  \pgfmathsetlength{\tikzphysics@surface@wDx}{\tikzphysics@surface@wAx+2*\tikzphysics@surface@hy*\tikzphysics@surface@@c}%
  \pgfmathsetlength{\tikzphysics@surface@wDy}{\tikzphysics@surface@wAy+2*\tikzphysics@surface@hy*\tikzphysics@surface@@s}%
  \pgfmathsetlength{\tikzphysics@surface@wCx}{\tikzphysics@surface@wDx+\tikzphysics@surface@sw*\tikzphysics@surface@@s}%
  \pgfmathsetlength{\tikzphysics@surface@wCy}{\tikzphysics@surface@wDy-\tikzphysics@surface@sw*\tikzphysics@surface@@c}%
}

%% Combined setdims for physicsplatformleft: floor dims + angled wall.
\newcommand{\tikzphysics@surface@setpldims}{%
  \tikzphysics@surface@setplatformdims
  \tikzphysics@surface@setwall{left}{\tikzphysics@surface@wallangle}%
    {\tikzphysics@surface@wallinset}{\tikzphysics@surface@walldrop}%
}

%% Combined setdims for physicsplatformright: floor dims + angled wall.
\newcommand{\tikzphysics@surface@setprdims}{%
  \tikzphysics@surface@setplatformdims
  \tikzphysics@surface@setwall{right}{\tikzphysics@surface@wallangle}%
    {\tikzphysics@surface@wallinset}{\tikzphysics@surface@walldrop}%
}

%% physicsplatformboth: two walls.  Left wall IC goes into ICx/ICy,
%% right wall IC goes into rICx/rICy.
\newcommand{\tikzphysics@surface@setpbdims}{%
  \tikzphysics@surface@setplatformdims
  \tikzphysics@resolve@nonnegative{\@tempdima}{\tikzphysics@surface@leftwallinset}%
  \tikzphysics@resolve@nonnegative{\@tempdimb}{\tikzphysics@surface@rightwallinset}%
  \advance\@tempdima by \@tempdimb\relax
  \ifdim\@tempdima<\tikzphysics@surface@dx\relax\else
    \PackageError{tikzphysics}{left and right wall insets must fit within platform width}%
      {Reduce either inset or increase platform width.}%
  \fi
  %% Left wall
  \tikzphysics@surface@setwall{left}{\tikzphysics@surface@leftwallangle}%
    {\tikzphysics@surface@leftwallinset}{\tikzphysics@surface@leftwalldrop}%
  %% snapshot left wall corners
  \tikzphysics@surface@rwAx=\tikzphysics@surface@wAx \tikzphysics@surface@rwAy=\tikzphysics@surface@wAy
  \tikzphysics@surface@rwBx=\tikzphysics@surface@wBx \tikzphysics@surface@rwBy=\tikzphysics@surface@wBy
  \tikzphysics@surface@rwCx=\tikzphysics@surface@wCx \tikzphysics@surface@rwCy=\tikzphysics@surface@wCy
  \tikzphysics@surface@rwDx=\tikzphysics@surface@wDx \tikzphysics@surface@rwDy=\tikzphysics@surface@wDy
  %% snapshot left IC
  \tikzphysics@surface@rICx=\tikzphysics@surface@ICx \tikzphysics@surface@rICy=\tikzphysics@surface@ICy
  %% Right wall
  \tikzphysics@surface@setwall{right}{\tikzphysics@surface@rightwallangle}%
    {\tikzphysics@surface@rightwallinset}{\tikzphysics@surface@rightwalldrop}%
  %% Now swap: wA-wD hold RIGHT wall, rwA-rwD hold LEFT wall.
  %% We want wA-wD = LEFT, rwA-rwD = RIGHT.
  \@tempdima=\tikzphysics@surface@wAx \tikzphysics@surface@wAx=\tikzphysics@surface@rwAx \tikzphysics@surface@rwAx=\@tempdima
  \@tempdima=\tikzphysics@surface@wAy \tikzphysics@surface@wAy=\tikzphysics@surface@rwAy \tikzphysics@surface@rwAy=\@tempdima
  \@tempdima=\tikzphysics@surface@wBx \tikzphysics@surface@wBx=\tikzphysics@surface@rwBx \tikzphysics@surface@rwBx=\@tempdima
  \@tempdima=\tikzphysics@surface@wBy \tikzphysics@surface@wBy=\tikzphysics@surface@rwBy \tikzphysics@surface@rwBy=\@tempdima
  \@tempdima=\tikzphysics@surface@wCx \tikzphysics@surface@wCx=\tikzphysics@surface@rwCx \tikzphysics@surface@rwCx=\@tempdima
  \@tempdima=\tikzphysics@surface@wCy \tikzphysics@surface@wCy=\tikzphysics@surface@rwCy \tikzphysics@surface@rwCy=\@tempdima
  \@tempdima=\tikzphysics@surface@wDx \tikzphysics@surface@wDx=\tikzphysics@surface@rwDx \tikzphysics@surface@rwDx=\@tempdima
  \@tempdima=\tikzphysics@surface@wDy \tikzphysics@surface@wDy=\tikzphysics@surface@rwDy \tikzphysics@surface@rwDy=\@tempdima
  %% Swap ICs: ICx/ICy = left IC, rICx/rICy = right IC
  \@tempdima=\tikzphysics@surface@ICx \tikzphysics@surface@ICx=\tikzphysics@surface@rICx \tikzphysics@surface@rICx=\@tempdima
  \@tempdima=\tikzphysics@surface@ICy \tikzphysics@surface@ICy=\tikzphysics@surface@rICy \tikzphysics@surface@rICy=\@tempdima
}

%% Given dx and ang, compute dy and tx for the current
%% right-angle-at mode.  Dispatch via \csname, no \ifx.
\newcommand{\tikzphysics@surface@computedyfromangle}{%
  \csname tikzphysics@surface@computedims@\tikzphysics@surface@wedgeraq\endcsname
}

\newcommand{\tikzphysics@surface@validatewedgeangle}{%
  \ifdim\tikzphysics@surface@ang pt>0pt\relax\else
    \PackageError{tikzphysics}{physics wedge angle must be greater than 0 degrees}%
      {Choose an angle strictly between 0 and 90 degrees.}%
  \fi
  \ifdim\tikzphysics@surface@ang pt<90pt\relax\else
    \PackageError{tikzphysics}{physics wedge angle must be less than 90 degrees}%
      {Choose an angle strictly between 0 and 90 degrees.}%
  \fi
}

\def\tikzphysics@surface@computedims@bl{%
  %% right angle at bl: apex directly above bl
  %%   legs = (bl,br) and (bl,apex);  apex = (-hx, +hy)
  \pgfmathsetlength{\tikzphysics@surface@dy}{\tikzphysics@surface@dx*tan(\tikzphysics@surface@ang)}%
  \tikzphysics@surface@tx=-.5\tikzphysics@surface@dx
}
\def\tikzphysics@surface@computedims@br{%
  %% right angle at br: apex directly above br; apex = (+hx, +hy)
  \pgfmathsetlength{\tikzphysics@surface@dy}{\tikzphysics@surface@dx*tan(\tikzphysics@surface@ang)}%
  \tikzphysics@surface@tx=.5\tikzphysics@surface@dx
}
\def\tikzphysics@surface@computedims@top{%
  %% right angle at apex: Thales geometry
  %%   dy = dx * sin(2a) / 2
  %%   tx = dx * cos(2a) / 2
  \pgfmathsetlength{\tikzphysics@surface@dy}{\tikzphysics@surface@dx*sin(2*\tikzphysics@surface@ang)/2}%
  \pgfmathsetlength{\tikzphysics@surface@tx}{\tikzphysics@surface@dx*cos(2*\tikzphysics@surface@ang)/2}%
}

%% Given dx and dy, compute ang and tx for the current mode.
\newcommand{\tikzphysics@surface@computeanglefromdy}{%
  \csname tikzphysics@surface@anglefromdy@\tikzphysics@surface@wedgeraq\endcsname
}

\def\tikzphysics@surface@anglefromdy@bl{%
  \pgfmathsetmacro{\tikzphysics@surface@ang}{atan(\tikzphysics@surface@dy/\tikzphysics@surface@dx)}%
  \tikzphysics@surface@tx=-.5\tikzphysics@surface@dx
}
\def\tikzphysics@surface@anglefromdy@br{%
  \pgfmathsetmacro{\tikzphysics@surface@ang}{atan(\tikzphysics@surface@dy/\tikzphysics@surface@dx)}%
  \tikzphysics@surface@tx=.5\tikzphysics@surface@dx
}
\def\tikzphysics@surface@anglefromdy@top{%
  %% Thales inverse:
  %%   ang = (1/2) * asin(2*dy/dx)    (requires 2*dy <= dx)
  %%   tx  = (1/2) * sqrt(dx^2 - 4*dy^2)
  \ifdim\tikzphysics@surface@dy>.5\tikzphysics@surface@dx\relax
    \PackageError{tikzphysics}%
      {physics wedge height > physics wedge width/2 is impossible with
       `physics wedge right angle at=top'}%
      {With right-angle-at=top the apex must lie on a semicircle
       (Thales' theorem). Reduce physics wedge height to at most
       physics wedge width/2, or drop `physics wedge right angle at=top'.}%
  \fi
  \pgfmathsetmacro{\tikzphysics@surface@ang}%
    {0.5*asin(2*\tikzphysics@surface@dy/\tikzphysics@surface@dx)}%
  \pgfmathsetlength{\tikzphysics@surface@tx}%
    {0.5*sqrt(\tikzphysics@surface@dx*\tikzphysics@surface@dx
              - 4*\tikzphysics@surface@dy*\tikzphysics@surface@dy)}%
}

%% The only place pgfkeys are read for wedge geometry.
%% Resolves all dimensions according to the precedence rule
%% angle > height > mode-default, then saves them to dx/dy/hx/hy/tx.
\newcommand{\tikzphysics@surface@setwedgedims}{%
  \pgfmathsetlength{\tikzphysics@surface@dx}{\pgfkeysvalueof{/pgf/minimum width}}%
  \ifnum\tikzphysics@surface@angleflag=1
    %% case 1: angle authoritative
    \pgfmathsetmacro{\tikzphysics@surface@ang}{\tikzphysics@surface@wedgeangle}%
    \tikzphysics@surface@validatewedgeangle
    \tikzphysics@surface@computedyfromangle
  \else
    \ifnum\tikzphysics@surface@heightflag=1
      %% case 2: height authoritative
      \pgfmathsetlength{\tikzphysics@surface@dy}%
        {\pgfkeysvalueof{/pgf/minimum height}}%
      \tikzphysics@surface@computeanglefromdy
    \else
      %% case 3: mode-specific default angle
      \edef\tikzphysics@surface@ang{%
        \csname tikzphysics@surface@defaultangle@\tikzphysics@surface@wedgeraq\endcsname}%
      \tikzphysics@surface@validatewedgeangle
      \tikzphysics@surface@computedyfromangle
    \fi
  \fi
  \tikzphysics@surface@hx=.5\tikzphysics@surface@dx
  \tikzphysics@surface@hy=.5\tikzphysics@surface@dy
}

%% ============================================================
%%  TIKZ KEYS  (scoped, unit-aware)
%% ============================================================

\tikzset{
  %% ---- platform sizing ----
  physics platform width/.code  = {\tikzphysics@length@keyhandler{/pgf/minimum width}{#1}},
  physics platform depth/.code  = {\tikzphysics@length@keyhandler{/pgf/minimum height}{#1}},
  physics strip width/.code     = {\def\tikzphysics@surface@stripwidth{#1}},
  platform width/.style = {physics platform width={#1}},
  platform depth/.style = {physics platform depth={#1}},
  strip width/.style    = {physics strip width={#1}},
  %% ---- wall direction (physicsplatform-left/right/both) ----
  %% Angle from +x axis, CCW positive, of the direction the wall
  %% extends from the platform corner. Default -90 deg = straight down.
  physics wall angle/.code = {%
    \def\tikzphysics@surface@wallangle{#1}%
    \def\tikzphysics@surface@leftwallangle{#1}%
    \def\tikzphysics@surface@rightwallangle{#1}%
  },
  %% physicsplatform-both supports independent left/right wall angles.
  physics left wall angle/.code  = {\def\tikzphysics@surface@leftwallangle{#1}},
  physics right wall angle/.code = {\def\tikzphysics@surface@rightwallangle{#1}},
  %% Optional tapered transition between a floor tip and its wall root.
  %% Shared forms set both sides; platform-left/right simply use the one
  %% relevant side. Zero values preserve the original sharp corner.
  physics wall inset/.code = {%
    \def\tikzphysics@surface@wallinset{#1}%
    \def\tikzphysics@surface@leftwallinset{#1}%
    \def\tikzphysics@surface@rightwallinset{#1}%
  },
  physics left wall inset/.code  = {\def\tikzphysics@surface@leftwallinset{#1}},
  physics right wall inset/.code = {\def\tikzphysics@surface@rightwallinset{#1}},
  physics wall drop/.code = {%
    \def\tikzphysics@surface@walldrop{#1}%
    \def\tikzphysics@surface@leftwalldrop{#1}%
    \def\tikzphysics@surface@rightwalldrop{#1}%
  },
  physics left wall drop/.code  = {\def\tikzphysics@surface@leftwalldrop{#1}},
  physics right wall drop/.code = {\def\tikzphysics@surface@rightwalldrop{#1}},
  %% Concise public forms; retain the prefixed keys as collision-safe aliases.
  wall angle/.style       = {physics wall angle={#1}},
  left wall angle/.style  = {physics left wall angle={#1}},
  right wall angle/.style = {physics right wall angle={#1}},
  wall inset/.style       = {physics wall inset={#1}},
  left wall inset/.style  = {physics left wall inset={#1}},
  right wall inset/.style = {physics right wall inset={#1}},
  wall drop/.style        = {physics wall drop={#1}},
  left wall drop/.style   = {physics left wall drop={#1}},
  right wall drop/.style  = {physics right wall drop={#1}},
  %% One-centimetre default pulley: a half-diameter inset and drop gives
  %% the compact 45-degree textbook transition supplied in the reference.
  physics pulley edge/.style={physics wall inset=0.5cm, physics wall drop=0.5cm},
  physics left pulley edge/.style={physics left wall inset=0.5cm, physics left wall drop=0.5cm},
  physics right pulley edge/.style={physics right wall inset=0.5cm, physics right wall drop=0.5cm},
  pulley edge/.style={physics pulley edge},
  pulley edges/.style={physics pulley edge},
  left pulley edge/.style={physics left pulley edge},
  right pulley edge/.style={physics right pulley edge},
  %% ---- wedge sizing ----
  physics wedge width/.code     = {\tikzphysics@length@keyhandler{/pgf/minimum width}{#1}},
  physics wedge height/.code    = {%
    \tikzphysics@length@keyhandler{/pgf/minimum height}{#1}%
    \def\tikzphysics@surface@heightflag{1}%
  },
  %% ---- wedge shape controls ----
  physics wedge angle/.code       = {%
    \def\tikzphysics@surface@wedgeangle{#1}%
    \def\tikzphysics@surface@angleflag{1}%
  },
  physics wedge right angle at/.is choice,
  physics wedge right angle at/bl/.code  = {\def\tikzphysics@surface@wedgeraq{bl}},
  physics wedge right angle at/br/.code  = {\def\tikzphysics@surface@wedgeraq{br}},
  physics wedge right angle at/top/.code = {\def\tikzphysics@surface@wedgeraq{top}},
  %% Concise public forms; the physics-prefixed keys remain available when
  %% generic key names would collide with another TikZ library.
  wedge width/.style          = {physics wedge width={#1}},
  wedge height/.style         = {physics wedge height={#1}},
  wedge angle/.style          = {physics wedge angle={#1}},
  wedge right angle at/.style = {physics wedge right angle at={#1}},
  %% ---- flat strip sizing (ground/ceiling/walls) ----
  physics ground width/.code    = {\tikzphysics@length@keyhandler{/pgf/minimum width}{#1}},
  physics ground depth/.code    = {\tikzphysics@length@keyhandler{/pgf/minimum height}{#1}},
  physics ceiling width/.code   = {\tikzphysics@length@keyhandler{/pgf/minimum width}{#1}},
  physics ceiling depth/.code   = {\tikzphysics@length@keyhandler{/pgf/minimum height}{#1}},
  physics wall thickness/.code  = {\tikzphysics@length@keyhandler{/pgf/minimum width}{#1}},
  physics wall height/.code     = {\tikzphysics@length@keyhandler{/pgf/minimum height}{#1}},
  ground width/.style      = {physics ground width={#1}},
  ground depth/.style      = {physics ground depth={#1}},
  ceiling width/.style     = {physics ceiling width={#1}},
  ceiling depth/.style     = {physics ceiling depth={#1}},
  wall thickness/.style    = {physics wall thickness={#1}},
  wall height/.style       = {physics wall height={#1}},
}

%% ============================================================
%%  PLATFORM SHAPES
%%
%%  Each platform uses individual \savedmacro's per dimension.
%%  This avoids pgf's internal re-edef of bundled \def's (which
%%  would try to expand not-yet-defined names).  The cost of
%%  calling setplatformdims 3x per node is negligible.
%% ============================================================

%% --------------------------------------------------------------
%%  physicsplatformleft
%%
%%  Geometry = one closed floor-and-wall polygon. Its outer boundary is
%%  the continuous contact line and its inner boundary uses an exact miter,
%%  so the bend is a sharp V rather than a rounded or patched connection.
%%
%%  Floor (fixed, horizontal strip along the top):
%%    x in [-hx, +hx],  y in [hy-sw, +hy]
%%  Wall (starts after the optional transition):
%%    projecting floor tip = (-hx, hy)
%%    wall root A = (-hx+wall inset, hy-wall drop)
%%    default (wall angle = -90): wall lies in
%%      a vertical strip extending from A
%%    user-facing key `wall angle' sets the wall direction from A.
%%
%%  Corner labels (intrinsic to the angled wall):
%%    A = outer-near, B = inner-near,
%%    C = inner-far,  D = outer-far
%%  where "near" is the platform-side short end and "far" is the free
%%  short end; "outer" faces away from the floor interior.
%% --------------------------------------------------------------
\pgfdeclareshape{physicsplatformleft}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchor[from=rectangle]{south east}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchorborder[from=rectangle]

  %% Floor dims
  \savedmacro{\tikzphysics@surface@pl@hx}{%
    \tikzphysics@surface@setpldims
    \edef\tikzphysics@surface@pl@hx{\the\tikzphysics@surface@hx}%
  }
  \savedmacro{\tikzphysics@surface@pl@hy}{%
    \tikzphysics@surface@setpldims
    \edef\tikzphysics@surface@pl@hy{\the\tikzphysics@surface@hy}%
  }
  \savedmacro{\tikzphysics@surface@pl@sw}{%
    \tikzphysics@surface@setpldims
    \edef\tikzphysics@surface@pl@sw{\the\tikzphysics@surface@sw}%
  }
  %% Angled wall corners
  \savedmacro{\tikzphysics@surface@pl@wAx}{%
    \tikzphysics@surface@setpldims
    \edef\tikzphysics@surface@pl@wAx{\the\tikzphysics@surface@wAx}%
  }
  \savedmacro{\tikzphysics@surface@pl@wAy}{%
    \tikzphysics@surface@setpldims
    \edef\tikzphysics@surface@pl@wAy{\the\tikzphysics@surface@wAy}%
  }
  \savedmacro{\tikzphysics@surface@pl@wBx}{%
    \tikzphysics@surface@setpldims
    \edef\tikzphysics@surface@pl@wBx{\the\tikzphysics@surface@wBx}%
  }
  \savedmacro{\tikzphysics@surface@pl@wBy}{%
    \tikzphysics@surface@setpldims
    \edef\tikzphysics@surface@pl@wBy{\the\tikzphysics@surface@wBy}%
  }
  \savedmacro{\tikzphysics@surface@pl@wCx}{%
    \tikzphysics@surface@setpldims
    \edef\tikzphysics@surface@pl@wCx{\the\tikzphysics@surface@wCx}%
  }
  \savedmacro{\tikzphysics@surface@pl@wCy}{%
    \tikzphysics@surface@setpldims
    \edef\tikzphysics@surface@pl@wCy{\the\tikzphysics@surface@wCy}%
  }
  \savedmacro{\tikzphysics@surface@pl@wDx}{%
    \tikzphysics@surface@setpldims
    \edef\tikzphysics@surface@pl@wDx{\the\tikzphysics@surface@wDx}%
  }
  \savedmacro{\tikzphysics@surface@pl@wDy}{%
    \tikzphysics@surface@setpldims
    \edef\tikzphysics@surface@pl@wDy{\the\tikzphysics@surface@wDy}%
  }
  %% Fixed platform corner
  \savedmacro{\tikzphysics@surface@pl@ICx}{%
    \tikzphysics@surface@setpldims
    \edef\tikzphysics@surface@pl@ICx{\the\tikzphysics@surface@ICx}%
  }
  \savedmacro{\tikzphysics@surface@pl@ICy}{%
    \tikzphysics@surface@setpldims
    \edef\tikzphysics@surface@pl@ICy{\the\tikzphysics@surface@ICy}%
  }

  %% One closed, mitered polygon. The pattern is evaluated once over the
  %% complete floor-and-wall geometry.
  \backgroundpath{%
    \pgfpathmoveto{\pgfpoint{\tikzphysics@surface@pl@wDx}{\tikzphysics@surface@pl@wDy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pl@wAx}{\tikzphysics@surface@pl@wAy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pl@ICx}{\tikzphysics@surface@pl@ICy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pl@hx}{\tikzphysics@surface@pl@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pl@hx}
                            {\dimexpr\tikzphysics@surface@pl@hy-\tikzphysics@surface@pl@sw\relax}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pl@wBx}{\tikzphysics@surface@pl@wBy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pl@wCx}{\tikzphysics@surface@pl@wCy}}%
    \pgfpathclose
  }
  %% One continuous contact line: wall free end -> wall root -> floor tip
  %% -> opposite floor end.
  \foregroundpath{%
    \pgfsetlinewidth{0.5pt}%
    \pgfpathmoveto{\pgfpoint{\tikzphysics@surface@pl@wDx}{\tikzphysics@surface@pl@wDy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pl@wAx}{\tikzphysics@surface@pl@wAy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pl@ICx}{\tikzphysics@surface@pl@ICy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pl@hx}{\tikzphysics@surface@pl@hy}}%
    \pgfusepath{stroke}%
  }

  %% ---- fixed projecting floor tip, suitable for a pulley centre ----
  \anchor{corner}{\pgf@x=\tikzphysics@surface@pl@ICx \pgf@y=\tikzphysics@surface@pl@ICy}
  \anchor{pulley-center}{\pgf@x=\tikzphysics@surface@pl@ICx \pgf@y=\tikzphysics@surface@pl@ICy}
  \anchor{wall-root}{\pgf@x=\tikzphysics@surface@pl@wAx \pgf@y=\tikzphysics@surface@pl@wAy}
  \anchor{transition-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pl@ICx+\tikzphysics@surface@pl@wAx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pl@ICy+\tikzphysics@surface@pl@wAy)/2}}

  %% ---- floor corners (fixed, ignore wall angle) ----
  \anchor{floor-tl}{\pgf@x=-\tikzphysics@surface@pl@hx \pgf@y=\tikzphysics@surface@pl@hy}
  \anchor{floor-tr}{\pgf@x= \tikzphysics@surface@pl@hx \pgf@y=\tikzphysics@surface@pl@hy}
  \anchor{floor-br}{\pgf@x= \tikzphysics@surface@pl@hx
                     \pgf@y=\dimexpr\tikzphysics@surface@pl@hy-\tikzphysics@surface@pl@sw\relax}
  \anchor{floor-bl}{\pgf@x=-\tikzphysics@surface@pl@hx
                     \pgf@y=\dimexpr\tikzphysics@surface@pl@hy-\tikzphysics@surface@pl@sw\relax}
  \anchor{floor-top-mid}   {\pgf@x=0pt \pgf@y=\tikzphysics@surface@pl@hy}
  \anchor{floor-bottom-mid}{\pgf@x=0pt
                     \pgf@y=\dimexpr\tikzphysics@surface@pl@hy-\tikzphysics@surface@pl@sw\relax}
  \anchor{floor-left-mid}  {\pgf@x=-\tikzphysics@surface@pl@hx
     \pgfmathsetlength{\pgf@y}{\tikzphysics@surface@pl@hy-0.5*\tikzphysics@surface@pl@sw}}
  \anchor{floor-right-mid} {\pgf@x= \tikzphysics@surface@pl@hx
     \pgfmathsetlength{\pgf@y}{\tikzphysics@surface@pl@hy-0.5*\tikzphysics@surface@pl@sw}}
  \anchor{floor-center}    {\pgf@x=0pt
     \pgfmathsetlength{\pgf@y}{\tikzphysics@surface@pl@hy-0.5*\tikzphysics@surface@pl@sw}}

  %% ---- wall corners ----
  \anchor{wall-A}{\pgf@x=\tikzphysics@surface@pl@wAx \pgf@y=\tikzphysics@surface@pl@wAy}
  \anchor{wall-B}{\pgf@x=\tikzphysics@surface@pl@wBx \pgf@y=\tikzphysics@surface@pl@wBy}
  \anchor{wall-C}{\pgf@x=\tikzphysics@surface@pl@wCx \pgf@y=\tikzphysics@surface@pl@wCy}
  \anchor{wall-D}{\pgf@x=\tikzphysics@surface@pl@wDx \pgf@y=\tikzphysics@surface@pl@wDy}

  %% ---- wall mids ----
  \anchor{wall-outer-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pl@wAx+\tikzphysics@surface@pl@wDx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pl@wAy+\tikzphysics@surface@pl@wDy)/2}}
  \anchor{wall-inner-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pl@wBx+\tikzphysics@surface@pl@wCx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pl@wBy+\tikzphysics@surface@pl@wCy)/2}}
  \anchor{wall-near-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pl@wAx+\tikzphysics@surface@pl@wBx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pl@wAy+\tikzphysics@surface@pl@wBy)/2}}
  \anchor{wall-far-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pl@wCx+\tikzphysics@surface@pl@wDx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pl@wCy+\tikzphysics@surface@pl@wDy)/2}}
  \anchor{wall-center}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pl@wAx+\tikzphysics@surface@pl@wBx
                              +\tikzphysics@surface@pl@wCx+\tikzphysics@surface@pl@wDx)/4}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pl@wAy+\tikzphysics@surface@pl@wBy
                              +\tikzphysics@surface@pl@wCy+\tikzphysics@surface@pl@wDy)/4}}

  %% ---- numeric edge anchors on the floor (CCW from FBL) ----
  %% floor-bottom : FBL -> FBR (left to right across the floor's
  %%                inner edge)
  %% floor-right  : FBR -> FTR (up the floor's right side)
  %% floor-top    : FTR -> FTL (right to left across the floor's
  %%                outer top -- the contact surface)
  %% floor-left   : FTL -> FBL (down the floor's left side)
  \tikzphysics@declareedgeanchors{floor-bottom}
    {-\tikzphysics@surface@pl@hx}{\dimexpr\tikzphysics@surface@pl@hy-\tikzphysics@surface@pl@sw\relax}
    {\tikzphysics@surface@pl@hx}{\dimexpr\tikzphysics@surface@pl@hy-\tikzphysics@surface@pl@sw\relax}
  \tikzphysics@declareedgeanchors{floor-right}
    {\tikzphysics@surface@pl@hx}{\dimexpr\tikzphysics@surface@pl@hy-\tikzphysics@surface@pl@sw\relax}
    {\tikzphysics@surface@pl@hx}{\tikzphysics@surface@pl@hy}
  \tikzphysics@declareedgeanchors{floor-top}
    {\tikzphysics@surface@pl@hx}{\tikzphysics@surface@pl@hy}
    {-\tikzphysics@surface@pl@hx}{\tikzphysics@surface@pl@hy}
  \tikzphysics@declareedgeanchors{floor-left}
    {-\tikzphysics@surface@pl@hx}{\tikzphysics@surface@pl@hy}
    {-\tikzphysics@surface@pl@hx}{\dimexpr\tikzphysics@surface@pl@hy-\tikzphysics@surface@pl@sw\relax}

  %% Transition runs from the projecting floor tip to the wall root.
  \tikzphysics@declareedgeanchors{transition}
    {\tikzphysics@surface@pl@ICx}{\tikzphysics@surface@pl@ICy}
    {\tikzphysics@surface@pl@wAx}{\tikzphysics@surface@pl@wAy}

  %% ---- numeric edge anchors on the wall ----
  %% Each edge parameterises 0 -> 100 in the natural direction
  %% along that face of the wall.  Direction is chosen so that
  %% 0 is on the outer-or-near side (closer to the corner for
  %% outer/inner; outer side for near/far).
  %%   wall-outer : wA  -> wD   (along outer long edge, near -> far)
  %%   wall-inner : wB  -> wC   (along inner long edge, near -> far)
  %%   wall-near  : wA  -> wB   (along near short edge, outer -> inner)
  %%   wall-far   : wD  -> wC   (along far short edge, outer -> inner)
  \tikzphysics@declareedgeanchors{wall-outer}
    {\tikzphysics@surface@pl@wAx}{\tikzphysics@surface@pl@wAy}
    {\tikzphysics@surface@pl@wDx}{\tikzphysics@surface@pl@wDy}
  \tikzphysics@declareedgeanchors{wall-inner}
    {\tikzphysics@surface@pl@wBx}{\tikzphysics@surface@pl@wBy}
    {\tikzphysics@surface@pl@wCx}{\tikzphysics@surface@pl@wCy}
  \tikzphysics@declareedgeanchors{wall-near}
    {\tikzphysics@surface@pl@wAx}{\tikzphysics@surface@pl@wAy}
    {\tikzphysics@surface@pl@wBx}{\tikzphysics@surface@pl@wBy}
  \tikzphysics@declareedgeanchors{wall-far}
    {\tikzphysics@surface@pl@wDx}{\tikzphysics@surface@pl@wDy}
    {\tikzphysics@surface@pl@wCx}{\tikzphysics@surface@pl@wCy}

}

%% --------------------------------------------------------------
%%  physicsplatformright
%%
%%  Mirror of physicsplatformleft: wall attaches on the right side of
%%  the floor strip. The projecting floor tip is (+hx, hy); the wall
%%  begins at the optional inward/downward wall root. Default wall angle = -90
%%  degrees (wall extends straight down).
%% --------------------------------------------------------------
\pgfdeclareshape{physicsplatformright}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchor[from=rectangle]{south east}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchorborder[from=rectangle]

  \savedmacro{\tikzphysics@surface@pr@hx}{%
    \tikzphysics@surface@setprdims
    \edef\tikzphysics@surface@pr@hx{\the\tikzphysics@surface@hx}%
  }
  \savedmacro{\tikzphysics@surface@pr@hy}{%
    \tikzphysics@surface@setprdims
    \edef\tikzphysics@surface@pr@hy{\the\tikzphysics@surface@hy}%
  }
  \savedmacro{\tikzphysics@surface@pr@sw}{%
    \tikzphysics@surface@setprdims
    \edef\tikzphysics@surface@pr@sw{\the\tikzphysics@surface@sw}%
  }
  \savedmacro{\tikzphysics@surface@pr@wAx}{%
    \tikzphysics@surface@setprdims
    \edef\tikzphysics@surface@pr@wAx{\the\tikzphysics@surface@wAx}%
  }
  \savedmacro{\tikzphysics@surface@pr@wAy}{%
    \tikzphysics@surface@setprdims
    \edef\tikzphysics@surface@pr@wAy{\the\tikzphysics@surface@wAy}%
  }
  \savedmacro{\tikzphysics@surface@pr@wBx}{%
    \tikzphysics@surface@setprdims
    \edef\tikzphysics@surface@pr@wBx{\the\tikzphysics@surface@wBx}%
  }
  \savedmacro{\tikzphysics@surface@pr@wBy}{%
    \tikzphysics@surface@setprdims
    \edef\tikzphysics@surface@pr@wBy{\the\tikzphysics@surface@wBy}%
  }
  \savedmacro{\tikzphysics@surface@pr@wCx}{%
    \tikzphysics@surface@setprdims
    \edef\tikzphysics@surface@pr@wCx{\the\tikzphysics@surface@wCx}%
  }
  \savedmacro{\tikzphysics@surface@pr@wCy}{%
    \tikzphysics@surface@setprdims
    \edef\tikzphysics@surface@pr@wCy{\the\tikzphysics@surface@wCy}%
  }
  \savedmacro{\tikzphysics@surface@pr@wDx}{%
    \tikzphysics@surface@setprdims
    \edef\tikzphysics@surface@pr@wDx{\the\tikzphysics@surface@wDx}%
  }
  \savedmacro{\tikzphysics@surface@pr@wDy}{%
    \tikzphysics@surface@setprdims
    \edef\tikzphysics@surface@pr@wDy{\the\tikzphysics@surface@wDy}%
  }
  \savedmacro{\tikzphysics@surface@pr@ICx}{%
    \tikzphysics@surface@setprdims
    \edef\tikzphysics@surface@pr@ICx{\the\tikzphysics@surface@ICx}%
  }
  \savedmacro{\tikzphysics@surface@pr@ICy}{%
    \tikzphysics@surface@setprdims
    \edef\tikzphysics@surface@pr@ICy{\the\tikzphysics@surface@ICy}%
  }

  %% One closed, sharply mitered floor-and-wall polygon.
  \backgroundpath{%
    \pgfpathmoveto{\pgfpoint{-\tikzphysics@surface@pr@hx}{\tikzphysics@surface@pr@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pr@ICx}{\tikzphysics@surface@pr@ICy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pr@wAx}{\tikzphysics@surface@pr@wAy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pr@wDx}{\tikzphysics@surface@pr@wDy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pr@wCx}{\tikzphysics@surface@pr@wCy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pr@wBx}{\tikzphysics@surface@pr@wBy}}%
    \pgfpathlineto{\pgfpoint{-\tikzphysics@surface@pr@hx}
                            {\dimexpr\tikzphysics@surface@pr@hy-\tikzphysics@surface@pr@sw\relax}}%
    \pgfpathclose
  }
  %% One continuous contact line: floor end -> floor tip -> wall root
  %% -> wall free end.
  \foregroundpath{%
    \pgfsetlinewidth{0.5pt}%
    \pgfpathmoveto{\pgfpoint{-\tikzphysics@surface@pr@hx}{\tikzphysics@surface@pr@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pr@ICx}{\tikzphysics@surface@pr@ICy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pr@wAx}{\tikzphysics@surface@pr@wAy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pr@wDx}{\tikzphysics@surface@pr@wDy}}%
    \pgfusepath{stroke}%
  }

  %% ---- fixed projecting floor tip, suitable for a pulley centre ----
  \anchor{corner}{\pgf@x=\tikzphysics@surface@pr@ICx \pgf@y=\tikzphysics@surface@pr@ICy}
  \anchor{pulley-center}{\pgf@x=\tikzphysics@surface@pr@ICx \pgf@y=\tikzphysics@surface@pr@ICy}
  \anchor{wall-root}{\pgf@x=\tikzphysics@surface@pr@wAx \pgf@y=\tikzphysics@surface@pr@wAy}
  \anchor{transition-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pr@ICx+\tikzphysics@surface@pr@wAx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pr@ICy+\tikzphysics@surface@pr@wAy)/2}}

  %% ---- floor corners (fixed) ----
  \anchor{floor-tl}{\pgf@x=-\tikzphysics@surface@pr@hx \pgf@y=\tikzphysics@surface@pr@hy}
  \anchor{floor-tr}{\pgf@x= \tikzphysics@surface@pr@hx \pgf@y=\tikzphysics@surface@pr@hy}
  \anchor{floor-br}{\pgf@x= \tikzphysics@surface@pr@hx
                     \pgf@y=\dimexpr\tikzphysics@surface@pr@hy-\tikzphysics@surface@pr@sw\relax}
  \anchor{floor-bl}{\pgf@x=-\tikzphysics@surface@pr@hx
                     \pgf@y=\dimexpr\tikzphysics@surface@pr@hy-\tikzphysics@surface@pr@sw\relax}
  \anchor{floor-top-mid}   {\pgf@x=0pt \pgf@y=\tikzphysics@surface@pr@hy}
  \anchor{floor-bottom-mid}{\pgf@x=0pt
                     \pgf@y=\dimexpr\tikzphysics@surface@pr@hy-\tikzphysics@surface@pr@sw\relax}
  \anchor{floor-left-mid}  {\pgf@x=-\tikzphysics@surface@pr@hx
     \pgfmathsetlength{\pgf@y}{\tikzphysics@surface@pr@hy-0.5*\tikzphysics@surface@pr@sw}}
  \anchor{floor-right-mid} {\pgf@x= \tikzphysics@surface@pr@hx
     \pgfmathsetlength{\pgf@y}{\tikzphysics@surface@pr@hy-0.5*\tikzphysics@surface@pr@sw}}
  \anchor{floor-center}    {\pgf@x=0pt
     \pgfmathsetlength{\pgf@y}{\tikzphysics@surface@pr@hy-0.5*\tikzphysics@surface@pr@sw}}

  %% ---- wall corners ----
  \anchor{wall-A}{\pgf@x=\tikzphysics@surface@pr@wAx \pgf@y=\tikzphysics@surface@pr@wAy}
  \anchor{wall-B}{\pgf@x=\tikzphysics@surface@pr@wBx \pgf@y=\tikzphysics@surface@pr@wBy}
  \anchor{wall-C}{\pgf@x=\tikzphysics@surface@pr@wCx \pgf@y=\tikzphysics@surface@pr@wCy}
  \anchor{wall-D}{\pgf@x=\tikzphysics@surface@pr@wDx \pgf@y=\tikzphysics@surface@pr@wDy}

  %% ---- wall mids ----
  \anchor{wall-outer-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pr@wAx+\tikzphysics@surface@pr@wDx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pr@wAy+\tikzphysics@surface@pr@wDy)/2}}
  \anchor{wall-inner-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pr@wBx+\tikzphysics@surface@pr@wCx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pr@wBy+\tikzphysics@surface@pr@wCy)/2}}
  \anchor{wall-near-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pr@wAx+\tikzphysics@surface@pr@wBx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pr@wAy+\tikzphysics@surface@pr@wBy)/2}}
  \anchor{wall-far-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pr@wCx+\tikzphysics@surface@pr@wDx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pr@wCy+\tikzphysics@surface@pr@wDy)/2}}
  \anchor{wall-center}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pr@wAx+\tikzphysics@surface@pr@wBx
                              +\tikzphysics@surface@pr@wCx+\tikzphysics@surface@pr@wDx)/4}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pr@wAy+\tikzphysics@surface@pr@wBy
                              +\tikzphysics@surface@pr@wCy+\tikzphysics@surface@pr@wDy)/4}}

  %% ---- numeric edge anchors on the floor (CCW from FBL) ----
  \tikzphysics@declareedgeanchors{floor-bottom}
    {-\tikzphysics@surface@pr@hx}{\dimexpr\tikzphysics@surface@pr@hy-\tikzphysics@surface@pr@sw\relax}
    {\tikzphysics@surface@pr@hx}{\dimexpr\tikzphysics@surface@pr@hy-\tikzphysics@surface@pr@sw\relax}
  \tikzphysics@declareedgeanchors{floor-right}
    {\tikzphysics@surface@pr@hx}{\dimexpr\tikzphysics@surface@pr@hy-\tikzphysics@surface@pr@sw\relax}
    {\tikzphysics@surface@pr@hx}{\tikzphysics@surface@pr@hy}
  \tikzphysics@declareedgeanchors{floor-top}
    {\tikzphysics@surface@pr@hx}{\tikzphysics@surface@pr@hy}
    {-\tikzphysics@surface@pr@hx}{\tikzphysics@surface@pr@hy}
  \tikzphysics@declareedgeanchors{floor-left}
    {-\tikzphysics@surface@pr@hx}{\tikzphysics@surface@pr@hy}
    {-\tikzphysics@surface@pr@hx}{\dimexpr\tikzphysics@surface@pr@hy-\tikzphysics@surface@pr@sw\relax}

  %% Transition runs from the projecting floor tip to the wall root.
  \tikzphysics@declareedgeanchors{transition}
    {\tikzphysics@surface@pr@ICx}{\tikzphysics@surface@pr@ICy}
    {\tikzphysics@surface@pr@wAx}{\tikzphysics@surface@pr@wAy}

  %% ---- numeric edge anchors on the wall ----
  %% Same intrinsic convention as physicsplatformleft:
  %%   wall-outer : wA -> wD   (along outer long edge, near -> far)
  %%   wall-inner : wB -> wC   (along inner long edge, near -> far)
  %%   wall-near  : wA -> wB   (along near short edge, outer -> inner)
  %%   wall-far   : wD -> wC   (along far short edge, outer -> inner)
  \tikzphysics@declareedgeanchors{wall-outer}
    {\tikzphysics@surface@pr@wAx}{\tikzphysics@surface@pr@wAy}
    {\tikzphysics@surface@pr@wDx}{\tikzphysics@surface@pr@wDy}
  \tikzphysics@declareedgeanchors{wall-inner}
    {\tikzphysics@surface@pr@wBx}{\tikzphysics@surface@pr@wBy}
    {\tikzphysics@surface@pr@wCx}{\tikzphysics@surface@pr@wCy}
  \tikzphysics@declareedgeanchors{wall-near}
    {\tikzphysics@surface@pr@wAx}{\tikzphysics@surface@pr@wAy}
    {\tikzphysics@surface@pr@wBx}{\tikzphysics@surface@pr@wBy}
  \tikzphysics@declareedgeanchors{wall-far}
    {\tikzphysics@surface@pr@wDx}{\tikzphysics@surface@pr@wDy}
    {\tikzphysics@surface@pr@wCx}{\tikzphysics@surface@pr@wCy}

}

%% --------------------------------------------------------------
%%  physicsplatformboth
%%
%%  One closed floor-and-two-wall polygon with two exact inner miters.
%%  User keys:
%%    wall angle         -- sets BOTH walls (convenience)
%%    left wall angle    -- just the left wall
%%    right wall angle   -- just the right wall
%%  Default for both walls is -90 degrees.
%%
%%  Left wall  corners -> lA, lB, lC, lD (stored in pb@lAx .. pb@lDy)
%%  Right wall corners -> rA, rB, rC, rD (stored in pb@rAx .. pb@rDy)
%%  Using the same A/B/C/D convention per wall as physicsplatformleft/right.
%% --------------------------------------------------------------
\pgfdeclareshape{physicsplatformboth}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchor[from=rectangle]{south east}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchorborder[from=rectangle]

  \savedmacro{\tikzphysics@surface@pb@hx}{%
    \tikzphysics@surface@setpbdims
    \edef\tikzphysics@surface@pb@hx{\the\tikzphysics@surface@hx}%
  }
  \savedmacro{\tikzphysics@surface@pb@hy}{%
    \tikzphysics@surface@setpbdims
    \edef\tikzphysics@surface@pb@hy{\the\tikzphysics@surface@hy}%
  }
  \savedmacro{\tikzphysics@surface@pb@sw}{%
    \tikzphysics@surface@setpbdims
    \edef\tikzphysics@surface@pb@sw{\the\tikzphysics@surface@sw}%
  }
  %% Left wall corners (wA/B/C/D from setpbdims)
  \savedmacro{\tikzphysics@surface@pb@lAx}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@lAx{\the\tikzphysics@surface@wAx}}
  \savedmacro{\tikzphysics@surface@pb@lAy}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@lAy{\the\tikzphysics@surface@wAy}}
  \savedmacro{\tikzphysics@surface@pb@lBx}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@lBx{\the\tikzphysics@surface@wBx}}
  \savedmacro{\tikzphysics@surface@pb@lBy}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@lBy{\the\tikzphysics@surface@wBy}}
  \savedmacro{\tikzphysics@surface@pb@lCx}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@lCx{\the\tikzphysics@surface@wCx}}
  \savedmacro{\tikzphysics@surface@pb@lCy}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@lCy{\the\tikzphysics@surface@wCy}}
  \savedmacro{\tikzphysics@surface@pb@lDx}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@lDx{\the\tikzphysics@surface@wDx}}
  \savedmacro{\tikzphysics@surface@pb@lDy}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@lDy{\the\tikzphysics@surface@wDy}}
  %% Right wall corners (rwA/B/C/D from setpbdims)
  \savedmacro{\tikzphysics@surface@pb@rAx}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@rAx{\the\tikzphysics@surface@rwAx}}
  \savedmacro{\tikzphysics@surface@pb@rAy}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@rAy{\the\tikzphysics@surface@rwAy}}
  \savedmacro{\tikzphysics@surface@pb@rBx}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@rBx{\the\tikzphysics@surface@rwBx}}
  \savedmacro{\tikzphysics@surface@pb@rBy}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@rBy{\the\tikzphysics@surface@rwBy}}
  \savedmacro{\tikzphysics@surface@pb@rCx}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@rCx{\the\tikzphysics@surface@rwCx}}
  \savedmacro{\tikzphysics@surface@pb@rCy}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@rCy{\the\tikzphysics@surface@rwCy}}
  \savedmacro{\tikzphysics@surface@pb@rDx}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@rDx{\the\tikzphysics@surface@rwDx}}
  \savedmacro{\tikzphysics@surface@pb@rDy}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@rDy{\the\tikzphysics@surface@rwDy}}
  %% Left wall IC
  \savedmacro{\tikzphysics@surface@pb@lICx}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@lICx{\the\tikzphysics@surface@ICx}}
  \savedmacro{\tikzphysics@surface@pb@lICy}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@lICy{\the\tikzphysics@surface@ICy}}
  %% Right wall IC
  \savedmacro{\tikzphysics@surface@pb@rICx}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@rICx{\the\tikzphysics@surface@rICx}}
  \savedmacro{\tikzphysics@surface@pb@rICy}{%
    \tikzphysics@surface@setpbdims \edef\tikzphysics@surface@pb@rICy{\the\tikzphysics@surface@rICy}}

  %% One closed polygon: left free end, floor, right free end, then the
  %% complete inner boundary through both sharp miter points.
  \backgroundpath{%
    \pgfpathmoveto{\pgfpoint{\tikzphysics@surface@pb@lDx}{\tikzphysics@surface@pb@lDy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pb@lAx}{\tikzphysics@surface@pb@lAy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pb@lICx}{\tikzphysics@surface@pb@lICy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pb@rICx}{\tikzphysics@surface@pb@rICy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pb@rAx}{\tikzphysics@surface@pb@rAy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pb@rDx}{\tikzphysics@surface@pb@rDy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pb@rCx}{\tikzphysics@surface@pb@rCy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pb@rBx}{\tikzphysics@surface@pb@rBy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pb@lBx}{\tikzphysics@surface@pb@lBy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pb@lCx}{\tikzphysics@surface@pb@lCy}}%
    \pgfpathclose
  }
  %% One continuous contact line across the full bent platform.
  \foregroundpath{%
    \pgfsetlinewidth{0.5pt}%
    \pgfpathmoveto{\pgfpoint{\tikzphysics@surface@pb@lDx}{\tikzphysics@surface@pb@lDy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pb@lAx}{\tikzphysics@surface@pb@lAy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pb@lICx}{\tikzphysics@surface@pb@lICy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pb@rICx}{\tikzphysics@surface@pb@rICy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pb@rAx}{\tikzphysics@surface@pb@rAy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@pb@rDx}{\tikzphysics@surface@pb@rDy}}%
    \pgfusepath{stroke}%
  }

  %% ---- fixed surface corners ----
  \anchor{left-corner}{\pgf@x=\tikzphysics@surface@pb@lICx \pgf@y=\tikzphysics@surface@pb@lICy}
  \anchor{right-corner}{\pgf@x=\tikzphysics@surface@pb@rICx \pgf@y=\tikzphysics@surface@pb@rICy}
  \anchor{left-pulley-center}{\pgf@x=\tikzphysics@surface@pb@lICx \pgf@y=\tikzphysics@surface@pb@lICy}
  \anchor{right-pulley-center}{\pgf@x=\tikzphysics@surface@pb@rICx \pgf@y=\tikzphysics@surface@pb@rICy}
  \anchor{left-wall-root}{\pgf@x=\tikzphysics@surface@pb@lAx \pgf@y=\tikzphysics@surface@pb@lAy}
  \anchor{right-wall-root}{\pgf@x=\tikzphysics@surface@pb@rAx \pgf@y=\tikzphysics@surface@pb@rAy}
  \anchor{left-transition-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pb@lICx+\tikzphysics@surface@pb@lAx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pb@lICy+\tikzphysics@surface@pb@lAy)/2}}
  \anchor{right-transition-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pb@rICx+\tikzphysics@surface@pb@rAx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pb@rICy+\tikzphysics@surface@pb@rAy)/2}}

  %% ---- floor anchors (fixed) ----
  \anchor{floor-tl}{\pgf@x=-\tikzphysics@surface@pb@hx \pgf@y=\tikzphysics@surface@pb@hy}
  \anchor{floor-tr}{\pgf@x= \tikzphysics@surface@pb@hx \pgf@y=\tikzphysics@surface@pb@hy}
  \anchor{floor-br}{\pgf@x= \tikzphysics@surface@pb@hx
                     \pgf@y=\dimexpr\tikzphysics@surface@pb@hy-\tikzphysics@surface@pb@sw\relax}
  \anchor{floor-bl}{\pgf@x=-\tikzphysics@surface@pb@hx
                     \pgf@y=\dimexpr\tikzphysics@surface@pb@hy-\tikzphysics@surface@pb@sw\relax}
  \anchor{floor-top-mid}   {\pgf@x=0pt \pgf@y=\tikzphysics@surface@pb@hy}
  \anchor{floor-bottom-mid}{\pgf@x=0pt
                     \pgf@y=\dimexpr\tikzphysics@surface@pb@hy-\tikzphysics@surface@pb@sw\relax}
  \anchor{floor-center}    {\pgf@x=0pt
     \pgfmathsetlength{\pgf@y}{\tikzphysics@surface@pb@hy-0.5*\tikzphysics@surface@pb@sw}}

  %% ---- left wall corners ----
  \anchor{left-wall-A}{\pgf@x=\tikzphysics@surface@pb@lAx \pgf@y=\tikzphysics@surface@pb@lAy}
  \anchor{left-wall-B}{\pgf@x=\tikzphysics@surface@pb@lBx \pgf@y=\tikzphysics@surface@pb@lBy}
  \anchor{left-wall-C}{\pgf@x=\tikzphysics@surface@pb@lCx \pgf@y=\tikzphysics@surface@pb@lCy}
  \anchor{left-wall-D}{\pgf@x=\tikzphysics@surface@pb@lDx \pgf@y=\tikzphysics@surface@pb@lDy}
  \anchor{left-wall-outer-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pb@lAx+\tikzphysics@surface@pb@lDx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pb@lAy+\tikzphysics@surface@pb@lDy)/2}}
  \anchor{left-wall-inner-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pb@lBx+\tikzphysics@surface@pb@lCx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pb@lBy+\tikzphysics@surface@pb@lCy)/2}}
  \anchor{left-wall-far-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pb@lCx+\tikzphysics@surface@pb@lDx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pb@lCy+\tikzphysics@surface@pb@lDy)/2}}
  \anchor{left-wall-near-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pb@lAx+\tikzphysics@surface@pb@lBx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pb@lAy+\tikzphysics@surface@pb@lBy)/2}}

  %% ---- right wall corners ----
  \anchor{right-wall-A}{\pgf@x=\tikzphysics@surface@pb@rAx \pgf@y=\tikzphysics@surface@pb@rAy}
  \anchor{right-wall-B}{\pgf@x=\tikzphysics@surface@pb@rBx \pgf@y=\tikzphysics@surface@pb@rBy}
  \anchor{right-wall-C}{\pgf@x=\tikzphysics@surface@pb@rCx \pgf@y=\tikzphysics@surface@pb@rCy}
  \anchor{right-wall-D}{\pgf@x=\tikzphysics@surface@pb@rDx \pgf@y=\tikzphysics@surface@pb@rDy}
  \anchor{right-wall-outer-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pb@rAx+\tikzphysics@surface@pb@rDx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pb@rAy+\tikzphysics@surface@pb@rDy)/2}}
  \anchor{right-wall-inner-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pb@rBx+\tikzphysics@surface@pb@rCx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pb@rBy+\tikzphysics@surface@pb@rCy)/2}}
  \anchor{right-wall-far-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pb@rCx+\tikzphysics@surface@pb@rDx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pb@rCy+\tikzphysics@surface@pb@rDy)/2}}
  \anchor{right-wall-near-mid}{%
    \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@pb@rAx+\tikzphysics@surface@pb@rBx)/2}%
    \pgfmathsetlength{\pgf@y}{(\tikzphysics@surface@pb@rAy+\tikzphysics@surface@pb@rBy)/2}}

  %% ---- numeric edge anchors on the floor ----
  \tikzphysics@declareedgeanchors{floor-bottom}
    {-\tikzphysics@surface@pb@hx}{\dimexpr\tikzphysics@surface@pb@hy-\tikzphysics@surface@pb@sw\relax}
    {\tikzphysics@surface@pb@hx}{\dimexpr\tikzphysics@surface@pb@hy-\tikzphysics@surface@pb@sw\relax}
  \tikzphysics@declareedgeanchors{floor-right}
    {\tikzphysics@surface@pb@hx}{\dimexpr\tikzphysics@surface@pb@hy-\tikzphysics@surface@pb@sw\relax}
    {\tikzphysics@surface@pb@hx}{\tikzphysics@surface@pb@hy}
  \tikzphysics@declareedgeanchors{floor-top}
    {\tikzphysics@surface@pb@hx}{\tikzphysics@surface@pb@hy}
    {-\tikzphysics@surface@pb@hx}{\tikzphysics@surface@pb@hy}
  \tikzphysics@declareedgeanchors{floor-left}
    {-\tikzphysics@surface@pb@hx}{\tikzphysics@surface@pb@hy}
    {-\tikzphysics@surface@pb@hx}{\dimexpr\tikzphysics@surface@pb@hy-\tikzphysics@surface@pb@sw\relax}

  \tikzphysics@declareedgeanchors{left-transition}
    {\tikzphysics@surface@pb@lICx}{\tikzphysics@surface@pb@lICy}
    {\tikzphysics@surface@pb@lAx}{\tikzphysics@surface@pb@lAy}
  \tikzphysics@declareedgeanchors{right-transition}
    {\tikzphysics@surface@pb@rICx}{\tikzphysics@surface@pb@rICy}
    {\tikzphysics@surface@pb@rAx}{\tikzphysics@surface@pb@rAy}

  %% ---- numeric edge anchors on the left wall ----
  \tikzphysics@declareedgeanchors{left-wall-outer}
    {\tikzphysics@surface@pb@lAx}{\tikzphysics@surface@pb@lAy}
    {\tikzphysics@surface@pb@lDx}{\tikzphysics@surface@pb@lDy}
  \tikzphysics@declareedgeanchors{left-wall-inner}
    {\tikzphysics@surface@pb@lBx}{\tikzphysics@surface@pb@lBy}
    {\tikzphysics@surface@pb@lCx}{\tikzphysics@surface@pb@lCy}
  \tikzphysics@declareedgeanchors{left-wall-near}
    {\tikzphysics@surface@pb@lAx}{\tikzphysics@surface@pb@lAy}
    {\tikzphysics@surface@pb@lBx}{\tikzphysics@surface@pb@lBy}
  \tikzphysics@declareedgeanchors{left-wall-far}
    {\tikzphysics@surface@pb@lDx}{\tikzphysics@surface@pb@lDy}
    {\tikzphysics@surface@pb@lCx}{\tikzphysics@surface@pb@lCy}

  %% ---- numeric edge anchors on the right wall ----
  \tikzphysics@declareedgeanchors{right-wall-outer}
    {\tikzphysics@surface@pb@rAx}{\tikzphysics@surface@pb@rAy}
    {\tikzphysics@surface@pb@rDx}{\tikzphysics@surface@pb@rDy}
  \tikzphysics@declareedgeanchors{right-wall-inner}
    {\tikzphysics@surface@pb@rBx}{\tikzphysics@surface@pb@rBy}
    {\tikzphysics@surface@pb@rCx}{\tikzphysics@surface@pb@rCy}
  \tikzphysics@declareedgeanchors{right-wall-near}
    {\tikzphysics@surface@pb@rAx}{\tikzphysics@surface@pb@rAy}
    {\tikzphysics@surface@pb@rBx}{\tikzphysics@surface@pb@rBy}
  \tikzphysics@declareedgeanchors{right-wall-far}
    {\tikzphysics@surface@pb@rDx}{\tikzphysics@surface@pb@rDy}
    {\tikzphysics@surface@pb@rCx}{\tikzphysics@surface@pb@rCy}

}

%% ============================================================
%%  WEDGE SHAPE
%%
%%  Individual savedmacros, one per dim.  See platform comment
%%  about why we avoid the "bundle of \def's" pattern.
%% ============================================================

%% Contact anchors follow the usable slope from left to right in every
%% mode; existing CCW edge families keep their original meanings.
\def\tikzphysics@surface@guidevalue{0.5cm}
\tikzset{
  surface guide length/.code={\def\tikzphysics@surface@guidevalue{#1}},
  surface guide length/.value required,
  physics surface guide length/.style={surface guide length={#1}},
  physics surface guide length/.value required,
}
\def\tikzphysics@surface@contactpoint#1#2{%
  \def\tikzphysics@surface@mode@bl{bl}%
  \def\tikzphysics@surface@mode@top{top}%
  \def\tikzphysics@surface@contact@right{right}%
  \def\tikzphysics@surface@contact@which{#2}%
  \def\tikzphysics@surface@contact@descending{0}%
  \ifx\tikzphysics@surface@w@ra\tikzphysics@surface@mode@bl
    \def\tikzphysics@surface@contact@descending{1}%
  \fi
  \ifx\tikzphysics@surface@w@ra\tikzphysics@surface@mode@top
    \ifx\tikzphysics@surface@contact@which\tikzphysics@surface@contact@right
      \def\tikzphysics@surface@contact@descending{1}%
    \fi
  \fi
  \ifnum\tikzphysics@surface@contact@descending=1
    \pgfmathsetlength{\pgf@x}{\tikzphysics@surface@w@tx+(#1/100)*(\tikzphysics@surface@w@hx-\tikzphysics@surface@w@tx)}%
    \pgfmathsetlength{\pgf@y}{(1-2*#1/100)*\tikzphysics@surface@w@hy}%
    \pgfmathsetmacro{\tikzphysics@surface@contact@angle}{atan2(-2*\tikzphysics@surface@w@hy,\tikzphysics@surface@w@hx-\tikzphysics@surface@w@tx)}%
  \else
    \pgfmathsetlength{\pgf@x}{-\tikzphysics@surface@w@hx+(#1/100)*(\tikzphysics@surface@w@hx+\tikzphysics@surface@w@tx)}%
    \pgfmathsetlength{\pgf@y}{(-1+2*#1/100)*\tikzphysics@surface@w@hy}%
    \pgfmathsetmacro{\tikzphysics@surface@contact@angle}{atan2(2*\tikzphysics@surface@w@hy,\tikzphysics@surface@w@hx+\tikzphysics@surface@w@tx)}%
  \fi
}
\def\tikzphysics@surface@contactguide#1#2#3{%
  \tikzphysics@surface@contactpoint{#1}{#2}%
  \edef\tikzphysics@surface@contact@x{\the\pgf@x}%
  \edef\tikzphysics@surface@contact@y{\the\pgf@y}%
  \ifnum#3=0
    \pgfmathsetlength{\pgf@x}{\tikzphysics@surface@contact@x-\tikzphysics@surface@w@guide*sin(\tikzphysics@surface@contact@angle)}%
    \pgfmathsetlength{\pgf@y}{\tikzphysics@surface@contact@y+\tikzphysics@surface@w@guide*cos(\tikzphysics@surface@contact@angle)}%
  \else
    \pgfmathsetlength{\pgf@x}{\tikzphysics@surface@contact@x+#3*0.5*\tikzphysics@surface@w@guide*cos(\tikzphysics@surface@contact@angle)}%
    \pgfmathsetlength{\pgf@y}{\tikzphysics@surface@contact@y+#3*0.5*\tikzphysics@surface@w@guide*sin(\tikzphysics@surface@contact@angle)}%
  \fi
}
\def\tikzphysics@surface@declarecontact@one#1{%
  \anchor{surface-#1}{\tikzphysics@surface@contactpoint{#1}{left}}%
  \anchor{tangent-before-#1}{\tikzphysics@surface@contactguide{#1}{left}{-1}}%
  \anchor{tangent-after-#1}{\tikzphysics@surface@contactguide{#1}{left}{1}}%
  \anchor{normal-#1}{\tikzphysics@surface@contactguide{#1}{left}{0}}%
  \anchor{right-surface-#1}{\tikzphysics@surface@contactpoint{#1}{right}}%
  \anchor{right-tangent-before-#1}{\tikzphysics@surface@contactguide{#1}{right}{-1}}%
  \anchor{right-tangent-after-#1}{\tikzphysics@surface@contactguide{#1}{right}{1}}%
  \anchor{right-normal-#1}{\tikzphysics@surface@contactguide{#1}{right}{0}}%
}
\def\tikzphysics@surface@declarecontactanchors{%
  \foreach \tikzphysics@@t in {0,1,...,100}{%
    \edef\tikzphysics@@partial{\noexpand\tikzphysics@surface@declarecontact@one{\tikzphysics@@t}}%
    \tikzphysics@@partial
  }%
}

\pgfdeclareshape{physicswedge}{
  \savedmacro{\tikzphysics@surface@w@guide}{%
    \tikzphysics@resolve@length{\@tempdima}{\tikzphysics@surface@guidevalue}%
    \edef\tikzphysics@surface@w@guide{\the\@tempdima}%
  }
  \anchor{surface-start}{\tikzphysics@surface@contactpoint{0}{left}}
  \anchor{surface-end}{\tikzphysics@surface@contactpoint{100}{left}}
  \tikzphysics@surface@declarecontactanchors

  \inheritsavedanchors[from=rectangle]
  \inheritanchorborder[from=rectangle]

  \savedmacro{\tikzphysics@surface@w@hx}{%
    \tikzphysics@surface@setwedgedims
    \edef\tikzphysics@surface@w@hx{\the\tikzphysics@surface@hx}%
  }
  \savedmacro{\tikzphysics@surface@w@hy}{%
    \tikzphysics@surface@setwedgedims
    \edef\tikzphysics@surface@w@hy{\the\tikzphysics@surface@hy}%
  }
  \savedmacro{\tikzphysics@surface@w@tx}{%
    \tikzphysics@surface@setwedgedims
    \edef\tikzphysics@surface@w@tx{\the\tikzphysics@surface@tx}%
  }
  \savedmacro{\tikzphysics@surface@w@ra}{%
    \edef\tikzphysics@surface@w@ra{\tikzphysics@surface@wedgeraq}%
  }
  \savedmacro{\tikzphysics@surface@w@ang}{%
    \tikzphysics@surface@setwedgedims
    \edef\tikzphysics@surface@w@ang{\tikzphysics@surface@ang}%
  }

  %% ---- bounding-box anchors ----
  \anchor{center}    {\pgf@x=0pt                 \pgf@y=0pt}
  \anchor{north}     {\pgf@x=0pt                 \pgf@y=\tikzphysics@surface@w@hy}
  \anchor{south}     {\pgf@x=0pt                 \pgf@y=-\tikzphysics@surface@w@hy}
  \anchor{east}      {\pgf@x=\tikzphysics@surface@w@hx   \pgf@y=0pt}
  \anchor{west}      {\pgf@x=-\tikzphysics@surface@w@hx  \pgf@y=0pt}
  \anchor{north east}{\pgf@x=\tikzphysics@surface@w@hx   \pgf@y=\tikzphysics@surface@w@hy}
  \anchor{north west}{\pgf@x=-\tikzphysics@surface@w@hx  \pgf@y=\tikzphysics@surface@w@hy}
  \anchor{south east}{\pgf@x=\tikzphysics@surface@w@hx   \pgf@y=-\tikzphysics@surface@w@hy}
  \anchor{south west}{\pgf@x=-\tikzphysics@surface@w@hx  \pgf@y=-\tikzphysics@surface@w@hy}

  %% ---- physics anchors ----

  %% base corners and apex are identical in formula across modes,
  %% because tx = -hx for bl, +hx for br, and the Thales x for top.
  \anchor{bl}  {\pgf@x=-\tikzphysics@surface@w@hx \pgf@y=-\tikzphysics@surface@w@hy}
  \anchor{br}  {\pgf@x=\tikzphysics@surface@w@hx  \pgf@y=-\tikzphysics@surface@w@hy}
  \anchor{top} {\pgf@x=\tikzphysics@surface@w@tx  \pgf@y=\tikzphysics@surface@w@hy}

  %% base-mid: midpoint of bl--br. Always (0, -hy).
  \anchor{base-mid}{\pgf@x=0pt \pgf@y=-\tikzphysics@surface@w@hy}

  %% right-mid: midpoint of the right-angle-adjacent non-base leg.
  %%   bl  mode: leg is (-hx,-hy)--(-hx,+hy), mid = (-hx, 0) = (tx, 0)
  %%   br  mode: leg is (+hx,-hy)--(+hx,+hy), mid = (+hx, 0) = (tx, 0)
  %%   top mode: no single "right-angle leg"; falls out as (tx, 0),
  %%             the vertical centre of the apex column.
  \anchor{right-mid}{\pgf@x=\tikzphysics@surface@w@tx \pgf@y=0pt}

  %% slope-mid: midpoint of the hypotenuse (sloped side).
  %%   bl mode:  br (+hx,-hy) -> apex (-hx,+hy), mid = (0, 0)
  %%   br mode:  bl (-hx,-hy) -> apex (+hx,+hy), mid = (0, 0)
  %%   top mode: the hypotenuse IS the base; we return the midpoint
  %%             of the LEFT leg for a useful "where a block sits
  %%             on the left slope" value.  Use slope-right-mid for
  %%             the right leg.
  \anchor{slope-mid}{%
    \def\tikzphysics@surface@ra@top{top}%
    \ifx\tikzphysics@surface@w@ra\tikzphysics@surface@ra@top
      \pgfmathsetlength{\pgf@x}{(-\tikzphysics@surface@w@hx+\tikzphysics@surface@w@tx)/2}%
      \pgf@y=0pt
    \else
      \pgf@x=0pt \pgf@y=0pt
    \fi
  }

  %% slope-right-mid: only meaningful in top mode; mid of apex--br.
  %%   Elsewhere this equals slope-mid for consistency.
  \anchor{slope-right-mid}{%
    \def\tikzphysics@surface@ra@top{top}%
    \ifx\tikzphysics@surface@w@ra\tikzphysics@surface@ra@top
      \pgfmathsetlength{\pgf@x}{(\tikzphysics@surface@w@hx+\tikzphysics@surface@w@tx)/2}%
      \pgf@y=0pt
    \else
      \pgf@x=0pt \pgf@y=0pt
    \fi
  }

  %% centroid = (bl + br + apex) / 3
  %%   = ((-hx + hx + tx)/3, (-hy - hy + hy)/3)
  %%   = (tx/3, -hy/3)   for ALL modes.
  \anchor{centroid}{%
    \pgfmathsetlength{\pgf@x}{\tikzphysics@surface@w@tx/3}%
    \pgfmathsetlength{\pgf@y}{-\tikzphysics@surface@w@hy/3}%
  }
  \anchor{mid}{%
    \pgfmathsetlength{\pgf@x}{\tikzphysics@surface@w@tx/3}%
    \pgfmathsetlength{\pgf@y}{-\tikzphysics@surface@w@hy/3}%
  }

  %% ---- background (fill/pattern) path ----
  %% Single triangle: bl -> br -> apex, where apex = (tx, hy)
  %% regardless of mode.
  \backgroundpath{%
    \pgfpathmoveto{\pgfpoint{-\tikzphysics@surface@w@hx}{-\tikzphysics@surface@w@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@w@hx}{-\tikzphysics@surface@w@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@w@tx}{\tikzphysics@surface@w@hy}}%
    \pgfpathclose%
  }

  %% ---- numeric edge anchors (CCW from bl on the triangle) ----
  %% base : bl -> br           (base-0 at bl,  base-100 at br)
  %% right: br -> apex         (right-0 at br, right-100 at apex)
  %% slope: apex -> bl         (slope-0 at apex, slope-100 at foot bl)
  %%
  %% In `physics wedge right angle at=br' (the default) the names match
  %% physics intuition: right is the vertical leg, slope is the
  %% hypotenuse.  In bl and top modes, the names still follow
  %% pure CCW ordering from bl, so `right' and `slope' refer to
  %% whichever geometric edges CCW yields (see the docs for what
  %% they mean in each mode).
  \tikzphysics@declareedgeanchors{base}
    {-\tikzphysics@surface@w@hx}{-\tikzphysics@surface@w@hy}
    {\tikzphysics@surface@w@hx}{-\tikzphysics@surface@w@hy}
  \tikzphysics@declareedgeanchors{right}
    {\tikzphysics@surface@w@hx}{-\tikzphysics@surface@w@hy}
    {\tikzphysics@surface@w@tx}{\tikzphysics@surface@w@hy}
  \tikzphysics@declareedgeanchors{slope}
    {\tikzphysics@surface@w@tx}{\tikzphysics@surface@w@hy}
    {-\tikzphysics@surface@w@hx}{-\tikzphysics@surface@w@hy}
}

%% Snapshot scalar geometry for \geometryvalue after a named wedge is built.
%% Interior angles are at the semantic vertices bl, br, and top. Edge
%% directions rise toward top; slope placement directions instead run along
%% the corresponding contact surface and can be passed directly to rotate.
\def\tikzphysics@surface@wedgegeometry@bl{%
  \def\tikzphysics@surface@g@leftangle{90}%
  \edef\tikzphysics@surface@g@rightangle{\tikzphysics@surface@g@inputangle}%
  \pgfmathsetmacro{\tikzphysics@surface@g@topangle}{90-\tikzphysics@surface@g@inputangle}%
  \def\tikzphysics@surface@g@leftdirection{90}%
  \pgfmathsetmacro{\tikzphysics@surface@g@rightdirection}{180-\tikzphysics@surface@g@inputangle}%
  \pgfmathsetmacro{\tikzphysics@surface@g@slopedirection}{-\tikzphysics@surface@g@inputangle}%
  \edef\tikzphysics@surface@g@rightslopedirection{\tikzphysics@surface@g@slopedirection}%
}
\def\tikzphysics@surface@wedgegeometry@br{%
  \edef\tikzphysics@surface@g@leftangle{\tikzphysics@surface@g@inputangle}%
  \def\tikzphysics@surface@g@rightangle{90}%
  \pgfmathsetmacro{\tikzphysics@surface@g@topangle}{90-\tikzphysics@surface@g@inputangle}%
  \edef\tikzphysics@surface@g@leftdirection{\tikzphysics@surface@g@inputangle}%
  \edef\tikzphysics@surface@g@slopedirection{\tikzphysics@surface@g@inputangle}%
  \edef\tikzphysics@surface@g@rightslopedirection{\tikzphysics@surface@g@slopedirection}%
  \def\tikzphysics@surface@g@rightdirection{90}%
}
\def\tikzphysics@surface@wedgegeometry@top{%
  \edef\tikzphysics@surface@g@leftangle{\tikzphysics@surface@g@inputangle}%
  \pgfmathsetmacro{\tikzphysics@surface@g@rightangle}{90-\tikzphysics@surface@g@inputangle}%
  \def\tikzphysics@surface@g@topangle{90}%
  \edef\tikzphysics@surface@g@leftdirection{\tikzphysics@surface@g@inputangle}%
  \edef\tikzphysics@surface@g@slopedirection{\tikzphysics@surface@g@inputangle}%
  \pgfmathsetmacro{\tikzphysics@surface@g@rightdirection}{90+\tikzphysics@surface@g@inputangle}%
  \pgfmathsetmacro{\tikzphysics@surface@g@rightslopedirection}{\tikzphysics@surface@g@inputangle-90}%
}

\newcommand{\tikzphysics@surface@recordwedgegeometry}[1]{%
  \begingroup
    \ifcsname pgf@sh@ma@#1\endcsname
      \csname pgf@sh@ma@#1\endcsname
      \edef\tikzphysics@surface@g@inputangle{\tikzphysics@surface@w@ang}%
      \edef\tikzphysics@surface@g@mode{\tikzphysics@surface@w@ra}%
      \csname tikzphysics@surface@wedgegeometry@\tikzphysics@surface@g@mode\endcsname
      \@tempdima=\tikzphysics@surface@w@hx\relax
      \multiply\@tempdima by 2
      \edef\tikzphysics@surface@g@width{\the\@tempdima}%
      \@tempdima=\tikzphysics@surface@w@hy\relax
      \multiply\@tempdima by 2
      \edef\tikzphysics@surface@g@height{\the\@tempdima}%
      \tikzphysics@storegeometryvalue{#1}{left angle}{\tikzphysics@surface@g@leftangle}%
      \tikzphysics@storegeometryvalue{#1}{right angle}{\tikzphysics@surface@g@rightangle}%
      \tikzphysics@storegeometryvalue{#1}{top angle}{\tikzphysics@surface@g@topangle}%
      \tikzphysics@storegeometryvalue{#1}{base direction}{0}%
      \tikzphysics@storegeometryvalue{#1}{slope direction}{\tikzphysics@surface@g@slopedirection}%
      \tikzphysics@storegeometryvalue{#1}{left edge direction}{\tikzphysics@surface@g@leftdirection}%
      \tikzphysics@storegeometryvalue{#1}{right edge direction}{\tikzphysics@surface@g@rightdirection}%
      \tikzphysics@storegeometryvalue{#1}{base angle}{0}%
      \tikzphysics@storegeometryvalue{#1}{slope angle}{\tikzphysics@surface@g@slopedirection}%
      \tikzphysics@storegeometryvalue{#1}{surface angle}{\tikzphysics@surface@g@slopedirection}%
      \tikzphysics@storegeometryvalue{#1}{right slope angle}{\tikzphysics@surface@g@rightslopedirection}%
      \tikzphysics@storegeometryvalue{#1}{right edge angle}{\tikzphysics@surface@g@rightdirection}%
      \tikzphysics@storegeometryvalue{#1}{width}{\tikzphysics@surface@g@width}%
      \tikzphysics@storegeometryvalue{#1}{height}{\tikzphysics@surface@g@height}%
      \tikzphysics@storegeometryvalue{#1}{right angle at}{\tikzphysics@surface@g@mode}%
    \fi
  \endgroup
}

\tikzphysics@registergeometryrecorder{physicswedge}{\tikzphysics@surface@recordwedgegeometry}

%% ============================================================
%%  FLAT / WALL / CEILING SHAPES
%%
%%  Four thin rectangular shapes that share the same sizing
%%  primitive but differ in which edge carries the "surface"
%%  foreground line (and hence which side is the usable face):
%%
%%    physicsground    : surface on TOP edge  (6cm x 0.4cm default)
%%    physicsceiling   : surface on BOTTOM edge (2cm x 0.4cm default)
%%    physicswallleft  : surface on RIGHT edge (hatching appears on
%%                   the left side of the strip - so a "left
%%                   wall" whose usable face is its right edge)
%%                  default 0.4cm x 3cm (thickness x height)
%%    physicswallright : mirror of physicswallleft - surface on LEFT edge
%%
%%  Patterned hatching comes from the user-facing compound
%%  style (pattern=north east lines), not from the shape.
%%
%%  Anchors: 4 corners + 4 midpoints (top-mid, bottom-mid,
%%  left-mid, right-mid) + center, plus a convenience `surface'
%%  anchor that points at the useful face's midpoint.  Numeric
%%  edge anchors (bottom/right/top/left)-0..100 are declared
%%  CCW from bl on the bounding box.
%% ============================================================

\pgfdeclareshape{physicsground}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchor[from=rectangle]{south east}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchorborder[from=rectangle]

  \savedmacro{\tikzphysics@surface@g@hx}{%
    \tikzphysics@surface@setflatdims
    \edef\tikzphysics@surface@g@hx{\the\tikzphysics@surface@hx}%
  }
  \savedmacro{\tikzphysics@surface@g@hy}{%
    \tikzphysics@surface@setflatdims
    \edef\tikzphysics@surface@g@hy{\the\tikzphysics@surface@hy}%
  }

  \backgroundpath{%
    \pgfpathmoveto{\pgfpoint{-\tikzphysics@surface@g@hx}{-\tikzphysics@surface@g@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@g@hx}{-\tikzphysics@surface@g@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@g@hx}{\tikzphysics@surface@g@hy}}%
    \pgfpathlineto{\pgfpoint{-\tikzphysics@surface@g@hx}{\tikzphysics@surface@g@hy}}%
    \pgfpathclose%
  }
  \foregroundpath{%
    \pgfsetlinewidth{0.5pt}%
    \pgfpathmoveto{\pgfpoint{-\tikzphysics@surface@g@hx}{\tikzphysics@surface@g@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@g@hx}{\tikzphysics@surface@g@hy}}%
    \pgfusepath{stroke}%
  }

  \anchor{top-left}    {\pgf@x=-\tikzphysics@surface@g@hx \pgf@y=\tikzphysics@surface@g@hy}
  \anchor{top-right}   {\pgf@x=\tikzphysics@surface@g@hx  \pgf@y=\tikzphysics@surface@g@hy}
  \anchor{top-mid}     {\pgf@x=0pt                \pgf@y=\tikzphysics@surface@g@hy}
  \anchor{bottom-left} {\pgf@x=-\tikzphysics@surface@g@hx \pgf@y=-\tikzphysics@surface@g@hy}
  \anchor{bottom-right}{\pgf@x=\tikzphysics@surface@g@hx  \pgf@y=-\tikzphysics@surface@g@hy}
  \anchor{bottom-mid}  {\pgf@x=0pt                \pgf@y=-\tikzphysics@surface@g@hy}
  \anchor{left-mid}    {\pgf@x=-\tikzphysics@surface@g@hx \pgf@y=0pt}
  \anchor{right-mid}   {\pgf@x=\tikzphysics@surface@g@hx  \pgf@y=0pt}
  \anchor{surface}     {\pgf@x=0pt                \pgf@y=\tikzphysics@surface@g@hy}

  %% ---- numeric edge anchors (CCW from bl, bounding box) ----
  \tikzphysics@declareedgeanchors{bottom}
    {-\tikzphysics@surface@g@hx}{-\tikzphysics@surface@g@hy}
    {\tikzphysics@surface@g@hx}{-\tikzphysics@surface@g@hy}
  \tikzphysics@declareedgeanchors{right}
    {\tikzphysics@surface@g@hx}{-\tikzphysics@surface@g@hy}
    {\tikzphysics@surface@g@hx}{\tikzphysics@surface@g@hy}
  \tikzphysics@declareedgeanchors{top}
    {\tikzphysics@surface@g@hx}{\tikzphysics@surface@g@hy}
    {-\tikzphysics@surface@g@hx}{\tikzphysics@surface@g@hy}
  \tikzphysics@declareedgeanchors{left}
    {-\tikzphysics@surface@g@hx}{\tikzphysics@surface@g@hy}
    {-\tikzphysics@surface@g@hx}{-\tikzphysics@surface@g@hy}
}

\pgfdeclareshape{physicsceiling}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchor[from=rectangle]{south east}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchorborder[from=rectangle]

  \savedmacro{\tikzphysics@surface@c@hx}{%
    \tikzphysics@surface@setflatdims
    \edef\tikzphysics@surface@c@hx{\the\tikzphysics@surface@hx}%
  }
  \savedmacro{\tikzphysics@surface@c@hy}{%
    \tikzphysics@surface@setflatdims
    \edef\tikzphysics@surface@c@hy{\the\tikzphysics@surface@hy}%
  }

  \backgroundpath{%
    \pgfpathmoveto{\pgfpoint{-\tikzphysics@surface@c@hx}{-\tikzphysics@surface@c@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@c@hx}{-\tikzphysics@surface@c@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@c@hx}{\tikzphysics@surface@c@hy}}%
    \pgfpathlineto{\pgfpoint{-\tikzphysics@surface@c@hx}{\tikzphysics@surface@c@hy}}%
    \pgfpathclose%
  }
  \foregroundpath{%
    \pgfsetlinewidth{0.5pt}%
    \pgfpathmoveto{\pgfpoint{-\tikzphysics@surface@c@hx}{-\tikzphysics@surface@c@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@c@hx}{-\tikzphysics@surface@c@hy}}%
    \pgfusepath{stroke}%
  }

  \anchor{top-left}    {\pgf@x=-\tikzphysics@surface@c@hx \pgf@y=\tikzphysics@surface@c@hy}
  \anchor{top-right}   {\pgf@x=\tikzphysics@surface@c@hx  \pgf@y=\tikzphysics@surface@c@hy}
  \anchor{top-mid}     {\pgf@x=0pt                \pgf@y=\tikzphysics@surface@c@hy}
  \anchor{bottom-left} {\pgf@x=-\tikzphysics@surface@c@hx \pgf@y=-\tikzphysics@surface@c@hy}
  \anchor{bottom-right}{\pgf@x=\tikzphysics@surface@c@hx  \pgf@y=-\tikzphysics@surface@c@hy}
  \anchor{bottom-mid}  {\pgf@x=0pt                \pgf@y=-\tikzphysics@surface@c@hy}
  \anchor{left-mid}    {\pgf@x=-\tikzphysics@surface@c@hx \pgf@y=0pt}
  \anchor{right-mid}   {\pgf@x=\tikzphysics@surface@c@hx  \pgf@y=0pt}
  \anchor{surface}     {\pgf@x=0pt                \pgf@y=-\tikzphysics@surface@c@hy}

  %% ---- numeric edge anchors (CCW from bl, bounding box) ----
  \tikzphysics@declareedgeanchors{bottom}
    {-\tikzphysics@surface@c@hx}{-\tikzphysics@surface@c@hy}
    {\tikzphysics@surface@c@hx}{-\tikzphysics@surface@c@hy}
  \tikzphysics@declareedgeanchors{right}
    {\tikzphysics@surface@c@hx}{-\tikzphysics@surface@c@hy}
    {\tikzphysics@surface@c@hx}{\tikzphysics@surface@c@hy}
  \tikzphysics@declareedgeanchors{top}
    {\tikzphysics@surface@c@hx}{\tikzphysics@surface@c@hy}
    {-\tikzphysics@surface@c@hx}{\tikzphysics@surface@c@hy}
  \tikzphysics@declareedgeanchors{left}
    {-\tikzphysics@surface@c@hx}{\tikzphysics@surface@c@hy}
    {-\tikzphysics@surface@c@hx}{-\tikzphysics@surface@c@hy}
}

\pgfdeclareshape{physicswallleft}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchor[from=rectangle]{south east}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchorborder[from=rectangle]

  \savedmacro{\tikzphysics@surface@wl@hx}{%
    \tikzphysics@surface@setflatdims
    \edef\tikzphysics@surface@wl@hx{\the\tikzphysics@surface@hx}%
  }
  \savedmacro{\tikzphysics@surface@wl@hy}{%
    \tikzphysics@surface@setflatdims
    \edef\tikzphysics@surface@wl@hy{\the\tikzphysics@surface@hy}%
  }

  \backgroundpath{%
    \pgfpathmoveto{\pgfpoint{-\tikzphysics@surface@wl@hx}{-\tikzphysics@surface@wl@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@wl@hx}{-\tikzphysics@surface@wl@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@wl@hx}{\tikzphysics@surface@wl@hy}}%
    \pgfpathlineto{\pgfpoint{-\tikzphysics@surface@wl@hx}{\tikzphysics@surface@wl@hy}}%
    \pgfpathclose%
  }
  %% surface on RIGHT edge (usable face points to +x)
  \foregroundpath{%
    \pgfsetlinewidth{0.5pt}%
    \pgfpathmoveto{\pgfpoint{\tikzphysics@surface@wl@hx}{-\tikzphysics@surface@wl@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@wl@hx}{\tikzphysics@surface@wl@hy}}%
    \pgfusepath{stroke}%
  }

  \anchor{top-left}    {\pgf@x=-\tikzphysics@surface@wl@hx \pgf@y=\tikzphysics@surface@wl@hy}
  \anchor{top-right}   {\pgf@x=\tikzphysics@surface@wl@hx  \pgf@y=\tikzphysics@surface@wl@hy}
  \anchor{top-mid}     {\pgf@x=0pt                 \pgf@y=\tikzphysics@surface@wl@hy}
  \anchor{bottom-left} {\pgf@x=-\tikzphysics@surface@wl@hx \pgf@y=-\tikzphysics@surface@wl@hy}
  \anchor{bottom-right}{\pgf@x=\tikzphysics@surface@wl@hx  \pgf@y=-\tikzphysics@surface@wl@hy}
  \anchor{bottom-mid}  {\pgf@x=0pt                 \pgf@y=-\tikzphysics@surface@wl@hy}
  \anchor{left-mid}    {\pgf@x=-\tikzphysics@surface@wl@hx \pgf@y=0pt}
  \anchor{right-mid}   {\pgf@x=\tikzphysics@surface@wl@hx  \pgf@y=0pt}
  \anchor{surface}     {\pgf@x=\tikzphysics@surface@wl@hx  \pgf@y=0pt}

  %% ---- numeric edge anchors (CCW from bl, bounding box) ----
  \tikzphysics@declareedgeanchors{bottom}
    {-\tikzphysics@surface@wl@hx}{-\tikzphysics@surface@wl@hy}
    {\tikzphysics@surface@wl@hx}{-\tikzphysics@surface@wl@hy}
  \tikzphysics@declareedgeanchors{right}
    {\tikzphysics@surface@wl@hx}{-\tikzphysics@surface@wl@hy}
    {\tikzphysics@surface@wl@hx}{\tikzphysics@surface@wl@hy}
  \tikzphysics@declareedgeanchors{top}
    {\tikzphysics@surface@wl@hx}{\tikzphysics@surface@wl@hy}
    {-\tikzphysics@surface@wl@hx}{\tikzphysics@surface@wl@hy}
  \tikzphysics@declareedgeanchors{left}
    {-\tikzphysics@surface@wl@hx}{\tikzphysics@surface@wl@hy}
    {-\tikzphysics@surface@wl@hx}{-\tikzphysics@surface@wl@hy}
}

\pgfdeclareshape{physicswallright}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchor[from=rectangle]{south east}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchorborder[from=rectangle]

  \savedmacro{\tikzphysics@surface@wr@hx}{%
    \tikzphysics@surface@setflatdims
    \edef\tikzphysics@surface@wr@hx{\the\tikzphysics@surface@hx}%
  }
  \savedmacro{\tikzphysics@surface@wr@hy}{%
    \tikzphysics@surface@setflatdims
    \edef\tikzphysics@surface@wr@hy{\the\tikzphysics@surface@hy}%
  }

  \backgroundpath{%
    \pgfpathmoveto{\pgfpoint{-\tikzphysics@surface@wr@hx}{-\tikzphysics@surface@wr@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@wr@hx}{-\tikzphysics@surface@wr@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@surface@wr@hx}{\tikzphysics@surface@wr@hy}}%
    \pgfpathlineto{\pgfpoint{-\tikzphysics@surface@wr@hx}{\tikzphysics@surface@wr@hy}}%
    \pgfpathclose%
  }
  %% surface on LEFT edge (usable face points to -x)
  \foregroundpath{%
    \pgfsetlinewidth{0.5pt}%
    \pgfpathmoveto{\pgfpoint{-\tikzphysics@surface@wr@hx}{-\tikzphysics@surface@wr@hy}}%
    \pgfpathlineto{\pgfpoint{-\tikzphysics@surface@wr@hx}{\tikzphysics@surface@wr@hy}}%
    \pgfusepath{stroke}%
  }

  \anchor{top-left}    {\pgf@x=-\tikzphysics@surface@wr@hx \pgf@y=\tikzphysics@surface@wr@hy}
  \anchor{top-right}   {\pgf@x=\tikzphysics@surface@wr@hx  \pgf@y=\tikzphysics@surface@wr@hy}
  \anchor{top-mid}     {\pgf@x=0pt                 \pgf@y=\tikzphysics@surface@wr@hy}
  \anchor{bottom-left} {\pgf@x=-\tikzphysics@surface@wr@hx \pgf@y=-\tikzphysics@surface@wr@hy}
  \anchor{bottom-right}{\pgf@x=\tikzphysics@surface@wr@hx  \pgf@y=-\tikzphysics@surface@wr@hy}
  \anchor{bottom-mid}  {\pgf@x=0pt                 \pgf@y=-\tikzphysics@surface@wr@hy}
  \anchor{left-mid}    {\pgf@x=-\tikzphysics@surface@wr@hx \pgf@y=0pt}
  \anchor{right-mid}   {\pgf@x=\tikzphysics@surface@wr@hx  \pgf@y=0pt}
  \anchor{surface}     {\pgf@x=-\tikzphysics@surface@wr@hx \pgf@y=0pt}

  %% ---- numeric edge anchors (CCW from bl, bounding box) ----
  \tikzphysics@declareedgeanchors{bottom}
    {-\tikzphysics@surface@wr@hx}{-\tikzphysics@surface@wr@hy}
    {\tikzphysics@surface@wr@hx}{-\tikzphysics@surface@wr@hy}
  \tikzphysics@declareedgeanchors{right}
    {\tikzphysics@surface@wr@hx}{-\tikzphysics@surface@wr@hy}
    {\tikzphysics@surface@wr@hx}{\tikzphysics@surface@wr@hy}
  \tikzphysics@declareedgeanchors{top}
    {\tikzphysics@surface@wr@hx}{\tikzphysics@surface@wr@hy}
    {-\tikzphysics@surface@wr@hx}{\tikzphysics@surface@wr@hy}
  \tikzphysics@declareedgeanchors{left}
    {-\tikzphysics@surface@wr@hx}{\tikzphysics@surface@wr@hy}
    {-\tikzphysics@surface@wr@hx}{-\tikzphysics@surface@wr@hy}
}

%% ============================================================
%%  ANCHOR AND KEY REGISTRATION (for debug overlays)
%% ============================================================

\tikzphysics@registeranchors{physicsplatformleft}{%
  corner, pulley-center, wall-root, transition-mid,
  floor-tl, floor-tr, floor-br, floor-bl,
  floor-top-mid, floor-bottom-mid, floor-left-mid, floor-right-mid,
  floor-center, wall-A, wall-B, wall-C, wall-D,
  wall-outer-mid, wall-inner-mid, wall-near-mid, wall-far-mid,
  wall-center, center}
\tikzphysics@registeranchors{physicsplatformright}{%
  corner, pulley-center, wall-root, transition-mid,
  floor-tl, floor-tr, floor-br, floor-bl,
  floor-top-mid, floor-bottom-mid, floor-left-mid, floor-right-mid,
  floor-center, wall-A, wall-B, wall-C, wall-D,
  wall-outer-mid, wall-inner-mid, wall-near-mid, wall-far-mid,
  wall-center, center}
\tikzphysics@registeranchors{physicsplatformboth}{%
  left-corner, right-corner, left-pulley-center, right-pulley-center,
  left-wall-root, right-wall-root,
  left-transition-mid, right-transition-mid,
  floor-tl, floor-tr, floor-br, floor-bl,
  floor-top-mid, floor-bottom-mid, floor-center,
  left-wall-A, left-wall-B, left-wall-C, left-wall-D,
  left-wall-outer-mid, left-wall-inner-mid,
  left-wall-near-mid, left-wall-far-mid,
  right-wall-A, right-wall-B, right-wall-C, right-wall-D,
  right-wall-outer-mid, right-wall-inner-mid,
  right-wall-near-mid, right-wall-far-mid, center}
\tikzphysics@registeranchors{physicswedge}{%
  bl, br, top, base-mid, slope-mid, slope-right-mid,
  surface-start, surface-end, surface-50, normal-50,
  right-mid, centroid, center, north, south, east, west}
\tikzphysics@registeranchors{physicsground}{%
  top-left, top-right, top-mid, left-mid, right-mid,
  bottom-left, bottom-right, bottom-mid, surface, center}
\tikzphysics@registeranchors{physicsceiling}{%
  top-left, top-right, top-mid, left-mid, right-mid,
  bottom-left, bottom-right, bottom-mid, surface, center}
\tikzphysics@registeranchors{physicswallleft}{%
  top-left, top-right, top-mid, left-mid, right-mid,
  bottom-left, bottom-right, bottom-mid, surface, center}
\tikzphysics@registeranchors{physicswallright}{%
  top-left, top-right, top-mid, left-mid, right-mid,
  bottom-left, bottom-right, bottom-mid, surface, center}

\tikzphysics@registerdisplayname{physicsplatformleft}{platform-left}
\tikzphysics@registerdisplayname{physicsplatformright}{platform-right}
\tikzphysics@registerdisplayname{physicsplatformboth}{platform}
\tikzphysics@registerdisplayname{physicswedge}{wedge}
\tikzphysics@registerdisplayname{physicsground}{ground}
\tikzphysics@registerdisplayname{physicsceiling}{ceiling}
\tikzphysics@registerdisplayname{physicswallleft}{wall-left}
\tikzphysics@registerdisplayname{physicswallright}{wall-right}

\tikzphysics@registerkeys{physicsplatformleft}{%
  minimum width, minimum height, strip width, wall angle,
  wall inset, wall drop, pulley edge}
\tikzphysics@registerkeydefaults{physicsplatformleft}{%
  minimum width/5cm, minimum height/2cm, strip width/0.25cm, wall angle/$-90^\circ$,
  wall inset/0cm, wall drop/0cm, pulley edge/off; preset uses 0.5cm inset and drop}
\tikzphysics@registerkeys{physicsplatformright}{%
  minimum width, minimum height, strip width, wall angle,
  wall inset, wall drop, pulley edge}
\tikzphysics@registerkeydefaults{physicsplatformright}{%
  minimum width/5cm, minimum height/2cm, strip width/0.25cm, wall angle/$-90^\circ$,
  wall inset/0cm, wall drop/0cm, pulley edge/off; preset uses 0.5cm inset and drop}
\tikzphysics@registerkeys{physicsplatformboth}{%
  minimum width, minimum height, strip width,
  wall angle, left wall angle, right wall angle,
  wall inset, left wall inset, right wall inset,
  wall drop, left wall drop, right wall drop,
  pulley edge, left pulley edge, right pulley edge, pulley edges}
\tikzphysics@registerkeydefaults{physicsplatformboth}{%
  minimum width/5cm, minimum height/2cm, strip width/0.25cm,
  wall angle/$-90^\circ$, left wall angle/$-90^\circ$, right wall angle/$-90^\circ$,
  wall inset/0cm, left wall inset/0cm, right wall inset/0cm,
  wall drop/0cm, left wall drop/0cm, right wall drop/0cm,
  pulley edge/off; shared preset uses 0.5cm inset and drop,
  left pulley edge/off; left-side preset uses 0.5cm inset and drop,
  right pulley edge/off; right-side preset uses 0.5cm inset and drop,
  pulley edges/off; both-side alias of pulley edge}
\tikzphysics@registerkeys{physicswedge}{%
  minimum width, wedge height, wedge angle, wedge right angle at}
\tikzphysics@registerkeydefaults{physicswedge}{%
  minimum width/4cm, wedge height/derived, wedge angle/$30^\circ$, wedge right angle at/br, surface guide length/0.5cm}
\tikzphysics@registerkeys{physicsground}{%
  minimum width, minimum height}
\tikzphysics@registerkeydefaults{physicsground}{%
  minimum width/6cm, minimum height/0.3cm}
\tikzphysics@registerkeys{physicsceiling}{%
  minimum width, minimum height}
\tikzphysics@registerkeydefaults{physicsceiling}{%
  minimum width/2cm, minimum height/0.3cm}
\tikzphysics@registerkeys{physicswallleft}{%
  minimum width, minimum height}
\tikzphysics@registerkeydefaults{physicswallleft}{%
  minimum width/0.3cm, minimum height/3cm}
\tikzphysics@registerkeys{physicswallright}{%
  minimum width, minimum height}
\tikzphysics@registerkeydefaults{physicswallright}{%
  minimum width/0.3cm, minimum height/3cm}

%% ============================================================
%%  COMPOUND NODE STYLES
%% ============================================================

\tikzset{
  physicsplatform-left/.style={
    shape=physicsplatformleft,
    physics logical shape=physicsplatformleft,
    anchor=floor-tl,
    draw=none,
    fill=white,
    pattern=north east lines,
    pattern color=black,
    inner sep=0pt,
    outer sep=0pt,
    minimum width=5cm,
    minimum height=2cm,
    physics debug setup, every physics object, every platform,
  },
  physicsplatform-right/.style={
    shape=physicsplatformright,
    physics logical shape=physicsplatformright,
    anchor=floor-tr,
    draw=none,
    fill=white,
    pattern=north east lines,
    pattern color=black,
    inner sep=0pt,
    outer sep=0pt,
    minimum width=5cm,
    minimum height=2cm,
    physics debug setup, every physics object, every platform,
  },
  physicsplatform-left-up/.style={physicsplatform-left, wall angle=90},
  physicsplatform-right-up/.style={physicsplatform-right, wall angle=90},
  physicsplatform-both/.style={
    shape=physicsplatformboth,
    physics logical shape=physicsplatformboth,
    anchor=floor-top-mid,
    draw=none,
    fill=white,
    pattern=north east lines,
    pattern color=black,
    inner sep=0pt,
    outer sep=0pt,
    minimum width=5cm,
    minimum height=2cm,
    physics debug setup, every physics object, every platform,
  },
  physicswedge/.style={
    shape=physicswedge,
    physics logical shape=physicswedge,
    physics geometry shape=physicswedge,
    physics logical shape=physicswedge,
    physics logical shape=physicswedge,
    anchor=bl,
    draw=black,
    line width=0.5pt,
    fill=none,
    pattern=dots,
    pattern color=black,
    inner sep=0pt,
    outer sep=0pt,
    minimum width=4cm,
    minimum height=3cm,
    physics debug setup, every physics object, every wedge,
  },
  physicsground/.style={
    shape=physicsground,
    physics logical shape=physicsground,
    anchor=top-mid,
    draw=none,
    fill=white,
    pattern=north east lines,
    pattern color=black,
    inner sep=0pt,
    outer sep=0pt,
    minimum width=6cm,
    minimum height=0.3cm,
    physics debug setup, every physics object, every ground,
  },
  physicsceiling/.style={
    shape=physicsceiling,
    physics logical shape=physicsceiling,
    anchor=bottom-mid,
    draw=none,
    fill=white,
    pattern=north east lines,
    pattern color=black,
    inner sep=0pt,
    outer sep=0pt,
    minimum width=2cm,
    minimum height=0.3cm,
    physics debug setup, every physics object, every ceiling,
  },
  physicswall-left/.style={
    shape=physicswallleft,
    physics logical shape=physicswallleft,
    anchor=right-mid,
    draw=none,
    fill=white,
    pattern=north east lines,
    pattern color=black,
    inner sep=0pt,
    outer sep=0pt,
    minimum width=0.3cm,
    minimum height=3cm,
    physics debug setup, every physics object, every wall-left,
  },
  physicswall-right/.style={
    shape=physicswallright,
    physics logical shape=physicswallright,
    anchor=left-mid,
    draw=none,
    fill=white,
    pattern=north east lines,
    pattern color=black,
    inner sep=0pt,
    outer sep=0pt,
    minimum width=0.3cm,
    minimum height=3cm,
    physics debug setup, every physics object, every wall-right,
  },
}

%% Short public names.  The physics-prefixed styles above remain available
%% when a document or another TikZ library already uses a generic name.
\tikzset{
  platform/.style={physicsplatform-both},
  platform-left/.style={physicsplatform-left},
  platform-right/.style={physicsplatform-right},
  platform-left-up/.style={physicsplatform-left-up},
  platform-right-up/.style={physicsplatform-right-up},
  platform-both/.style={physicsplatform-both},
  wedge/.style={physicswedge},
  ground/.style={physicsground},
  ceiling/.style={physicsceiling},
  wall-left/.style={physicswall-left},
  wall-right/.style={physicswall-right},
}

\tikzset{
  physics platform width/.value required,
  physics platform depth/.value required,
  physics strip width/.value required,
  physics wall angle/.value required,
  physics left wall angle/.value required,
  physics right wall angle/.value required,
  physics wall inset/.value required,
  physics left wall inset/.value required,
  physics right wall inset/.value required,
  physics wall drop/.value required,
  physics left wall drop/.value required,
  physics right wall drop/.value required,
  physics wedge width/.value required,
  physics wedge height/.value required,
  physics wedge angle/.value required,
  physics ground width/.value required,
  physics ground depth/.value required,
  physics ceiling width/.value required,
  physics ceiling depth/.value required,
  physics wall thickness/.value required,
  physics wall height/.value required,
  surface guide length/.value required,
}
\makeatother
\endinput
%%
%% End of file `tikzlibrarytikzphysics.surface.code.tex'.
