%% tikzphysics.tex -- user manual for tikzphysics 1.2.0
\documentclass[11pt]{article}

\usepackage[T1]{fontenc}
\usepackage{fourier}
\usepackage[a4paper,margin=22mm,headheight=14pt]{geometry}
\usepackage{microtype}
\usepackage{parskip}
\usepackage{needspace}
\usepackage{booktabs}
\usepackage{tabularx}
\usepackage{array}
\usepackage{enumitem}
\usepackage{xcolor}
\usepackage{minted}
\usepackage{fancyhdr}
\usepackage{hyperref}
\usepackage{tikzphysics}

\definecolor{physicsblue}{HTML}{1E4E79}
\definecolor{physicsteal}{HTML}{0B6E69}
\definecolor{physicssoft}{HTML}{F2F6F8}
\definecolor{physicscode}{HTML}{263238}
\definecolor{physicsgray}{HTML}{5E6A71}
\definecolor{physicscodebg}{HTML}{282A36}

\hypersetup{
  colorlinks=true,
  linkcolor=physicsblue,
  urlcolor=physicsteal,
  pdftitle={tikzphysics - TikZ-native physics diagrams},
  pdfauthor={Vaibhav Blayer},
  pdfsubject={User manual for tikzphysics 1.2.0},
  pdfkeywords={LaTeX, TikZ, physics, diagrams, mechanics, optics},
}

\pagestyle{fancy}
\fancyhf{}
\fancyhead[L]{\textcolor{physicsgray}{\texttt{tikzphysics} 1.2.0}}
\fancyhead[R]{\textcolor{physicsgray}{User manual}}
\fancyfoot[C]{\thepage}
\renewcommand{\headrulewidth}{0.3pt}

\setlist{nosep,leftmargin=*}
\setcounter{tocdepth}{2}
\setlength{\emergencystretch}{2em}

\usemintedstyle{friendly}
\setminted{
  fontsize=\footnotesize,
  bgcolor=physicssoft,
  breaklines=true,
  breakanywhere=true,
  autogobble=true,
  tabsize=2,
  frame=single,
  framesep=3mm,
  baselinestretch=1.05,
  formatcom=\color{black},
  linenos=false,
  samepage=true,
}

\let\physicsoriginalsubsection\subsection
\renewcommand{\subsection}{\Needspace{8\baselineskip}\physicsoriginalsubsection}
\let\physicsoriginalsubsubsection\subsubsection
\renewcommand{\subsubsection}{\Needspace{6\baselineskip}\physicsoriginalsubsubsection}

\newcommand{\key}[1]{\texttt{#1}}
\newcommand{\sty}[1]{\texttt{#1}}
\newcommand{\module}[1]{\texttt{tikzphysics.#1}}
\newcommand{\physicsnote}[1]{%
  \par\smallskip
  \noindent\colorbox{physicssoft}{%
    \parbox{\dimexpr\linewidth-2\fboxsep\relax}{\textcolor{physicsblue}{\textbf{Note.}} #1}}%
  \par\smallskip
}

\newcolumntype{K}{>{\ttfamily\raggedright\arraybackslash}p{0.31\linewidth}}
\newcolumntype{D}{>{\raggedright\arraybackslash}X}

\title{%
  \vspace{-1.5cm}
  {\Huge\bfseries\textcolor{physicsblue}{\texttt{tikzphysics}}}\\[5pt]
  {\Large TikZ-native physics diagrams}\\[12pt]
  {\large Version 1.2.0}}
\author{Vaibhav Blayer\\\href{mailto:vaibhavblayer@gmail.com}{vaibhavblayer@gmail.com}}
\date{2026-09-05}

\begin{document}
\maketitle

\begin{abstract}
\noindent
\texttt{tikzphysics} extends TikZ with reusable shapes and geometric anchors for
classical-physics diagrams. It provides continuous contact surfaces, straight
and circular ramps, inclined planes, blocks, springs, pulleys, concave and convex mirrors, convex and concave lenses,
slabs, and prisms. Mechanics primitives include particles, disks, supports,
vectors, and pendulums. Diagrams use ordinary TikZ nodes, paths, and named pics.
\end{abstract}

\noindent\colorbox{physicssoft}{%
  \parbox{\dimexpr\linewidth-2\fboxsep\relax}{%
    \textbf{In one line:}
    \key{\textbackslash node[wedge, wedge angle=30] (W) \{\};}}}

\tableofcontents
\clearpage

% -----------------------------------------------------------------------------
\section{Start here}\label{sec:start}


\subsection{Your first diagram in five minutes}
Copy \texttt{tikzphysics.sty} and every \texttt{tikzlibrarytikzphysics*.code.tex}
file next to your document, including the \texttt{catalog} file. Compile this
complete document with pdfLaTeX. No shell escape is needed to use the package.
\Needspace{10\baselineskip}
\begin{minted}{latex}
\documentclass[tikz,border=5mm]{standalone}
\usepackage{tikzphysics}
\begin{document}
\begin{tikzpicture}
  \node[block] (B) at (3,0) {$m$};
  \draw[spring] (0,0) -- node[above] {$k$} (B.west);
\end{tikzpicture}
\end{document}
\end{minted}
\begin{center}
\begin{tikzpicture}
  \node[block] (B) at (3,0) {$m$};
  \draw[spring] (0,0) -- node[above] {$k$} (B.west);
\end{tikzpicture}
\end{center}
Read this as: create a \sty{block}, name it \key{B}, and connect a
\sty{spring} to its \key{west} anchor. Change \key{(3,0)} to move the block;
change \key{minimum width} to resize it. The spring follows its endpoints.

\subsection{How to explore this manual}
\begin{tabularx}{\linewidth}{@{}p{.36\linewidth}D@{}}
\toprule
Your next task & Where to go \\
\midrule
Choose defaults for a whole worksheet & Section~\ref{sec:defaults} \\
Build the spring--block--pulley example & Section~\ref{sec:complete-system} \\
Find anchors while drawing & Section~\ref{sec:debug} \\
Draw supports, vectors, or pendulums & Section~\ref{sec:primitives} \\
Look up every feature's keys and anchors & Section~\ref{sec:reference} \\
Troubleshoot placement or transformations & Section~\ref{sec:troubleshooting} \\
\bottomrule
\end{tabularx}
The examples directory contains complete documents. Its \texttt{README.md}
provides a learning route and explains what each example demonstrates.

\subsection{Loading}

Load every module with the package wrapper:

\Needspace{3\baselineskip}
\begin{minted}{latex}
\usepackage{tikzphysics}
\end{minted}

For smaller documents, load only the required TikZ libraries:

\Needspace{4\baselineskip}
\begin{minted}{latex}
\usepackage{tikz}
\usetikzlibrary{tikzphysics.surface, tikzphysics.mechanics}
\end{minted}

The available libraries are \module{surface}, \module{ramps}, \module{mechanics},
\module{optics}, and \module{core}. Each feature library loads
\module{core} automatically.

\subsection{The design model}

\begin{enumerate}
  \item Choose a node style such as \sty{wedge}, \sty{block}, \sty{convex-lens},
        \sty{concave-lens}, \sty{slab}, or \sty{prism}.
  \item Use familiar TikZ sizing keys where they apply, and \key{physics ...}
        keys for shape-specific geometry or as unit-aware conveniences.
  \item Give each node a name and compose the diagram through its anchors;
        draw a spring directly between any two such coordinates.
\end{enumerate}

Short style names are the normal user interface. The longer forms remain
available when another package or the surrounding document already defines a
generic TikZ style such as \sty{block}.

\begin{tabularx}{\linewidth}{@{}KKD@{}}
\toprule
Short style & Collision-safe style & Object \\
\midrule
platform & physicsplatform-both & General platform with two configurable walls \\
platform-left / platform-right / platform-both & physicsplatform-left / physicsplatform-right /
  physicsplatform-both & Explicit platform variants \\
platform-left-up / platform-right-up & physicsplatform-left-up /
  physicsplatform-right-up & One-wall presets with \key{wall angle=90} \\
wedge & physicswedge & Inclined plane \\
ramp / ramp-left & physicsramp & Continuous wall--floor--linear-incline body \\
curved-ramp / curved-ramp-left & physicscurvedramp & Circular contact ramp with a filled body \\
ground / ceiling & physicsground / physicsceiling & Horizontal contact strips \\
wall-left / wall-right & physicswall-left / physicswall-right & Vertical contact strips \\
block / pulley & physicsblock / physicspulley & Mechanics nodes \\
spring & physics spring / physicsspring & Coil decoration for \key{\textbackslash draw} paths \\
concave-mirror / convex-mirror & physicsconcavemirror / physicsconvexmirror & Curved mirrors \\
convex-lens & physicsconvexlens & Symmetric biconvex lens \\
concave-lens & physicsconcavelens & Symmetric biconcave lens \\
slab & physicsslab & Parallel-sided rectangular slab \\
prism & physicsprism & Isosceles triangular prism \\
\bottomrule
\end{tabularx}

\Needspace{7\baselineskip}
\begin{minted}{latex}
\begin{tikzpicture}
  \node[wedge, wedge width=5, wedge angle=30] (W) at (0,0) {};
  \node[block, minimum width=0.9cm, minimum height=0.7cm,
        rotate=30, anchor=south] at (W.slope-mid) {$m$};
\end{tikzpicture}
\end{minted}

\begin{center}
\begin{tikzpicture}
  \node[wedge, wedge width=5, wedge angle=30] (W) at (0,0) {};
  \node[block, minimum width=0.9cm, minimum height=0.7cm,
        rotate=30, anchor=south] at (W.slope-mid) {$m$};
\end{tikzpicture}
\end{center}


\subsection{Set defaults once}\label{sec:defaults}
The default block is a 1\,cm square and the default pulley diameter is 1\,cm.
Simple names are the public interface: \sty{spring}, \sty{block},
\sty{pulley}, and \sty{wedge}. No slash-prefixed style is required.
Each node or path style offers an \key{every <name>} hook:
\Needspace{10\baselineskip}
\begin{minted}{latex}
\tikzset{
  every block/.style={minimum width=1cm,minimum height=1cm,fill=white},
  every spring/.style={pre length=3mm,post length=3mm,amplitude=2mm},
  every pulley/.style={minimum size=1cm}
}
\node[block] (A) {};
\node[block,minimum width=2cm] (B) at (3,0) {};
\draw[spring] (A.east) -- (B.west);
\end{minted}
For node and path styles, the order is built-in settings, the shared hook,
the feature hook, then later options on your node or path. This means a
local \key{minimum width=2cm} overrides \key{every block} when placed after
\sty{block}. A scope contains its own settings without changing later pictures.
A bare \key{minimum width} set at picture level may still be replaced by the
object's built-in dimensions; use \key{every block} for object-wide sizing.

\key{every physics object} applies to package node styles;
\key{every physics connection} applies to package path styles.
\key{every platform} covers all platform variants; the other node/path hooks
use the short feature name. The collision-safe hook \key{every physics block}
is called by the initial definition of \key{every block}; redefining the short
hook replaces that forwarding style. Do not put \sty{block} inside
\key{every block}, since that would call the hook recursively.

You can also use \key{spring/.append style=\{...\}}. Hooks are a convenient,
explicit place to keep preferences while retaining the short drawing syntax.
Built-in defaults are not the same as a key's missing-value default:
\key{show anchors} means \key{show anchors=true}, whereas geometric keys such
as \key{wedge angle} require a value. An omitted geometry key keeps its
inherited or built-in setting.

\subsection{Dimensions}

TikZ's native sizing keys are fully supported and are often the most familiar
choice. Use explicit units with them, for example
\key{minimum width=1.2cm}, \key{minimum height=8mm}, or
\key{minimum size=0.7cm}. Package convenience keys may be used instead. They
accept explicit dimensions and also interpret a bare value as centimetres, so
\key{block width=1.2} and \key{minimum width=1.2cm} produce the same
block size requirement.

\begin{tabularx}{\linewidth}{@{}>{\ttfamily\raggedright\arraybackslash}p{0.37\linewidth}
  >{\ttfamily\raggedright\arraybackslash}p{0.27\linewidth}D@{}}
\toprule
\normalfont Native TikZ (preferred) & \normalfont Package convenience & \normalfont Applies to \\
\midrule
minimum width / height & block width / height & \sty{block} \\
minimum size & pulley diameter & \sty{pulley} \\
minimum width / height & platform width / depth & Bent platforms \\
minimum width / height & ground width / depth & \sty{ground} \\
minimum width / height & ceiling width / depth & \sty{ceiling} \\
minimum width / height & wall thickness / height & Left and right walls \\
minimum width & wedge width & \sty{wedge} width only \\
minimum width & --- & \sty{ramp} overall horizontal width \\
minimum width / height & slab width / height & \sty{slab} \\
minimum width / height & prism width / height & \sty{prism} \\
\bottomrule
\end{tabularx}

The alternatives in each row set the same underlying TikZ size requirement.
If both are supplied, normal TikZ option ordering applies: the last value wins.
Put the shape style first, then the desired sizing keys, for example
\key{block, minimum width=1.2cm}. These are minimum dimensions; a node
may grow to contain wider or taller text.

Shape-specific keys remain necessary when they control more than a native node
size. In particular, use \key{wedge height} rather than
\key{minimum height} when the height should determine wedge geometry. Keys
such as \key{wall angle}, \key{strip width},
\key{convex lens radius}, and \key{prism apex angle} have no native TikZ sizing
equivalent. All package
size keys require positive values. Each concise wedge key also has a
collision-safe form prefixed by \key{physics}, as listed in the wedge section.

\subsection{Complete copy-paste examples}

Each example below includes the document class, package loading, document
environment, and complete TikZ picture. The first shows the basic composition
pattern: name a node, then place another node at one of its anchors.

\Needspace{14\baselineskip}
\begin{minted}{latex}
\documentclass[tikz, border=6mm]{standalone}
\usepackage{tikzphysics}

\begin{document}
\begin{tikzpicture}
  \node[platform, minimum width=5cm, minimum height=2cm]
    (platform) at (0,0) {};

  \node[pulley, minimum size=8mm]
    (pulley) at (platform.north east) {};
\end{tikzpicture}
\end{document}
\end{minted}

\begin{center}
\begin{tikzpicture}[scale=0.8,every node/.append style={transform shape}]
  \node[platform, minimum width=5cm, minimum height=2cm]
    (platform) at (0,0) {};
  \node[pulley, minimum size=8mm]
    (pulley) at (platform.north east) {};
\end{tikzpicture}
\end{center}

The next complete document composes an inclined plane, two blocks, a pulley,
and one exactly tangent string.

\Needspace{22\baselineskip}
\begin{minted}{latex}
\documentclass[tikz, border=6mm]{standalone}
\usepackage{tikzphysics}

\begin{document}
\begin{tikzpicture}
  \node[wedge, minimum width=6cm, wedge angle=30]
    (plane) at (0,0) {};

  \node[block, minimum width=1cm, minimum height=1cm,
        rotate=30, anchor=south]
    (surface-block) at (plane.slope-mid) {$m$};

  \node[pulley] (pulley) at (plane.top) {};

  \node[block, minimum width=8mm, minimum height=1cm]
    (load) at ($(pulley.east)+(0,-2.5)$) {$M$};

  \physicsstringoverpulley{surface-block.east}{pulley}{load.north}
\end{tikzpicture}
\end{document}
\end{minted}

\begin{center}
\begin{tikzpicture}[scale=0.72,every node/.append style={transform shape}]
  \node[wedge, minimum width=6cm, wedge angle=30]
    (plane) at (0,0) {};
  \node[block, minimum width=1cm, minimum height=1cm,
        rotate=30, anchor=south]
    (surface-block) at (plane.slope-mid) {$m$};
  \node[pulley] (pulley) at (plane.top) {};
  \node[block, minimum width=8mm, minimum height=1cm]
    (load) at ($(pulley.east)+(0,-2.5)$) {$M$};
  \physicsstringoverpulley{surface-block.east}{pulley}{load.north}
\end{tikzpicture}
\end{center}

\subsubsection*{Wedge key variants}

This complete document demonstrates angle-driven and height-driven geometry,
both width interfaces, and every value of
\key{wedge right angle at}.

\Needspace{32\baselineskip}
\begin{minted}{latex}
\documentclass[tikz, border=6mm]{standalone}
\usepackage{tikzphysics}

\begin{document}
\begin{tikzpicture}[font=\small]
  \node[wedge, minimum width=3cm, wedge angle=30,
        anchor=base-mid]
    (angle-br) at (0,0) {};
  \node[align=center] at (0,-0.65)
    {angle 30\textdegree\\right angle at br};

  \node[wedge, wedge width=3, wedge angle=40,
        wedge right angle at=bl, anchor=base-mid]
    (angle-bl) at (4.2,0) {};
  \node[align=center] at (4.2,-0.65)
    {width 3cm, angle 40\textdegree\\right angle at bl};

  \node[wedge, minimum width=3cm, wedge angle=45,
        wedge right angle at=top, anchor=base-mid]
    (angle-top) at (8.4,0) {};
  \node[align=center] at (8.4,-0.65)
    {angle 45\textdegree\\right angle at top};

  \node[wedge, minimum width=3.2cm, wedge height=2cm,
        anchor=base-mid]
    (height-driven) at (12.6,0) {};
  \node[align=center] at (12.6,-0.65)
    {height 2cm\\angle derived};
\end{tikzpicture}
\end{document}
\end{minted}

\begin{center}
\begin{tikzpicture}[font=\scriptsize,scale=0.8,every node/.append style={transform shape}]
  \node[wedge, minimum width=3cm, wedge angle=30,
        anchor=base-mid]
    (angle-br) at (0,0) {};
  \node[align=center] at (0,-0.65)
    {angle 30\textdegree\\right angle at br};
  \node[wedge, wedge width=3, wedge angle=40,
        wedge right angle at=bl, anchor=base-mid]
    (angle-bl) at (4.2,0) {};
  \node[align=center] at (4.2,-0.65)
    {width 3cm, angle 40\textdegree\\right angle at bl};
  \node[wedge, minimum width=3cm, wedge angle=45,
        wedge right angle at=top, anchor=base-mid]
    (angle-top) at (8.4,0) {};
  \node[align=center] at (8.4,-0.65)
    {angle 45\textdegree\\right angle at top};
  \node[wedge, minimum width=3.2cm, wedge height=2cm,
        anchor=base-mid]
    (height-driven) at (12.6,0) {};
  \node[align=center] at (12.6,-0.65)
    {height 2cm\\angle derived};
\end{tikzpicture}
\end{center}

% -----------------------------------------------------------------------------
\clearpage
\section{Contact surfaces and wedges}

\subsection{Bent platforms}

The three underlying platform shapes share a horizontal floor strip. The left
and right variants extend that strip through one bent wall; the general
\sty{platform} style uses the two-wall shape and is equivalent to the explicit
\sty{platform-both} style. Each node is rendered as one continuous
platform, without a hinge mark or seam. Wall direction is continuous rather
than limited to presets, so the gallery below covers every distinct
configuration class; intermediate angles use the same keys.

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Style & Configuration \\
\midrule
platform & General two-wall platform; equivalent to \sty{platform-both}. \\
platform-left & One wall at the left floor corner. \\
platform-right & One wall at the right floor corner. \\
platform-left-up & Left-wall preset with \key{wall angle=90}. \\
platform-right-up & Right-wall preset with \key{wall angle=90}. \\
platform-both & Two walls; set both with \key{wall angle}, or set them
  independently with \key{left wall angle} and
  \key{right wall angle}. \\
\bottomrule
\end{tabularx}

\subsubsection*{Variant gallery}

\begin{center}
\begin{tikzpicture}[font=\scriptsize]
  % Row 1: vertical variants
  \node[platform-left-up, platform width=2.2, platform depth=1,
        anchor=floor-top-mid] at (0,0) {};
  \node[align=center] at (0,-1.45) {up-left preset\\\key{90}};
  \node[platform-right-up, platform width=2.2, platform depth=1,
        anchor=floor-top-mid] at (3.8,0) {};
  \node[align=center] at (3.8,-1.45) {up-right preset\\\key{90}};
  \node[platform, platform width=2.2, platform depth=1,
        wall angle=-90, anchor=floor-top-mid] at (7.6,0) {};
  \node[align=center] at (7.6,-1.45) {down both\\\key{-90/-90}};
  \node[platform-both, platform width=2.2, platform depth=1,
        wall angle=90, anchor=floor-top-mid] at (11.4,0) {};
  \node[align=center] at (11.4,-1.45) {up both\\\key{90/90}};

  % Row 2: sloped variants
  \node[platform-left, platform width=2.2, platform depth=1,
        wall angle=135, anchor=floor-top-mid] at (0,-3) {};
  \node[align=center] at (0,-4.45) {outward left\\\key{135}};
  \node[platform-right, platform width=2.2, platform depth=1,
        wall angle=45, anchor=floor-top-mid] at (3.8,-3) {};
  \node[align=center] at (3.8,-4.45) {outward right\\\key{45}};
  \node[platform, platform width=2.2, platform depth=1,
        left wall angle=135, right wall angle=45,
        anchor=floor-top-mid] at (7.6,-3) {};
  \node[align=center] at (7.6,-4.45) {outward both\\\key{135/45}};
  \node[platform-both, platform width=2.2, platform depth=1,
        left wall angle=45, right wall angle=135,
        anchor=floor-top-mid] at (11.4,-3) {};
  \node[align=center] at (11.4,-4.45) {inward both\\\key{45/135}};

  % Row 3: straight and independently angled variants
  \node[platform-left, platform width=2.2, platform depth=1,
        wall angle=180, anchor=floor-top-mid] at (0,-6) {};
  \node[align=center] at (0,-7.45) {straight left\\\key{180}};
  \node[platform-right, platform width=2.2, platform depth=1,
        wall angle=0, anchor=floor-top-mid] at (3.8,-6) {};
  \node[align=center] at (3.8,-7.45) {straight right\\\key{0}};
  \node[platform-both, platform width=2.2, platform depth=1,
        left wall angle=180, right wall angle=0,
        anchor=floor-top-mid] at (7.6,-6) {};
  \node[align=center] at (7.6,-7.45) {straight both\\\key{180/0}};
  \node[platform-both, platform width=2.2, platform depth=1,
        left wall angle=120, right wall angle=-35,
        anchor=floor-top-mid] at (11.4,-6) {};
  \node[align=center] at (11.4,-7.45) {asymmetric\\\key{120/-35}};
\end{tikzpicture}
\end{center}

\begin{tabularx}{\linewidth}{@{}>{\ttfamily\raggedright\arraybackslash}p{0.28\linewidth}
  >{\ttfamily\raggedright\arraybackslash}p{0.28\linewidth}D@{}}
\toprule
\normalfont Concise key & \normalfont Collision-safe alias & \normalfont Meaning and default \\
\midrule
minimum width / platform width & physics platform width & Overall floor width; default \texttt{5cm}. \\
minimum height / platform depth & physics platform depth & Wall length and nominal vertical extent; default
  \texttt{2cm}. \\
strip width & physics strip width & Thickness of the floor and walls; default \texttt{0.25cm}. \\
wall angle & physics wall angle & Direction of every wall, measured counter-clockwise from the
  positive x-axis; default \texttt{-90}. \\
left wall angle & physics left wall angle & Left-wall override for \sty{platform-both}. \\
right wall angle & physics right wall angle & Right-wall override for \sty{platform-both}. \\
\bottomrule
\end{tabularx}

\clearpage
\subsubsection*{Key-by-key variants}

Each public platform key can be varied independently and combined with any
configuration from the preceding gallery. These examples isolate the visual
effect of all six keys.

\begin{center}
\begin{tikzpicture}[font=\scriptsize]
  % Row 1: dimensions
  \node[platform-both, platform width=3.8, platform depth=0.8,
        anchor=floor-top-mid] at (0,0) {};
  \node[align=center] at (0,-1.85)
    {wide floor\\\key{platform width=3.8}};
  \node[platform-both, platform width=2.5, platform depth=1.5,
        anchor=floor-top-mid] at (5.2,0) {};
  \node[align=center] at (5.2,-1.85)
    {deep walls\\\key{platform depth=1.5}};
  \node[platform-both, platform width=2.8, platform depth=1,
        strip width=0.5, anchor=floor-top-mid] at (10.4,0) {};
  \node[align=center] at (10.4,-1.85)
    {thick material\\\key{strip width=0.5}};

  % Row 2: shared and independent directions
  \node[platform-both, platform width=2.6, platform depth=1.1,
        wall angle=70, anchor=floor-top-mid] at (0,-4) {};
  \node[align=center] at (0,-5.65)
    {shared direction\\\key{wall angle=70}};
  \node[platform-both, platform width=2.6, platform depth=1.1,
        left wall angle=135, right wall angle=-90,
        anchor=floor-top-mid] at (5.2,-4) {};
  \node[align=center] at (5.2,-5.65)
    {left override\\\key{left wall angle=135}};
  \node[platform-both, platform width=2.6, platform depth=1.1,
        left wall angle=-90, right wall angle=45,
        anchor=floor-top-mid] at (10.4,-4) {};
  \node[align=center] at (10.4,-5.65)
    {right override\\\key{right wall angle=45}};
\end{tikzpicture}
\end{center}

The floor and wall contact lines meet at a fixed \key{corner}. The complete
floor-and-wall body is one closed polygon: its outer contact line and inner
edge both meet in exact, sharp V-shaped miters. The two-wall style exposes
\key{left-corner} and \key{right-corner}; these lie on the same continuous
geometry rather than on separately assembled parts. Angles may vary
continuously; only a left wall at $0^\circ$ and a right wall at $180^\circ$
(modulo $360^\circ$) are excluded because they retrace the floor and have no
finite miter.

\begin{center}
\begin{tikzpicture}[font=\small]
  \node[platform-left, platform width=5, platform depth=2.2,
        wall angle=125, anchor=corner] (P) at (0,0) {};
  \draw[physicsblue,very thick]
    (P.wall-outer-55) -- (P.corner) -- (P.floor-top-25);
  \fill[physicsblue] (P.corner) circle (1.5pt);
  \node[physicsblue,below left=2pt] at (P.corner) {fixed \key{corner}};
  \fill[physicsteal] (P.floor-top-25) circle (1.2pt);
  \node[physicsteal,above=2pt] at (P.floor-top-25) {\key{floor-top-25}};
\end{tikzpicture}
\end{center}

\subsubsection*{Platform anchors}

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Family & Available anchors \\
\midrule
Surface corner & \key{corner}; for the two-wall style, \key{left-corner} and
  \key{right-corner}. \\
Floor corners & \key{floor-tl}, \key{floor-tr}, \key{floor-br},
  \key{floor-bl}. \\
Floor midpoints & \key{floor-top-mid}, \key{floor-bottom-mid},
  \key{floor-left-mid}, \key{floor-right-mid}, \key{floor-center}. \\
Wall corners & \key{wall-A}, \key{wall-B}, \key{wall-C}, \key{wall-D},
  ordered as outer-near, inner-miter, inner-far, outer-far. \\
Wall midpoints & \key{wall-outer-mid}, \key{wall-inner-mid},
  \key{wall-near-mid}, \key{wall-far-mid}, \key{wall-center}. \\
Two-wall prefixes & Use \key{left-wall-...} and \key{right-wall-...} for
  wall corners, midpoints, and numeric wall edges. \\
\bottomrule
\end{tabularx}

Every floor and wall edge also provides integer anchors from 0 through 100,
for example \key{floor-top-25}, \key{wall-outer-50}, and
\key{right-wall-inner-75}.

\clearpage
\subsection{Wedges}

\sty{wedge} creates a right triangle for inclined-plane diagrams.
Its material uses TikZ's \key{dots} pattern by default; a later
\key{pattern=...} option can replace it normally.

\begin{center}
\begin{tikzpicture}[font=\footnotesize]
  \node[wedge, wedge width=3.2, wedge angle=32] (A) at (0,0) {};
  \node[below=3pt] at (A.base-mid) {right angle at \key{br}};

  \node[wedge, wedge width=3.2, wedge angle=40,
        wedge right angle at=bl] (B) at (4.4,0) {};
  \node[below=3pt] at (B.base-mid) {right angle at \key{bl}};

  \node[wedge, wedge width=3.2,
        wedge right angle at=top] (C) at (8.8,0) {};
  \node[below=3pt] at (C.base-mid) {right angle at \key{top}};
\end{tikzpicture}
\end{center}

\begin{tabularx}{\linewidth}{@{}>{\ttfamily\raggedright\arraybackslash}p{0.27\linewidth}
  >{\ttfamily\raggedright\arraybackslash}p{0.34\linewidth}D@{}}
\toprule
\normalfont Concise key & \normalfont Collision-safe alias & \normalfont Meaning and default \\
\midrule
wedge width & physics wedge width & Base width; default \texttt{4cm}. \\
wedge height & physics wedge height & Explicit height when no angle is supplied. \\
wedge angle & physics wedge angle & Authoritative acute angle; default is 30 degrees for
  \key{bl}/\key{br}, and 45 degrees for \key{top}. \\
wedge right angle at & physics wedge right angle at & One of \key{br} (default), \key{bl}, or
  \key{top}. \\
\bottomrule
\end{tabularx}

Geometry precedence is \key{wedge angle}, then \key{wedge height}, then
the mode default. The principal anchors are \key{bl}, \key{br}, \key{top},
\key{base-mid}, \key{right-mid}, \key{slope-mid},
\key{slope-right-mid}, and \key{centroid}. Numeric edge families are
\key{base-0..100}, \key{right-0..100}, and \key{slope-0..100}.


\subsubsection*{Attach to the usable incline}
Prefer \key{surface-0..100} when positioning an object on the contact face.
Unlike the older CCW edge names, this family selects the actual incline in
all three modes and always runs left to right. In \key{top} mode it selects
the left face; \key{right-surface-0..100} selects the right face. In the other
two modes the right family refers to the same incline.
\Needspace{6\baselineskip}
\begin{minted}{latex}
\node[wedge,wedge right angle at=bl,wedge angle=30] (W) {};
\path (W.tangent-before-50) -- (W.tangent-after-50)
  node[midway,sloped,block,anchor=south] (B) {$m$};
\draw[force] (W.surface-25) -- (W.normal-25);
\end{minted}
The endpoint names are \key{surface-start} and \key{surface-end}.
The following guides are saved per node:
\begin{tabularx}{\linewidth}{@{}p{.48\linewidth}D@{}}
\toprule
Anchor or key & Meaning \\
\midrule
\key{tangent-before-T}, \key{tangent-after-T} & Two points straddling the contact point. \\
\key{normal-T} & A point outside the wedge, along its normal. \\
\key{surface guide length} & Tangent separation and normal length; initially 0.5cm. \\
\key{right-tangent-before-T}, \key{right-tangent-after-T} & Corresponding guides on the right face in top mode. \\
\key{right-normal-T} & Normal guide for that face. \\
\bottomrule
\end{tabularx}
Nonuniform scaling changes perpendicularity; use rigid transformations or
uniform scaling for physical normals.

\subsubsection*{Named geometry values}

Every named wedge snapshots its resolved scalar geometry. Query the value
owned by node \key{W} with

\begin{center}
  \key{\textbackslash geometryvalue\{W\}\{property\}}
\end{center}

The collision-safe command
\key{\textbackslash tikzphysicsgeometryvalue\{W\}\{property\}} has the same
result. The wedge must be named and its node command must finish before either
command is used. Because the result is a fixed literal, it can appear directly
inside \key{rotate=...}, a PGF calculation, or a label.

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Property & Meaning \\
\midrule
left angle & Interior angle at \key{bl}, in degrees \\
right angle & Interior angle at \key{br}, in degrees \\
top angle & Interior angle at \key{top}, in degrees \\
base direction & Direction from \key{bl} to \key{br} \\
left edge direction & Rising direction from \key{bl} to \key{top} \\
right edge direction & Rising direction from \key{br} to \key{top} \\
slope angle, slope direction, surface angle & Placement rotation for the surface at \key{slope-mid} \\
right slope angle & Placement rotation for the surface at \key{slope-right-mid} \\
base angle, right edge angle & Aliases for \key{base direction} and \key{right edge direction} \\
width, height & Resolved TeX dimensions \\
right angle at & The text value \key{bl}, \key{br}, or \key{top} \\
\bottomrule
\end{tabularx}

\clearpage
Angles and directions are returned as numbers without a degree symbol.
Directions use degrees counter-clockwise from the wedge's local positive
$x$-axis. The placement rotations for all wedge modes are:

\begin{center}
\begin{tabular}{@{}lcccc@{}}
\toprule
\key{right angle at} & \key{left angle} & \key{right angle} & \key{top angle} & \key{slope angle} \\
\midrule
\key{br} & $\theta$ & $90$ & $90-\theta$ & $\theta$ \\
\key{bl} & $90$ & $\theta$ & $90-\theta$ & $-\theta$ \\
\key{top} & $\theta$ & $90-\theta$ & $90$ & $\theta$ \\
\bottomrule
\end{tabular}
\end{center}

Here \key{slope angle} follows the contact surface selected by
\key{slope-mid}; it is therefore the property normally wanted for a block.
In \key{top} mode this is the left face. Use \key{right slope angle}, equal to
$\theta-90$, with \key{slope-right-mid} for the right face.

\Needspace{10\baselineskip}
\begin{minted}{latex}
\node[wedge, minimum width=6cm, wedge angle=32] (W) at (0,0) {};

\node[block, minimum width=1cm, minimum height=0.8cm,
      rotate=\geometryvalue{W}{slope angle}, anchor=south]
  (B) at (W.slope-mid) {$m$};

\node at (W.bl)
  {$\pgfmathprintnumber{\geometryvalue{W}{left angle}}^\circ$};
\end{minted}

\begin{center}
\begin{tikzpicture}[font=\footnotesize]
  \node[wedge, minimum width=6cm, wedge angle=32] (GW) at (0,0) {};
  \node[block, minimum width=1cm, minimum height=0.8cm,
        rotate=\geometryvalue{GW}{slope angle}, anchor=south]
    at (GW.slope-mid) {$m$};
  \node[below left=2pt] at (GW.bl)
    {$\pgfmathprintnumber{\geometryvalue{GW}{left angle}}^\circ$};
  \node[below right=2pt] at (GW.br)
    {$\pgfmathprintnumber{\geometryvalue{GW}{right angle}}^\circ$};
  \node[above right=2pt] at (GW.top)
    {$\pgfmathprintnumber{\geometryvalue{GW}{top angle}}^\circ$};
  \node[fill=white,inner sep=2pt] at (GW.centroid)
    {slope direction
     $=\pgfmathprintnumber{\geometryvalue{GW}{slope direction}}^\circ$};
\end{tikzpicture}
\end{center}

These direction values describe the untransformed wedge. They work directly
when the wedge and attached object share the same transformed scope. If the
wedge has its own independent rotation or a non-uniform scale, orient the
attached object from edge anchors with TikZ's \key{sloped} placement instead;
that follows the final rendered edge. The complete copy-ready source is
\path{examples/wedge-geometry-values.tex}.

\clearpage
\subsection{Ground, ceiling, and walls}

\begin{center}
\begin{tikzpicture}[font=\footnotesize]
  \node[ground, ground width=3.3] (G) at (0,0) {};
  \node[below=3pt] at (G.bottom-mid) {\sty{ground}};
  \node[ceiling, ceiling width=3.3] (C) at (4.7,0) {};
  \node[above=3pt] at (C.top-mid) {\sty{ceiling}};
  \node[wall-left, wall height=1.7] (WL) at (8.2,0) {};
  \node[left=4pt] at (WL.left-mid) {\sty{wall-left}};
  \node[wall-right, wall height=1.7] (WR) at (10.2,0) {};
  \node[right=4pt] at (WR.right-mid) {\sty{wall-right}};
\end{tikzpicture}
\end{center}

The sizing keys are grouped by shape:

\begin{center}
\begin{tabular}{@{}ll@{}}
\sty{ground} & \key{ground width}, \key{ground depth} \\
\sty{ceiling} & \key{ceiling width}, \key{ceiling depth} \\
\sty{wall-left}, \sty{wall-right} & \key{wall thickness},
  \key{wall height}
\end{tabular}
\end{center}

Each shape exposes four corners, four edge midpoints, \key{center}, and
\key{surface}. Numeric anchors are available as \key{top-T}, \key{right-T},
\key{bottom-T}, and \key{left-T}, where $T=0,\ldots,100$.

% -----------------------------------------------------------------------------
\clearpage
\section{Straight and curved ramps}

The \module{ramps} library provides two comparatively unusual mechanics
surfaces as genuine TikZ node shapes.  They are not collections of overlaid
lines: each ramp body is one closed path that receives the node's fill or
pattern, and each usable contact surface is drawn once as a continuous line.

\begin{center}
\begin{tikzpicture}[font=\footnotesize]
  \node[ramp, minimum width=5.2cm, ramp run=1.8cm,
        ramp angle=32, ramp wall height=1.3cm] (SR) at (0,0) {};
  \node[below=5pt] at (SR.floor-mid) {\sty{ramp}};
  \fill[physicsblue] (SR.ramp-foot) circle (1.4pt);
  \physicsrampangle[angle radius=5mm]{SR}{$32^\circ$}

  \node[curved-ramp, curved ramp floor length=1.3cm,
        curved ramp radius=2.1cm,
        curved ramp angle=75, curved ramp back extension=0.6cm]
    (CR) at (7.2,0) {};
  \node[below=5pt] at (CR.base-end) {\sty{curved-ramp}};
  \fill[physicsblue] (CR.curve-55) circle (1.4pt);
  \draw[physicsblue,->] (CR.curve-55) -- (CR.curve-normal-55);
\end{tikzpicture}
\end{center}

The default direction is right: parameter 0 is the low end and parameter 100
is the high end.  Use \key{ramp direction=left}, or the convenience styles
\sty{ramp-left} and \sty{curved-ramp-left}, to mirror the body.  The parameter
direction still runs from low to high, so algorithms and annotations do not
need to reverse their anchor numbers.

\subsection{Straight ramp geometry}

The straight ramp combines a vertical wall, a horizontal floor, and a linear
incline.  The floor-to-incline meeting point is a mathematically sharp vertex;
no rounding, joint circle, or seam is inserted.  \key{minimum width} is the
horizontal distance from the wall contact line to the high end.  The
\key{ramp run} occupies the final part of that width, so the flat length is

\[
  L_{\mathrm{flat}}=\texttt{minimum width}-\texttt{ramp run}.
\]

When \key{ramp angle} is supplied it is authoritative and the rise is
$h=L_{\mathrm{run}}\tan\theta$.  Otherwise an explicit \key{ramp rise}
determines the angle.  With neither key, the default angle is $30^\circ$.
Use \key{\textbackslash physicsrampangle\{R\}\{label\}}
after the node to draw the dashed reference ray, acute angle arc, and label at
the exact \key{ramp-foot}.  The command also works for \sty{ramp-left}; its
optional argument accepts ordinary TikZ angle-pic options.

\begin{tabularx}{\linewidth}{@{}>{\ttfamily\raggedright\arraybackslash}p{0.27\linewidth}
  >{\ttfamily\raggedright\arraybackslash}p{0.27\linewidth}D@{}}
\toprule
\normalfont Concise key & \normalfont Collision-safe alias & \normalfont Meaning and default \\
\midrule
minimum width & --- & Overall horizontal width; default \texttt{8.6cm}. \\
ramp run & physics ramp run & Horizontal run of the incline; default \texttt{2.6cm}. \\
ramp angle & physics ramp angle & Incline angle; default 30 degrees. \\
ramp rise & physics ramp rise & Explicit rise when no angle is supplied. \\
ramp wall height & physics ramp wall height & Contact-wall height; default \texttt{1.5cm}. \\
ramp wall width & physics ramp wall width & Material behind the wall; default \texttt{0.25cm}. \\
ramp depth & physics ramp depth & Material below the baseline; default \texttt{0.25cm}. \\
ramp direction & physics ramp direction & \key{right} (default) or \key{left}. \\
ramp guide length & physics ramp guide length & Length used by tangent/normal guide anchors; default \texttt{0.5cm}. \\
\bottomrule
\end{tabularx}

The following is a complete copy-paste document reproducing a wall, spring,
block, floor, and rising end as a single ramp node.

\Needspace{17\baselineskip}
\begin{minted}{latex}
\documentclass[tikz,border=6mm]{standalone}
\usepackage{tikzphysics}
\begin{document}
\begin{tikzpicture}[>=stealth]
  \node[ramp, minimum width=8.6cm, ramp run=2.6cm,
        ramp rise=1.5cm, ramp wall height=1.5cm] (R) at (0,0) {};

  \node[block, minimum width=1cm, minimum height=0.75cm,
        anchor=south] (B) at (R.floor-mid) {$m$};
  \coordinate (A) at (R.wall-mid |- B.west);
  \draw[spring] (A) -- node[above=3pt] {$k$} (B.west);
  \draw[->,thick] (B.east) -- ++(1.2,0) node[right] {$v$};
  \physicsrampangle{R}{$30^\circ$}
\end{tikzpicture}
\end{document}
\end{minted}

\subsection{Circular curved ramp geometry}

\sty{curved-ramp} begins with a horizontal floor extending left, then enters a
circular arc tangentially at $(0,0)$; it is not an arbitrary B\'ezier curve.
For radius $R$, sweep angle $\alpha$, and circular-arc parameter $t=T/100$,
the right-facing \key{curve-T} point is

\[
  x(T)=R\sin(t\alpha),\qquad
  y(T)=R\bigl(1-\cos(t\alpha)\bigr).
\]

Thus a 90-degree sweep ends at $(R,R)$ with a vertical tangent, exactly matching
the common quarter-circle ramp. The floor-to-curve transition has a common
horizontal tangent, so it contains no corner or visible joint. The body continues horizontally by
\key{curved ramp back extension}, then closes down to the baseline.  The
supported sweep range is greater than 0 and at most 90 degrees; this keeps the
filled body single-valued and prevents it folding back over itself.

\begin{tabularx}{\linewidth}{@{}>{\ttfamily\raggedright\arraybackslash}p{0.31\linewidth}
  >{\ttfamily\raggedright\arraybackslash}p{0.31\linewidth}D@{}}
\toprule
\normalfont Concise key & \normalfont Collision-safe alias & \normalfont Meaning and default \\
\midrule
curved ramp floor length & physics curved ramp floor length & Horizontal floor before the arc; default \texttt{2.5cm}. \\
curved ramp radius & physics curved ramp radius & Circular radius; default \texttt{4cm}. \\
curved ramp angle & physics curved ramp angle & Sweep angle; default 90 degrees. \\
curved ramp back extension & physics curved ramp back extension & Horizontal body after the arc; default \texttt{1cm}. \\
ramp depth & physics ramp depth & Material below the low endpoint; default \texttt{0.25cm}. \\
ramp direction & physics ramp direction & \key{right} or \key{left}. \\
ramp guide length & physics ramp guide length & Tangent/normal guide length; default \texttt{0.5cm}. \\
\bottomrule
\end{tabularx}

\subsection{Surface, tangent, and normal anchors}

Both ramp shapes expose \key{surface-0} through \key{surface-100}.  The short
forms \key{.0} through \key{.100} name exactly the same points.  On the
straight ramp the parameter follows arc length over the floor and then the
incline; it deliberately excludes the vertical wall. On the curved ramp it
follows arc length over the new horizontal floor and then the circular arc.
Use \key{curve-0..100} when a fraction of the circular portion alone is needed.

At every integer $T$, three orientation helpers are available:

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Anchor & Meaning \\
\midrule
tangent-before-T & Half a guide length before \key{surface-T} along the local tangent. \\
tangent-after-T & Half a guide length after \key{surface-T} along the local tangent. \\
normal-T & One guide length outward from \key{surface-T}, perpendicular to the surface. \\
curve-tangent-before-T & Half a guide length before \key{curve-T}. \\
curve-tangent-after-T & Half a guide length after \key{curve-T}. \\
curve-normal-T & Outward normal at \key{curve-T} only. \\
\bottomrule
\end{tabularx}

The tangent pair is symmetric about \key{surface-T}.  Consequently TikZ can
position and rotate a block without manually calculating its angle:

\Needspace{6\baselineskip}
\begin{minted}{latex}
\path (R.tangent-before-60) -- (R.tangent-after-60)
  node[midway,sloped,block,anchor=south] (B) {$m$};
\draw[->] (B.north) --
  ($(B.north)+(R.normal-60)-(R.surface-60)$) node[above left] {$N$};
\end{minted}

Named anchors provide the structural points:

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Shape & Named anchors \\
\midrule
Both & \key{center}, \key{surface-start}, \key{surface-mid},
  \key{surface-end}, \key{base-start}, \key{base-end}. \\
Straight ramp & \key{floor-start}, \key{floor-mid}, \key{floor-end},
  \key{ramp-foot}, \key{ramp-mid}, \key{ramp-top}, \key{wall-top},
  \key{wall-mid}, \key{wall-bottom}, \key{angle-baseline}, \key{angle-label}. \\
Curved ramp & \key{floor-start}, \key{floor-mid}, \key{floor-end},
  \key{curve-start}, \key{curve-mid}, \key{curve-end}, \key{curve-center},
  \key{back-top}, \key{back-bottom}. \\
\bottomrule
\end{tabularx}

Here is a complete curved-ramp document.  The dashed radius is perpendicular
to the tangent. The blue force arrow uses the exact outward-normal vector,
translated to begin at the block's north anchor so it does not cross the body.

\Needspace{20\baselineskip}
\begin{minted}{latex}
\documentclass[tikz,border=6mm]{standalone}
\usepackage{tikzphysics}
\begin{document}
\begin{tikzpicture}[>=stealth]
  \node[curved-ramp, curved ramp radius=4cm,
        curved ramp angle=90,
        curved ramp back extension=1cm] (R) at (0,0) {};

  \path (R.curve-tangent-before-60) -- (R.curve-tangent-after-60)
    node[midway,sloped,block,minimum width=1cm,
         minimum height=0.75cm,anchor=south] (B) {$m$};
  \draw[->,blue,thick] (B.north) --
    ($(B.north)+(R.curve-normal-60)-(R.curve-60)$)
    node[above left] {$N$};
  \draw[dashed] (R.curve-center) -- (R.curve-60)
    node[midway,left] {$r$};
\end{tikzpicture}
\end{document}
\end{minted}

\begin{center}
\begin{tikzpicture}[font=\footnotesize]
  \node[curved-ramp, curved ramp floor length=1.7cm,
        curved ramp radius=3.2cm,
        curved ramp angle=90, curved ramp back extension=0.8cm] (R) {};
  \path (R.curve-tangent-before-60) -- (R.curve-tangent-after-60)
    node[midway,sloped,block,minimum width=0.8cm,
         minimum height=0.6cm,anchor=south] (B) {$m$};
  \draw[physicsblue,->,thick] (B.north) --
    ($(B.north)+(R.curve-normal-60)-(R.curve-60)$)
    node[above left] {$N$};
  \draw[physicsgray,dashed] (R.curve-center) -- (R.curve-60);
  \fill[physicsteal] (R.floor-mid) circle (1.2pt)
    node[below=6pt,fill=white,inner sep=1pt] {\key{floor-mid}};
  \fill[physicsteal] (R.curve-20) circle (1.2pt)
    node[above left=3pt,fill=white,inner sep=1pt] {\key{curve-20}};
  \fill[physicsteal] (R.curve-80) circle (1.2pt)
    node[above left=3pt,fill=white,inner sep=1pt] {\key{curve-80}};
\end{tikzpicture}
\end{center}

\subsection{Styling and debug use}

The body follows ordinary TikZ styling.  Place the shape style first, then
override \key{pattern}, \key{pattern color}, \key{fill}, or \key{draw} in the
usual option order.  The contact line is always emitted once by the shape.
For example, \key{curved-ramp, pattern=grid, pattern color=gray} changes the
material rendering without changing anchors.

Debug overlays are especially useful for unfamiliar ramp geometry:

\Needspace{7\baselineskip}
\begin{minted}{latex}
\node[curved-ramp, curved ramp floor length=1.5cm,
      curved ramp radius=2.5cm,
      curved ramp angle=70,
      physics debug/anchors=true,
      physics debug/keys=true] (R) {};
\end{minted}

The key panel presents \key{minimum width} before package-specific sizing on
the straight ramp.  Anchor overlays show a compact representative set rather
than all 101 samples.  Use explicit \key{surface-T}, tangent, and normal
anchors when inspecting a particular value.

% -----------------------------------------------------------------------------
\clearpage
\section{Blocks, springs, and pulleys}

The \module{mechanics} library supplies block and pulley nodes, a spring path
style, and tangent pulley strings. They accept ordinary TikZ styling such as
\key{draw}, \key{line width}, and \key{scale}.


\subsection{Complete spring--block--pulley system}\label{sec:complete-system}
This example combines reusable defaults, a surface tangent, and the native
\key{to[over pulley=P]} connection. Copy the complete document below.
\Needspace{25\baselineskip}
\begin{minted}{latex}
\documentclass[tikz,border=6mm]{standalone}
\usepackage{tikzphysics}
\tikzset{
  every block/.style={minimum width=1cm,minimum height=1cm,fill=white},
  every pulley/.style={minimum size=1cm,fill=white},
  every spring/.style={pre length=3mm,post length=3mm,
    amplitude=2mm,segment length=2mm}
}
\begin{document}
\begin{tikzpicture}
  \node[wedge,minimum width=6cm,wedge angle=30] (W) {};
  % The contact anchors select the actual incline in every wedge mode.
  \path (W.tangent-before-50) -- (W.tangent-after-50)
    node[midway,sloped,block,anchor=south] (B) {$m_1$};
  \edef\InclineAngle{\geometryvalue{W}{slope angle}}
  \draw[thick] (W.surface-start) -- ++({\InclineAngle+90}:10mm);
  \coordinate (S) at ($(W.surface-start)+({\InclineAngle+90}:5mm)$);
  \draw[spring] (S) -- node[above=3mm,sloped] {$k$} (B.west);
  \node[pulley] (P) at (W.top) {};
  \node[block,minimum width=8mm,anchor=north] (H) at ($(P.east)+(0,-4cm)$) {$m_2$};
  \draw[rope] (B.east) to[over pulley=P] (H.north);
\end{tikzpicture}
\end{document}

\end{minted}
\begin{center}\begingroup
\tikzset{
  every block/.style={minimum width=1cm,minimum height=1cm,fill=white},
  every pulley/.style={minimum size=1cm,fill=white},
  every spring/.style={pre length=3mm,post length=3mm,
    amplitude=2mm,segment length=2mm}
}
\begin{tikzpicture}
  \node[wedge,minimum width=6cm,wedge angle=30] (W) {};
  % The contact anchors select the actual incline in every wedge mode.
  \path (W.tangent-before-50) -- (W.tangent-after-50)
    node[midway,sloped,block,anchor=south] (B) {$m_1$};
  \edef\InclineAngle{\geometryvalue{W}{slope angle}}
  \draw[thick] (W.surface-start) -- ++({\InclineAngle+90}:10mm);
  \coordinate (S) at ($(W.surface-start)+({\InclineAngle+90}:5mm)$);
  \draw[spring] (S) -- node[above=3mm,sloped] {$k$} (B.west);
  \node[pulley] (P) at (W.top) {};
  \node[block,minimum width=8mm,anchor=north] (H) at ($(P.east)+(0,-4cm)$) {$m_2$};
  \draw[rope] (B.east) to[over pulley=P] (H.north);
\end{tikzpicture}

\endgroup\end{center}
The 10\,mm block height matches the 10\,mm pulley diameter.
The hanging block has a local 8\,mm width for readability; the package default
remains a 1\,cm square. With the pulley
centred at the top vertex, the incoming rope is parallel to the incline.
The support's attachment is half the block height above the surface, so the
spring is parallel too. Changing one of these dimensions independently
requires adjusting the placement. This example is specifically the rising
\key{br} wedge arrangement; contact anchors support the other modes, but a
complete pulley layout must still be chosen for the intended route.

\subsection{Native rope connections}
\Needspace{5\baselineskip}
\begin{minted}{latex}
\draw[rope] (A) to[over pulley=P] (B);
\draw[rope,string route=under,red]
  (A) to[over pulley=P] node[right] {$T$} (B);
\end{minted}
Both endpoints must lie outside the pulley. Use a circular pulley, without
nonuniform scaling. The \key{to} segment computes both tangencies and the
contact arc; its labels belong to the final straight segment. Place labels
on another segment explicitly when that is what your diagram requires.
The compatibility command uses the same route:
\Needspace{3\baselineskip}
\begin{minted}{latex}
\physicsstringoverpulley[string route=under]{A}{P}{B}
\end{minted}
Both forms now respect scoped route settings. \key{shortest} selects the
shorter arc for the current tangent pair, not the globally shortest path
over every possible tangent combination. The safe path names are
\sty{physics string} and \key{physics over pulley}.

\subsection{Spring path}

\sty{spring} is a drawing style used directly between two coordinates. The
path endpoints determine its complete length and direction, so horizontal,
vertical, and inclined springs all use the same syntax. Zero-length leads are supported. Straight leads of
\key{pre length} and \key{post length} surround the coil; the remaining keys
map directly to TikZ's standard \key{coil} decoration parameters. Use
explicit units for typographic sizes such as \texttt{5pt}; bare convenience-key
values are interpreted as centimetres.

\begin{center}
\begin{tikzpicture}
  \coordinate (A) at (-2.5,0);
  \coordinate (B) at ( 2.5,0);
  \draw[spring, pre length=7mm, post length=4mm,
        amplitude=5pt, segment length=7pt]
    (A) -- node[above=4pt] {$k$} (B);
  \fill (A) circle[radius=1.2pt] (B) circle[radius=1.2pt];
  \node[below=4pt] at (A) {\key{A}};
  \node[below=4pt] at (B) {\key{B}};
\end{tikzpicture}
\end{center}

The spring has no node or private anchors: use the path endpoints and ordinary
TikZ nodes placed along the path. For a wall--spring--block system, draw
directly from a chosen wall coordinate to the block anchor:

\Needspace{18\baselineskip}
\begin{minted}{latex}
\documentclass[tikz,border=5mm]{standalone}
\usepackage{tikzphysics}
\begin{document}
\begin{tikzpicture}[>=stealth]
  \node[platform-left, minimum width=6cm, minimum height=2cm,
        anchor=floor-top-mid] (P) at (0,0) {};
  \node[block, minimum width=1cm, minimum height=0.8cm,
        anchor=south] (B) at (P.floor-top-25) {$m$};
  \coordinate (A) at ($(B.west)+(-4cm,0)$);
  \draw[spring,
        pre length=5pt, post length=5pt,
        amplitude=4.5pt, segment length=4.5pt]
    (A) -- node[above=3pt] {$k$} (B.west);
  \draw[->,thick] (B.east) -- ++(1.1,0) node[right] {$v$};
\end{tikzpicture}
\end{document}
\end{minted}

\subsection{Blocks, pulleys, and tangent strings}

\begin{center}
\begin{tikzpicture}[scale=0.78, every node/.append style={transform shape}]
  \node[wedge, wedge width=5.2, wedge angle=30] (W) at (0,0) {};
  \node[block, minimum width=0.8cm, minimum height=1cm,
        rotate=30, anchor=south] (B) at (W.slope-mid) {$m$};
  \node[pulley] (P) at (W.top) {};
  \node[block, minimum width=8mm, minimum height=1cm]
    (H) at ($(P.east)+(0,-2.1)$) {$M$};
  \physicsstringoverpulley{B.east}{P}{H.north}
\end{tikzpicture}
\end{center}

The pulley centre is exactly \key{W.top}. Its default diameter is
\texttt{1cm}; matching the surface block's height to that diameter places
\key{B.east} one radius above the slope, so the approaching tangent remains
exactly parallel to the incline.

\key{\textbackslash physicsstringoverpulley\{start\}\{pulley\}\{end\}}
draws a single physical string. Both straight portions meet the circular
pulley tangentially, and the intervening portion follows the pulley arc. The
default \key{surface-right} route matches the layout shown above: the pulley
is just beyond the incline's right end, the first string portion is parallel
to the slope, the contact arc passes over the upper rim, and the second
portion descends vertically on the right.

\subsection{String-routing variants}

The endpoint coordinates may be placed at any unequal positions outside the
pulley. The named routes below include two common left-to-right wraps and the
default surface-to-right-hanging turn. \key{shortest} keeps the selected
tangent pair and chooses the shorter contact arc. For other endpoint
orderings, select tangent solutions and wrap direction explicitly.

\begin{center}
\begin{tikzpicture}[font=\scriptsize]
  \begin{scope}
    \coordinate (RA) at (-1.5,-0.7);
    \coordinate (RB) at ( 1.5,-0.7);
    \node[pulley,minimum size=0.7cm] (RP) at (0,0) {};
    \physicsstringoverpulley[string route=over]{RA}{RP}{RB}
    \node at (0,-1.25) {\key{over}};
  \end{scope}
  \begin{scope}[xshift=4.1cm]
    \coordinate (RA) at (-1.5,0.7);
    \coordinate (RB) at ( 1.5,0.7);
    \node[pulley,minimum size=0.7cm] (RP) at (0,0) {};
    \physicsstringoverpulley[string route=under]{RA}{RP}{RB}
    \node at (0,-1.25) {\key{under}};
  \end{scope}
  \begin{scope}[xshift=8.2cm]
    \coordinate (RA) at (-1.5,-0.45);
    \coordinate (RB) at (0.35,-1.45);
    \node[pulley,minimum size=0.7cm] (RP) at (0,0) {};
    \physicsstringoverpulley{RA}{RP}{RB}
    \node at (0,-1.9) {\key{surface-right}};
  \end{scope}
  \begin{scope}[xshift=12.3cm]
    \coordinate (RA) at (-1.5,0.25);
    \coordinate (RB) at ( 1.25,-1.1);
    \node[pulley,minimum size=0.7cm] (RP) at (0,0) {};
    \physicsstringoverpulley[string route=shortest]{RA}{RP}{RB}
    \node at (0,-1.55) {unequal endpoints};
  \end{scope}
\end{tikzpicture}
\end{center}

\begin{tabularx}{\linewidth}{@{}>{\ttfamily\raggedright\arraybackslash}p{0.28\linewidth}
  >{\ttfamily\raggedright\arraybackslash}p{0.34\linewidth}D@{}}
\toprule
\normalfont Concise key & \normalfont Collision-safe alias & \normalfont Meaning and default \\
\midrule
block width & physics block width & Convenience alias for \key{minimum width}; default
  \texttt{1cm}. \\
block height & physics block height & Convenience alias for \key{minimum height}; default
  \texttt{1cm}. \\
pre length / post length & physics spring pre length / physics spring post length & Straight attachment leads; each defaults
  to \texttt{5pt}. \\
amplitude & physics spring amplitude & Coil half-height; default \texttt{4.5pt}. \\
segment length & physics spring segment length & Axial length of one repeated coil segment; default
  \texttt{4.5pt}. \\
aspect & physics spring aspect & Coil projection factor; default \texttt{0.5}. \\
pulley diameter & physics pulley diameter & Convenience alias for \key{minimum size}; default
  \texttt{1cm}. \\
pulley axle radius & physics pulley axle radius & Axle-dot radius; default \texttt{2pt}. Use
  \key{none} to hide the dot. \\
pulley axle color & physics pulley axle color & Axle-dot colour; default \texttt{black}. \\
string start solution & physics string start solution & Start-side tangent, \texttt{1} or \texttt{2};
  default \texttt{2}. \\
string end solution & physics string end solution & End-side tangent, \texttt{1} or \texttt{2};
  default \texttt{1}. \\
string route & physics string route & \texttt{surface-right} (default), \texttt{over},
  \texttt{under}, or \texttt{shortest}. \\
string wrap & physics string wrap & \texttt{clockwise} (default), \texttt{counterclockwise},
  or \texttt{shortest}. \\
\bottomrule
\end{tabularx}

\clearpage
\subsection{Complete pulley systems}

The mechanics shapes compose directly with every surface family. In each
diagram below, one call to \key{\textbackslash physicsstringoverpulley} draws both
straight tangent portions and the circular contact arc; no pulley compass
anchor is used as a substitute for the contact point. All four diagrams omit
a pulley sizing key and therefore use the documented default
\key{minimum size=1cm}. The inclined and bent systems place the pulley centre
directly at the endpoint anchors \key{W.top} and \key{S.wall-outer-100}.
Their \key{block height=1cm} makes \key{B.east} exactly one pulley radius from
the supporting surface, so the incoming tangent is surface-parallel.

\noindent
\begin{minipage}[t]{0.48\linewidth}
\centering
\begin{tikzpicture}
  \node[ground, ground width=5.6, ground depth=0.35] (G) at (0,0) {};
  \node[block, block width=0.9, block height=1,
        anchor=south] (B) at (G.top-30) {$m_1$};
  \coordinate (mount) at ($(G.top-right)+(0.5,0)$);
  \draw (G.top-right) -- (mount);
  \node[pulley] (P) at (mount) {};
  \node[block, minimum width=8mm, minimum height=1cm]
    (H) at ($(P.east)+(0,-2.1)$) {$m_2$};
  \physicsstringoverpulley{B.east}{P}{H.north}
\end{tikzpicture}

\smallskip\textbf{Horizontal plane}
\end{minipage}\hfill
\begin{minipage}[t]{0.48\linewidth}
\centering
\begin{tikzpicture}
  \node[wedge, wedge width=5, wedge angle=30] (W) at (0,0) {};
  \node[block, block width=0.9, block height=1,
        rotate=30, anchor=south] (B) at (W.slope-mid) {$m_1$};
  \node[pulley] (P) at (W.top) {};
  \node[block, minimum width=8mm, minimum height=1cm]
    (H) at ($(P.east)+(0,-2.2)$) {$m_2$};
  \physicsstringoverpulley{B.east}{P}{H.north}
\end{tikzpicture}

\smallskip\textbf{Inclined plane}
\end{minipage}

\vspace{1.2em}
\noindent
\begin{minipage}[t]{0.48\linewidth}
\centering
\begin{tikzpicture}
  \node[platform-right, platform width=4.6, platform depth=1.9,
        strip width=0.28, wall angle=42,
        anchor=floor-top-mid] (S) at (0,0) {};
  \node[block, block width=0.85, block height=1,
        rotate=42, anchor=south]
    (B) at (S.wall-outer-42) {$m_1$};
  \node[pulley] (P) at (S.wall-outer-100) {};
  \node[block, minimum width=8mm, minimum height=1cm]
    (H) at ($(P.east)+(0,-2.1)$) {$m_2$};
  \physicsstringoverpulley{B.east}{P}{H.north}
\end{tikzpicture}

\smallskip\textbf{Continuous bent platform}
\end{minipage}\hfill
\begin{minipage}[t]{0.48\linewidth}
\centering
\begin{tikzpicture}
  \node[ceiling, ceiling width=3.2, ceiling depth=0.3]
    (C) at (0,0) {};
  \draw (C.surface) -- ++(0,-0.5) coordinate (mount);
  \node[pulley] (P) at (mount) {};
  \node[block, minimum width=8mm, minimum height=1cm]
    (L) at ($(P.west)+(0,-2.1)$) {$m_1$};
  \node[block, minimum width=8mm, minimum height=1cm]
    (R) at ($(P.east)+(0,-2.7)$) {$m_2$};
  \physicsstringoverpulley[string route=over]{L.north}{P}{R.north}
\end{tikzpicture}

\smallskip\textbf{Two hanging masses}
\end{minipage}

\medskip
Copy-ready standalone sources are included in the \key{examples} directory:

\begin{itemize}
  \item \path{mechanics-pulley-flat-plane.tex} and
    \path{mechanics-block-pulley.tex};
  \item \path{mechanics-pulley-bent-platform.tex} and
    \path{mechanics-pulley-two-masses.tex};
  \item \path{mechanics-spring-block.tex}, a complete wall--spring--block system;
  \item \path{mechanics-pulley-string-variants.tex}, a gallery of six endpoint
    and wrapping arrangements.
\end{itemize}

\clearpage
% -----------------------------------------------------------------------------

\subsection{Bodies, forces and named assemblies}\label{sec:primitives}
\begin{tabularx}{\linewidth}{@{}p{.30\linewidth}D@{}}
\toprule
Feature & Use and defaults \\
\midrule
\sty{particle} & Filled circular node, diameter 3\,mm. \\
\sty{disk}, \sty{ring} & Circular nodes, diameter 15\,mm. Disk has a white fill;
ring is unfilled with a thicker outline. \\
\sty{force}, \sty{velocity}, \sty{acceleration} & Arrow path styles; you choose
origin, direction, length, and labels. \\
\sty{torque} & Arrow style for an arc you specify. \\
\sty{rod} & Straight or curved path with a 2\,pt stroke and round caps. \\
\sty{pin-support}, \sty{roller-support} & Named pics, controlled by
\key{support size} (6\,mm). The pic origin is the pivot. \\
\sty{pendulum} & Named pic with a particle bob. Length defaults to 2\,cm,
angle to 30 degrees from downward vertical, positive towards the right. \\
\bottomrule
\end{tabularx}
Circular bodies have ordinary compass and angular anchors. Use
\key{D.center} for an axle and \key{D.south} for bottom contact in an
unrotated disk. These are two-dimensional diagram symbols, not automatic
mass-distribution or rigid-body solvers.

\Needspace{8\baselineskip}
\begin{minted}{latex}
\pic (A) {pin-support};
\pic (B) at (4,0) {roller-support};
\draw[rod] (A-pivot) -- (B-pivot);
\draw[force] (2,1) -- (2,0) node[pos=0,left] {$F$};
\pic[pendulum length=2cm,pendulum angle=25] (P) at (6,1) {pendulum};
\draw[force] (P-bob.south) -- ++(0,-1) node[below] {$mg$};
\end{minted}
Support coordinates are \key{A-pivot}, \key{A-base}, \key{A-left}, and
\key{A-right}; \key{base} is the ground line's midpoint, while left/right
are the triangle's bottom corners. A pendulum exposes \key{P-pivot} and a
real bob node \key{P-bob}. Its specified length is pivot to bob centre;
the rope stops at the bob's border. Rotate or shift a pic using normal TikZ
options. Pic coordinates use a hyphen after the pic name, unlike a node's
\key{B.west} anchor syntax.

\key{every support} and \key{every pendulum} are applied when the pic type
is expanded. As with TikZ pics generally, type styles are processed after
options preceding the type; avoid conflicting geometric values in these
hooks and the pic options. Use the hooks for shared appearance or set
\key{support size} and \key{pendulum length} in the surrounding scope.
The collision-safe pic types are \sty{physics pin-support},
\sty{physics roller-support}, and \sty{physics pendulum}.
See \texttt{examples/mechanics-primitives.tex} for a complete gallery.
\begin{center}
\resizebox{\linewidth}{!}{%
\begin{tikzpicture}[font=\small]
  % A simply supported beam with an applied load.
  \pic (A) at (0,0) {pin-support};
  \pic (B) at (4,0) {roller-support};
  \draw[rod] (A-pivot) -- (B-pivot);
  \draw[force] (2,1) -- (2,0) node[pos=0,left] {$F$};
  \node[below] at (2,-1) {Supports and a rod};
  % A rolling body with independently styled vectors.
  \node[ground,minimum width=3cm] (G) at (7,-.75) {};
  \node[disk,anchor=south] (D) at (G.surface) {$M$};
  \draw[velocity] (D.north) -- ++(1,0) node[right] {$v$};
  \draw[torque] ($(D.center)+(130:1cm)$)
    arc[start angle=130,end angle=30,radius=1cm]
    node[right] {$\tau$};
  \node[below] at (7,-1.2) {Disk, velocity and torque};
  % Pic names prefix their coordinates; bob is a real node.
  \pic[pendulum length=2cm,pendulum angle=25] (P) at (11,1) {pendulum};
  \draw[dashed] (P-pivot) -- ++(0,-2.2);
  \draw[force] (P-bob.south) -- ++(0,-.8) node[below] {$mg$};
  \node[above] at (P-pivot) {Pendulum};
\end{tikzpicture}
}
\end{center}

\section{Optical components}

The \module{optics} library provides six node styles. They remain ordinary
TikZ nodes, so rotation, scaling, styling, naming, and anchor-based composition
work in the usual way.

\begin{center}
\begin{tikzpicture}[font=\footnotesize,scale=0.72,every node/.append style={transform shape}]
  \begin{scope}[xshift=0cm]
    \draw[->,physicsgray] (-1.7,0) -- (1.7,0);
    \node[concave-mirror, mirror radius=4, mirror thickness=0.22,
          mirror aperture angle=24] (OM1) at (0,0) {};
    \node[below=5pt] at (OM1.south) {\sty{concave-mirror}};
  \end{scope}
  \begin{scope}[xshift=5.4cm]
    \draw[->,physicsgray] (-1.7,0) -- (1.7,0);
    \node[convex-mirror, mirror radius=4, mirror thickness=0.22,
          mirror aperture angle=24] (OM2) at (0,0) {};
    \node[below=5pt] at (OM2.south) {\sty{convex-mirror}};
  \end{scope}
  \begin{scope}[xshift=10.8cm]
    \draw[->,physicsgray] (-1.7,0) -- (1.7,0);
    \node[convex-lens, convex lens radius=4, convex lens thickness=0.18,
          convex lens aperture angle=22] (OC) at (0,0) {};
    \node[below=5pt] at (OC.south) {\sty{convex-lens}};
  \end{scope}
  \begin{scope}[xshift=0cm,yshift=-5cm]
    \draw[->,physicsgray] (-1.7,0) -- (1.7,0);
    \node[concave-lens, concave lens radius=4, concave lens thickness=0.18,
          concave lens aperture angle=22] (OD) at (0,0) {};
    \node[below=5pt] at (OD.south) {\sty{concave-lens}};
  \end{scope}
  \begin{scope}[xshift=5.4cm,yshift=-5cm]
    \draw[->,physicsgray] (-1.7,0) -- (1.7,0);
    \node[slab, minimum width=1cm, minimum height=2.8cm] (OS) at (0,0) {};
    \node[below=5pt] at (OS.south) {\sty{slab}};
  \end{scope}
  \begin{scope}[xshift=10.8cm,yshift=-5cm]
    \draw[->,physicsgray] (-1.7,0) -- (1.7,0);
    \node[prism, prism width=2.8, prism apex angle=60] (OP) at (0,0) {};
    \node[below=5pt] at (OP.south) {\sty{prism}};
  \end{scope}
\end{tikzpicture}
\end{center}

\begin{tabularx}{\linewidth}{@{}KKD@{}}
\toprule
Short style & Collision-safe style & Geometry \\
\midrule
concave-mirror & physicsconcavemirror & Concave reflecting surface \\
convex-mirror & physicsconvexmirror & Convex reflecting surface \\
convex-lens & physicsconvexlens & Symmetric biconvex element \\
concave-lens & physicsconcavelens & Symmetric biconcave element \\
slab & physicsslab & Parallel rectangular faces \\
prism & physicsprism & Isosceles triangular cross-section \\
\bottomrule
\end{tabularx}

\subsection{Concave and convex mirrors}

\sty{concave-mirror} and \sty{convex-mirror} are reflected variants of one
spherical-mirror cross-section. The hatched side represents the backing; the
solid arc is the reflecting surface.

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Key & Meaning and default \\
\midrule
mirror radius & Radius of the reflecting surface; default \texttt{5cm}. \\
mirror thickness & On-axis backing thickness; default \texttt{0.25cm}. \\
mirror aperture angle & Reflecting-surface half-angle; default 30 degrees. \\
\bottomrule
\end{tabularx}

The aperture angle must be strictly between 0 and 90 degrees. Named anchors
include \key{surface-mid}, \key{surface-top}, \key{surface-bottom},
\key{back-mid}, \key{back-top}, \key{back-bottom}, \key{vertex},
\key{top}, and \key{bottom}. The families \key{surface-0..100} and
\key{back-0..100} run from bottom to top.

Collision-safe aliases add the \key{physics} prefix:
\begin{itemize}
  \item \key{physics mirror radius};
  \item \key{physics mirror thickness};
  \item \key{physics mirror aperture angle}.
\end{itemize}

\Needspace{14\baselineskip}
\begin{minted}{latex}
\documentclass[tikz, border=6mm]{standalone}
\usepackage{tikzphysics}
\begin{document}
\begin{tikzpicture}
  \node[concave-mirror, mirror radius=5cm,
        mirror aperture angle=28] (M1) at (0,0) {};
  \node[convex-mirror, mirror radius=5cm,
        mirror aperture angle=28] (M2) at (5,0) {};
  \draw[->] (-2,0.7) -- (M1.surface-70);
  \draw[->] (3,0.7) -- (M2.surface-70);
\end{tikzpicture}
\end{document}
\end{minted}

\subsection{Convex and concave lenses}

\sty{convex-lens} draws a symmetric biconvex element, while
\sty{concave-lens} draws a symmetric biconcave element.

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Key & Meaning and default \\
\midrule
convex lens radius & Radius of both optical surfaces; default \texttt{5cm}. \\
convex lens thickness & Material thickness at the top and bottom caps; default
  \texttt{0.2cm}. \\
convex lens aperture angle & Half-angle of both surfaces; default 25 degrees. \\
concave lens radius & Radius of both optical surfaces; default \texttt{5cm}. \\
concave lens thickness & Material thickness on the optical axis; default
  \texttt{0.2cm}. \\
concave lens aperture angle & Half-angle of both surfaces; default 25 degrees. \\
\bottomrule
\end{tabularx}

The aperture angle must be strictly between 0 and 90 degrees. Named anchors
include \key{front-mid}, \key{back-mid}, \key{front-top},
\key{front-bottom}, \key{back-top}, \key{back-bottom}, \key{top}, and
\key{bottom}. The arc families \key{front-0..100} and \key{back-0..100} run
from bottom to top. Collision-safe keys add the \key{physics} prefix, for
example \key{physics convex lens radius} and
\key{physics concave lens radius}.

\subsection{Slab}

\sty{slab} uses native \key{minimum width} and \key{minimum height}; the
unit-aware conveniences \key{slab width} and \key{slab height} set the same
requirements. Defaults are \texttt{1.2cm} by \texttt{3cm}. The shape is an
unfilled outline, so ray paths remain visible through it.

Named anchors are \key{front}, \key{back}, \key{front-top},
\key{front-bottom}, \key{back-top}, \key{back-bottom}, \key{top}, and
\key{bottom}. Numeric families \key{front-0..100} and \key{back-0..100} run
bottom to top; \key{top-0..100} and \key{bottom-0..100} cover the caps.

\subsection{Prism}

\sty{prism} is an isosceles triangle. Use native \key{minimum width} and
\key{minimum height}, or the unit-aware \key{prism width} and
\key{prism height}. Defaults are \texttt{3cm} by \texttt{2.6cm}. If
\key{prism apex angle} is supplied, it is authoritative and the height is
derived from the width; the angle must be strictly between 0 and 180 degrees.
The prism is also an unfilled outline.

Named anchors are \key{apex}, \key{base-left}, \key{base-right},
\key{base-mid}, \key{left-mid}, \key{right-mid}, \key{entry-mid},
\key{exit-mid}, and \key{centroid}. Numeric families are
\key{base-0..100}, \key{left-0..100}, and \key{right-0..100}.

\subsection{Short numeric anchors}

Each optical shape also exposes its primary ray-entry surface directly as
\key{.0} through \key{.100}. Thus \key{(L.50)} is the midpoint and
\key{(L.80)} is a point near the top of the primary surface.

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Shape & Meaning of \key{(name.T)} for $T=0\ldots100$ \\
\midrule
concave-mirror / convex-mirror & Same as \key{surface-T} \\
convex-lens / concave-lens & Same as \key{front-T} \\
slab & Same as \key{front-T} \\
prism & Same as \key{left-T} \\
\bottomrule
\end{tabularx}

Explicit family names can mark corresponding points, for example
\key{(L.80) -- (L.back-80)}; that segment is not generally a physical ray.

\subsection{Complete copy-paste ray diagram}

For the fixed ratio $n_{\mathrm{lens}}/n_{\mathrm{air}}=1.50$, the following
Snell-law construction bends each non-axial ray at both interfaces. The axial
ray stays straight because it meets both vertices normally.

\Needspace{20\baselineskip}
\begin{minted}{latex}
\documentclass[tikz, border=6mm]{standalone}
\usepackage{tikzphysics}

\begin{document}
\begin{tikzpicture}[ray/.style={red!75!black, very thick, ->}]
  \node[convex-lens, convex lens radius=3cm,
        convex lens thickness=0.2cm,
        convex lens aperture angle=25] (L) at (0,0) {};
  \coordinate (Xlow) at ($(L.center)+(0.29194,-0.72588)$);
  \coordinate (Xhigh) at ($(L.center)+(0.29194,0.72588)$);
  \coordinate (F) at (2.93841,0);
  \draw[densely dashed, gray] (-3.5,0) -- (3.5,0);
  \fill (F) circle (1.2pt) node[below] {$F$};
  \draw[ray] ($(L.20)+(-3,0)$) -- (L.20) -- (Xlow) -- (F);
  \draw[ray] ($(L.50)+(-3,0)$) -- (L.50) -- (L.back-50) -- (F);
  \draw[ray] ($(L.80)+(-3,0)$) -- (L.80) -- (Xhigh) -- (F);
\end{tikzpicture}
\end{document}
\end{minted}

\begin{center}
\begin{tikzpicture}[scale=0.72,every node/.append style={transform shape},
  ray/.style={red!75!black, very thick, ->},
  extension/.style={red!55!black, densely dashed}]
  \begin{scope}
    \node[convex-lens, convex lens radius=3cm, convex lens thickness=0.2cm,
          convex lens aperture angle=25] (RL) at (0,0) {};
    \coordinate (RLlow) at ($(RL.center)+(0.29194,-0.72588)$);
    \coordinate (RLhigh) at ($(RL.center)+(0.29194,0.72588)$);
    \coordinate (RF) at (2.93841,0);
    \draw[densely dashed,physicsgray] (-3.5,0) -- (3.5,0);
    \fill (RF) circle (1.2pt) node[below] {$F$};
    \draw[ray] ($(RL.20)+(-3,0)$) -- (RL.20) -- (RLlow) -- (RF);
    \draw[ray] ($(RL.50)+(-3,0)$) -- (RL.50) -- (RL.back-50) -- (RF);
    \draw[ray] ($(RL.80)+(-3,0)$) -- (RL.80) -- (RLhigh) -- (RF);
    \node[font=\small\bfseries] at (0,1.65) {Converging, $n=1.50$};
  \end{scope}
  \begin{scope}[xshift=8.5cm]
    \node[concave-lens, concave lens radius=3cm, concave lens thickness=0.2cm,
          concave lens aperture angle=25] (RD) at (0,0) {};
    \coordinate (RDlow) at ($(RD.center)+(0.21232,-0.81319)$);
    \coordinate (RDhigh) at ($(RD.center)+(0.21232,0.81319)$);
    \coordinate (RDF) at (-2.54285,0);
    \draw[densely dashed,physicsgray] (-3.5,0) -- (3.5,0);
    \fill (RDF) circle (1.2pt) node[below] {$F$};
    \draw[extension] (RDF) -- (RDlow);
    \draw[extension] (RDF) -- (RDhigh);
    \draw[ray] ($(RD.20)+(-3,0)$) -- (RD.20) -- (RDlow)
      -- ($(RDF)!2.25!(RDlow)$);
    \draw[ray] ($(RD.50)+(-3,0)$) -- (RD.50) -- (RD.back-50) -- (3.4,0);
    \draw[ray] ($(RD.80)+(-3,0)$) -- (RD.80) -- (RDhigh)
      -- ($(RDF)!2.25!(RDhigh)$);
    \node[font=\small\bfseries] at (0,1.65) {Diverging, $n=1.50$};
  \end{scope}
\end{tikzpicture}
\end{center}

\physicsnote{The package supplies geometry and anchors, not automatic ray
tracing. These coordinates are valid only for the stated lens and index;
recalculate them after changing either. The complete four-panel source is
\path{examples/optics-complete-ray-diagrams.tex}.}

\clearpage
% -----------------------------------------------------------------------------
\section{Shared tools}

\subsection{Percentage anchors: a beginner's guide}

A percentage anchor names a point partway along one particular edge, arc, or
contact surface. It removes the need to calculate coordinates manually. The
general spelling is

\begin{center}
  \key{(node-name.family-number)}
\end{center}

For example, \key{(W.slope-25)} means: use node \key{W}, choose its
\key{slope} edge, then travel 25 percent from that family's documented start
towards its end. The number is an integer from 0 to 100; write \key{25}, not
\key{25\%}. The three landmarks worth memorising are:

\begin{center}
\begin{tabular}{@{}cl@{}}
\key{family-0} & start of the family \\
\key{family-50} & halfway along the family \\
\key{family-100} & end of the family
\end{tabular}
\end{center}

The family direction matters. On a wedge, \key{slope-0} is the top vertex and
\key{slope-100} is the lower foot, so \key{slope-25} lies near the top rather
than near the foot.

\begin{center}
\begin{tikzpicture}[font=\footnotesize]
  \node[wedge, wedge width=6, wedge angle=30] (PW) at (0,0) {};
  \foreach \t in {0,25,50,75,100}{
    \fill[physicsblue] (PW.slope-\t) circle (1.6pt);
    \node[fill=white,inner sep=1pt]
      at ($(PW.slope-\t)+(0,0.34)$) {\key{\t}};
  }
  \draw[->,physicsblue,thick]
    ($(PW.slope-0)+(0,0.95)$) --
    node[above,sloped,fill=white,inner sep=1pt]{increasing $T$}
    ($(PW.slope-100)+(0,0.95)$);
\end{tikzpicture}
\end{center}

\subsubsection*{Using a percentage anchor}

The node must first have a name. Then use the anchor anywhere TikZ accepts a
coordinate:

\Needspace{17\baselineskip}
\begin{minted}{latex}
\begin{tikzpicture}
  \node[wedge, wedge width=6cm, wedge angle=30] (W) at (0,0) {};

  % Put the block midpoint on the middle of the slope.
  % anchor=south makes the block's bottom touch that point.
  \node[block, minimum width=1cm, minimum height=0.7cm,
        rotate=30, anchor=south]
    (B) at (W.slope-50) {$m$};

  % Mark a point 25 percent of the way from the top to the foot.
  \fill[red] (W.slope-25) circle (1.5pt);

  % Draw between two percentage anchors.
  \draw[blue, very thick] (W.base-20) -- (W.slope-80);
\end{tikzpicture}
\end{minted}

Changing the wedge width or angle moves all three points automatically. The
number describes progress along the selected family, not an $x$ coordinate,
$y$ coordinate, distance in centimetres, or angle around the node.

\subsubsection*{Which way does the percentage increase?}

Use 0 as the start and 100 as the arrowhead in the table below. Explicit family
names are recommended in teaching material because they state both the surface
and its direction.

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Family & Direction from 0 to 100 \\
\midrule
\key{floor-top-T} & right floor corner to left floor corner \\
\key{floor-bottom-T} & left floor corner to right floor corner \\
\key{wall-outer-T}, \key{wall-inner-T} & platform corner towards the far wall end \\
\key{base-T} on a wedge & \key{bl} to \key{br} \\
\key{right-T} on a wedge & \key{br} to \key{top} \\
\key{slope-T} on a wedge & \key{top} to \key{bl} \\
\key{surface-T} on a ramp & \key{surface-start} to \key{surface-end}, following the complete contact path \\
\key{curve-T} on a curved ramp & start to end of the circular portion only \\
\key{surface-T}, \key{front-T}, \key{back-T} in optics & bottom to top \\
\key{base-T} on a prism & \key{base-left} to \key{base-right} \\
\key{left-T} on a prism & \key{apex} to \key{base-left} \\
\key{right-T} on a prism & \key{base-right} to \key{apex} \\
\bottomrule
\end{tabularx}

For a multi-part ramp, the percentage follows distance along the complete
contact path. Consequently \key{surface-50} is halfway by path length; it need
not be the floor-to-incline joint or the visual centre of the node. On a
circular family the percentage follows the arc.

\subsubsection*{Short form \key{(name.T)}}

Ramps and optical shapes also provide a short form such as \key{(R.50)} or
\key{(L.80)}. It selects one documented primary surface:

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Shape & Meaning of \key{(name.T)} \\
\midrule
straight or curved ramp & \key{surface-T} \\
concave or convex mirror & \key{surface-T} \\
convex or concave lens & \key{front-T} \\
slab & \key{front-T} \\
prism & \key{left-T} \\
\bottomrule
\end{tabularx}

Thus \key{(L.80)} and \key{(L.front-80)} are the same point. Platforms and
wedges intentionally require the explicit family name, such as
\key{(P.floor-top-50)} or \key{(W.slope-50)}. This also avoids confusion with
ordinary TikZ numeric border anchors, where a number can mean an angle around a
node rather than a percentage.

The complete annotated source is
\path{examples/percentage-anchors-beginner.tex}; the more exhaustive edge
gallery is \path{examples/surface-numeric-anchors.tex}.

\clearpage
\subsection{Combining x and y coordinates}

TikZ's native projection operators solve a common mechanics-diagram problem:
take the horizontal position from one anchor and the vertical position from
another. They avoid measured offsets and continue working when either object
moves or changes size.

\begin{center}
\begin{tabular}{@{}cl@{}}
\key{(A |- B)} & x-coordinate from A, y-coordinate from B \\
\key{(A -| B)} & x-coordinate from B, y-coordinate from A
\end{tabular}
\end{center}

Suppose block \key{B} must connect horizontally to the vertical wall of ramp
\key{R}. Use the wall anchor only as the x source and \key{B.west} as the y
source:

\Needspace{9\baselineskip}
\begin{minted}{latex}
\node[ramp, minimum width=8.6cm, ramp run=2.6cm,
      ramp rise=1.5cm] (R) at (0,0) {};
\node[block, minimum width=1cm, minimum height=0.75cm,
      anchor=south] (B) at (R.floor-mid) {$m$};

\coordinate (A) at (R.wall-mid |- B.west);
\draw[spring] (A) -- (B.west);
\end{minted}

Both endpoints now have exactly the same y-coordinate, so the spring or line is
horizontal by construction. The same recipe works with an upward platform
wall:

\Needspace{6\baselineskip}
\begin{minted}{latex}
\node[platform-left-up, minimum width=6cm] (P) at (0,0) {};
\node[block, anchor=south] (B) at (P.floor-top-25) {$m$};
\coordinate (A) at (P.wall-outer-mid |- B.west);
\draw[spring] (A) -- (B.west);
\end{minted}

For a right upward wall, use \key{B.east} and a right-wall anchor instead. This
projection is exact for vertical walls. For an angled wall it keeps the chosen
anchor's x-coordinate; finding the geometric intersection with an arbitrary
sloping wall instead requires TikZ's \key{intersections} library.

See \path{examples/coordinate-projection.tex} for both complete diagrams.


\subsection{Explore keys and anchors inside TikZ}\label{sec:debug}
Add \key{show anchors} or \key{show keys} to a named object. Both keys
accept \key{true}/\key{false}; a bare key means true. The original
\key{physics debug/anchors}, \key{physics debug/keys}, and
\key{physics debug/all} forms remain supported.
\Needspace{5\baselineskip}
\begin{minted}{latex}
\begin{tikzpicture}
  \node[wedge,show anchors,show keys] (W) {};
\end{tikzpicture}
\end{minted}
\key{show keys} is a complete feature reference, labelled as
\emph{defaults}, not a dump of live node values. It lists geometry keys,
size aliases, all named anchors, percentage families, and common TikZ
styling options. Arbitrary user-defined TikZ keys cannot be enumerated by
the package. The full PGF/TikZ manual remains the reference for generic keys.

Use \key{\textbackslash physicshelp\{index\}} to list every feature.
Display a reference without constructing a shape:
\Needspace{5\baselineskip}
\begin{minted}{latex}
\begin{tikzpicture}
  \physicshelp{spring}
\end{tikzpicture}
\end{minted}
\key{\textbackslash physicshelp[<node options>]\{<feature>\}} accepts every
public feature name, including paths and pics. You can place a card with
\key{xshift}, \key{yshift}, \key{anchor}, or normal \key{at} node options.
Use \key{\textbackslash tikzphysicshelp} for the collision-safe command name.
The reference cards also work when loading only one feature module.
A card can describe another module's feature, but you must load that module
before drawing it.

\subsubsection*{Choose points without covering the diagram}
\Needspace{6\baselineskip}
\begin{minted}{latex}
\node[wedge,show anchors,
  physics debug/anchor list={bl,br,top},
  physics debug/anchor families={surface},
  physics debug/anchor samples={0,25,50,75,100}] (W) {};
\end{minted}
\key{anchor list=auto} is the default and enumerates all named anchors.
An explicit comma-separated list replaces that selection. Families add the
chosen samples; for example \key{surface} plus \key{50} adds
\key{surface-50}. You may leave the named list empty to inspect only families.
To inspect all points of one family, use
\key{anchor samples=\{0,1,...,100\}}. You can select every family with
\key{anchor families=all}; most diagrams are clearer with a few samples. The reference
always lists the full family ranges. Family names and samples must exist
on that object; unknown anchors receive the normal PGF error.
Coincident points share one label with multiple reference numbers.
\begin{center}
\begin{tikzpicture}
  \node[wedge,wedge angle=30,show anchors,
    physics debug/anchor list={bl,br,top},
    physics debug/anchor families={surface},
    physics debug/anchor samples={0,50,100}] (W) {};
\end{tikzpicture}
\end{center}

\subsubsection*{Scope settings and move panels}
\Needspace{6\baselineskip}
\begin{minted}{latex}
\begin{tikzpicture}[show anchors]
  \node[block] (A) {};
  \node[block,show anchors=false] (B) at (4,0) {};
\end{tikzpicture}
\end{minted}
Options are captured for each named object, so local false overrides, fonts,
and colours remain associated with that object. Debug drawings do not
recursively acquire debug overlays. Use explicit unique node names.

\begin{tabularx}{\linewidth}{@{}p{.44\linewidth}D@{}}
\toprule
Key under \key{physics debug/} & Default and effect \\
\midrule
\key{anchors}, \key{keys}, \key{all} & false; bare form enables the overlay. \\
\key{anchor list} & auto; all named anchors, or a comma-separated selection. \\
\key{anchor families} & Empty; selected percentage families, or all. \\
\key{anchor samples} & 0,25,50,75,100. \\
\key{anchor dot color}, \key{anchor dot radius} & red, 1.2pt. \\
\key{anchor label color}, \key{anchor label font} & red!80!black, tiny typewriter. \\
\key{key label color}, \key{key label font} & gray, tiny typewriter. \\
\key{anchor legend xshift}, \key{anchor legend yshift} & 0pt, -2cm from the object's centre. \\
\key{key panel xshift}, \key{key panel yshift} & 0pt, 2cm from the object's centre. \\
\bottomrule
\end{tabularx}
Panels deliberately enlarge the picture's bounding box. For a complex
system, inspect one object at a time or move its reference card beside the
system. Disable overlays for the final diagram. The examples
\texttt{debug-explorer.tex} and \texttt{debug-scoped.tex} are complete documents.

\subsection{Troubleshooting and geometry limits}\label{sec:troubleshooting}
\begin{description}
  \item[My default size did not apply.] Put the style first and the size after
  it, or set \key{every block}. Built-in style values follow ordinary option order.
  \item[The block is on a vertical wedge edge.] Use \key{surface-T} for physical
  contact. The older \key{slope-T} name follows a fixed CCW edge and is not
  the incline in every wedge mode.
  \item[My block is not rotated with its surface.] Use the tangent-before/after
  path with \key{sloped}. Local scalar geometry values do not include an
  independent node transformation.
  \item[An automatic line ends outside the shape.] Irregular shapes still
  inherit rectangular automatic border behaviour. Use explicit contact anchors;
  true outline intersections for all irregular bodies are future work.
  \item[Scaling makes a normal or rope wrong.] Nonuniform scaling changes
  circles to ellipses and does not preserve perpendicularity. Keep physical
  constructions rigid or uniformly scaled. Use \key{transform shape} when
  scaling the entire node geometry with a scope.
  \item[Long text does not fit an irregular shape.] Package geometry dimensions
  define its body; do not assume native text-driven minimum-size growth.
  Place labels in separate nodes. Blocks and circular primitives use standard
  TikZ shapes and can grow to fit text.
  \item[What does a bare number mean?] Convenience lengths use centimetres;
  native sizing keys should receive explicit units. Angles are degrees.
  \item[Is a numeric anchor an angle?] On a pulley or disk, yes. On ramps and
  optical shapes, integer .0 through .100 are retained percentage shortcuts.
  Explicit family names avoid ambiguity.
  \item[Does the package solve the physics?] No. Forces, constraints, motion,
  optical exit points, and physically compatible placements are supplied by you.
\end{description}

% -----------------------------------------------------------------------------
\section{Installation and development}

The installed drawing package requires only LaTeX2e and PGF/TikZ; using it in
a document does not require shell escape or an external executable. The source
manual uses Fourier and \texttt{minted}, so building \texttt{tikzphysics.pdf}
also requires those packages and shell escape for syntax highlighting.

For manual installation, place \texttt{tikzphysics.sty} and every
\texttt{tikzlibrarytikzphysics*.code.tex} file in a directory searched by TeX.

The source distribution uses \texttt{l3build}:

\Needspace{5\baselineskip}
\begin{minted}{bash}
l3build check   # run coordinate and anchor regression tests
l3build doc     # build tikzphysics.pdf (shell escape is configured)
l3build ctan    # create the CTAN and TDS archives
\end{minted}

Standalone examples are stored in \texttt{examples/}. The command-line helper
\texttt{tikzphysics-help} prints a compact key and anchor reference.

% -----------------------------------------------------------------------------
\section{Complete feature reference}\label{sec:reference}
Each entry lists built-in defaults, anchors, and available percentage families.
Use explicit family names in new diagrams. The same declarations generate
\texttt{docs/reference.md} and the in-picture \texttt{\textbackslash physicshelp}
cards. Common TikZ keys are additional to the geometry keys shown here;
see the earlier sections for sizing and transformation behaviour.
% BEGIN GENERATED REFERENCE
\subsection{platform-left (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 5cm\\
\texttt{minimum height} & 2cm\\
\texttt{strip width} & 0.25cm\\
\texttt{wall angle} & -90 degrees\\
\bottomrule\end{tabularx}
\textbf{Size aliases:} platform width = minimum width; platform depth = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, corner, 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, text\par
\textbf{Families:} floor-bottom-0..100, floor-right-0..100, floor-top-0..100, floor-left-0..100, wall-outer-0..100, wall-inner-0..100, wall-near-0..100, wall-far-0..100\par

\subsection{platform-right (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 5cm\\
\texttt{minimum height} & 2cm\\
\texttt{strip width} & 0.25cm\\
\texttt{wall angle} & -90 degrees\\
\bottomrule\end{tabularx}
\textbf{Size aliases:} platform width = minimum width; platform depth = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, corner, 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, text\par
\textbf{Families:} floor-bottom-0..100, floor-right-0..100, floor-top-0..100, floor-left-0..100, wall-outer-0..100, wall-inner-0..100, wall-near-0..100, wall-far-0..100\par

\subsection{platform (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 5cm\\
\texttt{minimum height} & 2cm\\
\texttt{strip width} & 0.25cm\\
\texttt{wall angle} & -90 degrees\\
\texttt{left wall angle} & -90 degrees\\
\texttt{right wall angle} & -90 degrees\\
\bottomrule\end{tabularx}
\textbf{Size aliases:} platform width = minimum width; platform depth = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, left-corner, right-corner, 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-far-mid, left-wall-near-mid, right-wall-A, right-wall-B, right-wall-C, right-wall-D, right-wall-outer-mid, right-wall-inner-mid, right-wall-far-mid, right-wall-near-mid, text\par
\textbf{Families:} floor-bottom-0..100, floor-right-0..100, floor-top-0..100, floor-left-0..100, left-wall-outer-0..100, left-wall-inner-0..100, left-wall-near-0..100, left-wall-far-0..100, right-wall-outer-0..100, right-wall-inner-0..100, right-wall-near-0..100, right-wall-far-0..100\par

\subsection{wedge (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 4cm\\
\texttt{wedge height} & derived\\
\texttt{wedge angle} & 30 degrees\\
\texttt{wedge right angle at} & br\\
\texttt{surface guide length} & 0.5cm\\
\bottomrule\end{tabularx}
\textbf{Size aliases:} wedge width = minimum width.\par
\textbf{Anchors:} surface-start, surface-end, center, north, south, east, west, north east, north west, south east, south west, bl, br, top, base-mid, right-mid, slope-mid, slope-right-mid, centroid, mid, text\par
\textbf{Families:} base-0..100, right-0..100, slope-0..100, surface-0..100, tangent-before-0..100, tangent-after-0..100, normal-0..100, right-surface-0..100, right-tangent-before-0..100, right-tangent-after-0..100, right-normal-0..100\par
surface runs left to right on the usable incline; top mode uses the left face. right-surface selects the right face in top mode. Legacy slope/right/base families keep their CCW directions. Directions and normals are local to the node.\par

\subsection{ground (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 6cm\\
\texttt{minimum height} & 0.3cm\\
\bottomrule\end{tabularx}
\textbf{Size aliases:} ground width = minimum width; ground depth = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, top-left, top-right, top-mid, bottom-left, bottom-right, bottom-mid, left-mid, right-mid, surface, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100\par

\subsection{ceiling (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 2cm\\
\texttt{minimum height} & 0.3cm\\
\bottomrule\end{tabularx}
\textbf{Size aliases:} ceiling width = minimum width; ceiling depth = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, top-left, top-right, top-mid, bottom-left, bottom-right, bottom-mid, left-mid, right-mid, surface, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100\par

\subsection{wall-left (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 0.3cm\\
\texttt{minimum height} & 3cm\\
\bottomrule\end{tabularx}
\textbf{Size aliases:} wall thickness = minimum width; wall height = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, top-left, top-right, top-mid, bottom-left, bottom-right, bottom-mid, left-mid, right-mid, surface, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100\par

\subsection{wall-right (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 0.3cm\\
\texttt{minimum height} & 3cm\\
\bottomrule\end{tabularx}
\textbf{Size aliases:} wall thickness = minimum width; wall height = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, top-left, top-right, top-mid, bottom-left, bottom-right, bottom-mid, left-mid, right-mid, surface, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100\par

\subsection{ramp (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 8.6cm\\
\texttt{ramp run} & 2.6cm\\
\texttt{ramp rise} & derived\\
\texttt{ramp angle} & 30\\
\texttt{ramp depth} & 0.25cm\\
\texttt{ramp wall height} & 1.5cm\\
\texttt{ramp wall width} & 0.25cm\\
\texttt{ramp direction} & right\\
\texttt{ramp guide length} & 0.5cm\\
\bottomrule\end{tabularx}
\textbf{Anchors:} center, surface-start, surface-mid, surface-end, floor-start, floor-mid, floor-end, ramp-foot, ramp-mid, ramp-top, wall-top, wall-mid, wall-bottom, base-start, base-end, angle-baseline, angle-label, angle-first, angle-second, text\par
\textbf{Families:} surface-0..100, tangent-before-0..100, tangent-after-0..100, normal-0..100; legacy .0..100 shorthand also available\par
surface follows the whole contact path by distance. At the sharp joint the tangent uses the incline side.\par

\subsection{curved-ramp (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{curved ramp floor length} & 2.5cm\\
\texttt{curved ramp radius} & 4cm\\
\texttt{curved ramp angle} & 90\\
\texttt{curved ramp back extension} & 1cm\\
\texttt{ramp depth} & 0.25cm\\
\texttt{ramp direction} & right\\
\texttt{ramp guide length} & 0.5cm\\
\bottomrule\end{tabularx}
\textbf{Anchors:} center, surface-start, surface-mid, surface-end, curve-center, curve-start, curve-mid, curve-end, floor-start, floor-mid, floor-end, base-start, base-end, back-top, back-bottom, text\par
\textbf{Families:} surface-0..100, curve-0..100, tangent-before-0..100, tangent-after-0..100, normal-0..100, curve-tangent-before-0..100, curve-tangent-after-0..100, curve-normal-0..100; legacy .0..100 shorthand also available\par
surface follows floor plus arc by distance; curve follows the arc only.\par

\subsection{block (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 1cm\\
\texttt{minimum height} & 1cm\\
\bottomrule\end{tabularx}
\textbf{Size aliases:} block width = minimum width; block height = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base, base east, base west, mid, mid east, mid west, text\par
\textbf{Families:} Numeric anchors are angles in degrees, as in ordinary TikZ.\par

\subsection{pulley (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum size} & 1cm\\
\texttt{pulley axle radius} & 2pt\\
\texttt{pulley axle color} & black\\
\bottomrule\end{tabularx}
\textbf{Size aliases:} pulley diameter = minimum size.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base, base east, base west, mid, mid east, mid west, text\par
\textbf{Families:} Numeric anchors are angles in degrees, as in ordinary TikZ.\par
Use a circular pulley with external rope endpoints. Set pulley axle radius=none to hide the axle.\par

\subsection{particle (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum size} & 3mm\\
\bottomrule\end{tabularx}
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base, base east, base west, mid, mid east, mid west, text\par
\textbf{Families:} Numeric anchors are angles in degrees, as in ordinary TikZ.\par

\subsection{disk (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum size} & 15mm\\
\bottomrule\end{tabularx}
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base, base east, base west, mid, mid east, mid west, text\par
\textbf{Families:} Numeric anchors are angles in degrees, as in ordinary TikZ.\par

\subsection{ring (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum size} & 15mm\\
\bottomrule\end{tabularx}
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base, base east, base west, mid, mid east, mid west, text\par
\textbf{Families:} Numeric anchors are angles in degrees, as in ordinary TikZ.\par

\subsection{spring (path)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{pre length} & 5pt\\
\texttt{post length} & 5pt\\
\texttt{amplitude} & 4.5pt\\
\texttt{segment length} & 4.5pt\\
\texttt{aspect} & 0.5\\
\bottomrule\end{tabularx}
\textbf{Anchors:} No private anchors; use path endpoints and nodes along the path.\par
Use draw[spring] (A)--(B). No private anchors. Lead lengths may be zero; amplitude and segment length must be positive.\par

\subsection{rope (path)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{line width} & 0.5pt\\
\texttt{over pulley} & required node name\\
\texttt{string route} & surface-right\\
\texttt{string start solution} & 2\\
\texttt{string end solution} & 1\\
\texttt{string wrap} & clockwise\\
\bottomrule\end{tabularx}
\textbf{Anchors:} No private anchors; use path endpoints and nodes along the path.\par
Use draw[rope] (A) to[over pulley=P] (B). Endpoints must lie outside a circular pulley. Labels on to sit on the final straight segment. shortest changes wrap only, not the tangent pair.\par

\subsection{force (path)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{line width} & 0.7pt\\
\bottomrule\end{tabularx}
\textbf{Anchors:} No private anchors; use path endpoints and nodes along the path.\par

\subsection{velocity (path)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{line width} & 0.6pt\\
\bottomrule\end{tabularx}
\textbf{Anchors:} No private anchors; use path endpoints and nodes along the path.\par

\subsection{acceleration (path)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{line width} & 0.6pt\\
\bottomrule\end{tabularx}
\textbf{Anchors:} No private anchors; use path endpoints and nodes along the path.\par

\subsection{torque (path)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{line width} & 0.7pt\\
\bottomrule\end{tabularx}
\textbf{Anchors:} No private anchors; use path endpoints and nodes along the path.\par

\subsection{rod (path)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{line width} & 2pt\\
\bottomrule\end{tabularx}
\textbf{Anchors:} No private anchors; use path endpoints and nodes along the path.\par

\subsection{pin-support (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{support size} & 6mm\\
\bottomrule\end{tabularx}
\textbf{Anchors:} pivot, base, left, right\par
Use pic (S) {pin-support}; anchors are coordinates (S-pivot), (S-base), (S-left), (S-right).\par

\subsection{roller-support (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{support size} & 6mm\\
\bottomrule\end{tabularx}
\textbf{Anchors:} pivot, base, left, right\par
Use pic (S) {roller-support}; anchors are coordinates (S-pivot), (S-base), (S-left), (S-right).\par

\subsection{pendulum (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{pendulum length} & 2cm\\
\texttt{pendulum angle} & 30 degrees\\
\bottomrule\end{tabularx}
\textbf{Anchors:} pivot, bob (node)\par
Use pic (P) {pendulum}. Angle is measured from downward vertical; positive swings right. Length is pivot to bob centre. Use (P-pivot) and (P-bob.center).\par

\subsection{concave-mirror (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{mirror radius} & 5cm\\
\texttt{mirror thickness} & 0.25cm\\
\texttt{mirror aperture angle} & 30 degrees\\
\bottomrule\end{tabularx}
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, vertex, arc-mid, surface-mid, front-mid, back-mid, front-top, front-bottom, surface-top, surface-bottom, back-top, back-bottom, top, bottom, text\par
\textbf{Families:} surface-0..100, front-0..100, back-0..100; legacy .0..100 shorthand also available\par

\subsection{convex-mirror (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{mirror radius} & 5cm\\
\texttt{mirror thickness} & 0.25cm\\
\texttt{mirror aperture angle} & 30 degrees\\
\bottomrule\end{tabularx}
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, vertex, arc-mid, surface-mid, front-mid, back-mid, front-top, front-bottom, surface-top, surface-bottom, back-top, back-bottom, top, bottom, text\par
\textbf{Families:} surface-0..100, front-0..100, back-0..100; legacy .0..100 shorthand also available\par

\subsection{convex-lens (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{convex lens radius} & 5cm\\
\texttt{convex lens thickness} & 0.2cm\\
\texttt{convex lens aperture angle} & 25 degrees\\
\bottomrule\end{tabularx}
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, front-mid, back-mid, front-top, front-bottom, back-top, back-bottom, top, bottom, text\par
\textbf{Families:} front-0..100, back-0..100; legacy .0..100 shorthand also available\par

\subsection{concave-lens (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{concave lens radius} & 5cm\\
\texttt{concave lens thickness} & 0.2cm\\
\texttt{concave lens aperture angle} & 25 degrees\\
\bottomrule\end{tabularx}
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, front-mid, back-mid, front-top, front-bottom, back-top, back-bottom, top, bottom, text\par
\textbf{Families:} front-0..100, back-0..100; legacy .0..100 shorthand also available\par

\subsection{slab (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 1.2cm\\
\texttt{minimum height} & 3cm\\
\bottomrule\end{tabularx}
\textbf{Size aliases:} slab width = minimum width; slab height = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, front, back, front-top, front-bottom, back-top, back-bottom, top, bottom, text\par
\textbf{Families:} front-0..100, back-0..100, top-0..100, bottom-0..100; legacy .0..100 shorthand also available\par

\subsection{prism (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 3cm\\
\texttt{minimum height} & 2.6cm\\
\texttt{prism apex angle} & derived\\
\bottomrule\end{tabularx}
\textbf{Size aliases:} prism width = minimum width; prism height = minimum height.\par
\textbf{Anchors:} center, centroid, north, south, east, west, north east, north west, south east, south west, apex, base-left, base-right, base-mid, left-mid, right-mid, entry-mid, exit-mid, text\par
\textbf{Families:} base-0..100, right-0..100, left-0..100; legacy .0..100 shorthand also available\par

% END GENERATED REFERENCE

\section{License}

Copyright \textcopyright\ 2026 Vaibhav Blayer.

This work may be distributed and/or modified under the conditions of the
LaTeX Project Public License, either version 1.3c or (at your option) any later
version. This work has LPPL maintenance status ``maintained''. The Current
Maintainer is Vaibhav Blayer.

\end{document}
