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

\usepackage[T1]{fontenc}
\usepackage{fourier}
\usepackage[a4paper,margin=22mm,headheight=14pt]{geometry}
\usepackage{microtype}
\usepackage{parskip}
\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.1.0},
  pdfkeywords={LaTeX, TikZ, physics, diagrams, mechanics, optics},
}

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

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

\usemintedstyle{dracula}
\setminted{
  fontsize=\footnotesize,
  bgcolor=physicscodebg,
  breaklines=true,
  breakanywhere=true,
  autogobble=true,
  tabsize=2,
  frame=single,
  framesep=3mm,
  baselinestretch=1.05,
  formatcom=\color{white},
  linenos=false,
}

\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.1.0}}
\author{Vaibhav Blayer\\\href{mailto:vaibhavblayer@gmail.com}{vaibhavblayer@gmail.com}}
\date{2026-08-15}

\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 without
introducing a new drawing language. Every object remains an ordinary TikZ node
or path.
\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}

\subsection{Loading}

Load every module with the package wrapper:

\begin{minted}{latex}
\usepackage{tikzphysics}
\end{minted}

For smaller documents, load only the required TikZ libraries:

\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 style such as \sty{wedge}, \sty{block}, \sty{spring}, \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 the node a name and compose the diagram through its anchors.
\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 \\
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 / spring / pulley & physicsblock / physicsspring / physicspulley & Mechanics objects \\
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}

\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{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{physics 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 & physics block width / height & \sty{block} \\
minimum width & --- & \sty{spring} end-to-end length \\
minimum size & physics pulley diameter & \sty{pulley} \\
minimum width / height & physics platform width / depth & Bent platforms \\
minimum width / height & physics ground width / depth & \sty{ground} \\
minimum width / height & physics ceiling width / depth & \sty{ceiling} \\
minimum width / height & physics 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{physics wall angle}, \key{physics 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.

\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.

\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$};

  \coordinate (pulley-center)
    at ($(plane.top)+(30:0.5)+(120:0.2)$);
  \node[pulley, minimum size=0.6cm]
    (pulley) at (pulley-center) {};

  \node[block, minimum width=0.8cm, minimum height=0.8cm]
    (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$};
  \coordinate (pulley-center)
    at ($(plane.top)+(30:0.5)+(120:0.2)$);
  \node[pulley, minimum size=0.6cm]
    (pulley) at (pulley-center) {};
  \node[block, minimum width=0.8cm, minimum height=0.8cm]
    (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}.

\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}

% -----------------------------------------------------------------------------
\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-both & Two walls; set both with \key{physics wall angle}, or set them
  independently with \key{physics left wall angle} and
  \key{physics right wall angle}. \\
\bottomrule
\end{tabularx}

\subsubsection*{Variant gallery}

\begin{center}
\begin{tikzpicture}[font=\scriptsize]
  % Row 1: vertical variants
  \node[platform-left, physics platform width=2.2, physics platform depth=1,
        physics wall angle=-90, anchor=floor-top-mid] at (0,0) {};
  \node[align=center] at (0,-1.45) {down left\\\key{-90}};
  \node[platform-right, physics platform width=2.2, physics platform depth=1,
        physics wall angle=-90, anchor=floor-top-mid] at (3.8,0) {};
  \node[align=center] at (3.8,-1.45) {down right\\\key{-90}};
  \node[platform, physics platform width=2.2, physics platform depth=1,
        physics 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, physics platform width=2.2, physics platform depth=1,
        physics 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, physics platform width=2.2, physics platform depth=1,
        physics wall angle=135, anchor=floor-top-mid] at (0,-3) {};
  \node[align=center] at (0,-4.45) {outward left\\\key{135}};
  \node[platform-right, physics platform width=2.2, physics platform depth=1,
        physics 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, physics platform width=2.2, physics platform depth=1,
        physics left wall angle=135, physics 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, physics platform width=2.2, physics platform depth=1,
        physics left wall angle=45, physics 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, physics platform width=2.2, physics platform depth=1,
        physics wall angle=180, anchor=floor-top-mid] at (0,-6) {};
  \node[align=center] at (0,-7.45) {straight left\\\key{180}};
  \node[platform-right, physics platform width=2.2, physics platform depth=1,
        physics 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, physics platform width=2.2, physics platform depth=1,
        physics left wall angle=180, physics 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, physics platform width=2.2, physics platform depth=1,
        physics left wall angle=120, physics 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}{@{}KD@{}}
\toprule
Key & Meaning and default \\
\midrule
physics platform width & Overall floor width; default \texttt{5cm}. \\
physics platform depth & Wall length and nominal vertical extent; default
  \texttt{2cm}. \\
physics strip width & Thickness of the floor and walls; default \texttt{0.3cm}. \\
physics wall angle & Direction of every wall, measured counter-clockwise from the
  positive x-axis; default \texttt{-90}. \\
physics left wall angle & Left-wall override for \sty{platform-both}. \\
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, physics platform width=3.8, physics platform depth=0.8,
        anchor=floor-top-mid] at (0,0) {};
  \node[align=center] at (0,-1.85)
    {wide floor\\\key{physics platform width=3.8}};
  \node[platform-both, physics platform width=2.5, physics platform depth=1.5,
        anchor=floor-top-mid] at (5.2,0) {};
  \node[align=center] at (5.2,-1.85)
    {deep walls\\\key{physics platform depth=1.5}};
  \node[platform-both, physics platform width=2.8, physics platform depth=1,
        physics strip width=0.5, anchor=floor-top-mid] at (10.4,0) {};
  \node[align=center] at (10.4,-1.85)
    {thick material\\\key{physics strip width=0.5}};

  % Row 2: shared and independent directions
  \node[platform-both, physics platform width=2.6, physics platform depth=1.1,
        physics wall angle=70, anchor=floor-top-mid] at (0,-4) {};
  \node[align=center] at (0,-5.65)
    {shared direction\\\key{physics wall angle=70}};
  \node[platform-both, physics platform width=2.6, physics platform depth=1.1,
        physics left wall angle=135, physics right wall angle=-90,
        anchor=floor-top-mid] at (5.2,-4) {};
  \node[align=center] at (5.2,-5.65)
    {left override\\\key{physics left wall angle=135}};
  \node[platform-both, physics platform width=2.6, physics platform depth=1.1,
        physics left wall angle=-90, physics right wall angle=45,
        anchor=floor-top-mid] at (10.4,-4) {};
  \node[align=center] at (10.4,-5.65)
    {right override\\\key{physics 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, physics platform width=5, physics platform depth=2.2,
        physics 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.

\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}.

\subsection{Ground, ceiling, and walls}

\begin{center}
\begin{tikzpicture}[font=\footnotesize]
  \node[ground, physics ground width=3.3] (G) at (0,0) {};
  \node[below=3pt] at (G.bottom-mid) {\sty{ground}};
  \node[ceiling, physics ceiling width=3.3] (C) at (4.7,0) {};
  \node[above=3pt] at (C.top-mid) {\sty{ceiling}};
  \node[wall-left, physics wall height=1.7] (WL) at (8.2,0) {};
  \node[left=4pt] at (WL.left-mid) {\sty{wall-left}};
  \node[wall-right, physics 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{physics ground width}, \key{physics ground depth} \\
\sty{ceiling} & \key{physics ceiling width}, \key{physics ceiling depth} \\
\sty{wall-left}, \sty{wall-right} & \key{physics wall thickness},
  \key{physics 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$.

% -----------------------------------------------------------------------------
\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.

\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$};
  \node[spring, minimum width=2.25cm, anchor=start]
    (S) at ($(R.wall-bottom)+(0.25,0.375)$) {};
  \node[above=3pt] at (S.coil-mid) {$k$};
  \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{2cm}. \\
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:

\begin{minted}{latex}
\path (R.tangent-before-60) -- (R.tangent-after-60)
  node[midway,sloped,block,anchor=south] {$m$};
\draw[->] (R.surface-60) -- (R.normal-60) node[above] {$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, while the blue arrow uses the outward normal directly.

\begin{minted}{latex}
\documentclass[tikz,border=6mm]{standalone}
\usepackage{tikzphysics}
\begin{document}
\begin{tikzpicture}[>=stealth]
  \node[curved-ramp, curved ramp floor length=2.5cm,
        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] {$m$};
  \draw[->,blue,thick] (R.curve-60) -- (R.curve-normal-60)
    node[above] {$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] {$m$};
  \draw[physicsblue,->,thick] (R.curve-60) -- (R.curve-normal-60) node[above] {$N$};
  \draw[physicsgray,dashed] (R.curve-center) -- (R.curve-60);
  \fill[physicsteal] (R.floor-mid) circle (1.2pt) node[below=8pt] {\key{floor-mid}};
  \fill[physicsteal] (R.curve-20) circle (1.2pt) node[above=4pt] {\key{curve-20}};
  \fill[physicsteal] (R.curve-80) circle (1.2pt) node[above right] {\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:

\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.

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

The \module{mechanics} library supplies blocks, springs, pulleys, and
tangent pulley strings. All are ordinary TikZ objects and accept native
styling such as \key{draw}, \key{line width}, \key{rotate}, and \key{scale}.

\subsection{Spring node}

\sty{spring} is a named node, not a loose decorated path. Its
\key{minimum width} is the complete end-to-end length. 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};
as elsewhere in this package, bare package-key values are centimetres.

\begin{center}
\begin{tikzpicture}
  \node[spring, minimum width=5cm,
        pre length=7mm, post length=4mm,
        amplitude=5pt, segment length=7pt] (S) {};
  \fill (S.start) circle[radius=1.2pt]
        (S.end) circle[radius=1.2pt];
  \node[above=4pt] at (S.coil-mid) {$k$};
  \node[below=4pt] at (S.start) {\key{start}};
  \node[below=4pt] at (S.end) {\key{end}};
\end{tikzpicture}
\end{center}

The principal anchors are \key{start}, \key{end}, \key{coil-start},
\key{coil-mid}, and \key{coil-end}, plus the usual compass anchors. For a
wall--spring--block system, anchor the spring's end directly at the block:

\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$};
  \node[spring, minimum width=4cm,
        pre length=5pt, post length=5pt,
        amplitude=4.5pt, segment length=4.5pt,
        anchor=end] (S) at (B.west) {};
  \node[above=3pt] at (S.coil-mid) {$k$};
  \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=0.8cm,
        rotate=30, anchor=south] (B) at (W.slope-mid) {$m$};
  \coordinate (pulley-center) at ($(W.top)+(30:0.5)+(120:0.125)$);
  \node[pulley, minimum size=0.55cm] (P) at (pulley-center) {};
  \node[block, minimum width=0.7cm, minimum height=0.7cm]
    (H) at ($(P.east)+(0,-2.1)$) {$M$};
  \physicsstringoverpulley{B.east}{P}{H.north}
\end{tikzpicture}
\end{center}

\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[physics 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[physics 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[physics string route=shortest]{RA}{RP}{RB}
    \node at (0,-1.55) {unequal endpoints};
  \end{scope}
\end{tikzpicture}
\end{center}

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Key & Meaning and default \\
\midrule
physics block width & Convenience alias for \key{minimum width}; default
  \texttt{1cm}. \\
physics block height & Convenience alias for \key{minimum height}; default
  \texttt{1cm}. \\
minimum width & Native TikZ key for the spring's total length; default
  \texttt{3cm}. \\
pre length / post length & Straight attachment leads; each defaults
  to \texttt{5pt}. \\
amplitude & Coil half-height; default \texttt{4.5pt}. \\
segment length & Axial length of one repeated coil segment; default
  \texttt{4.5pt}. \\
aspect & Coil projection factor; default \texttt{0.5}. \\
physics pulley diameter & Convenience alias for \key{minimum size}; default
  \texttt{1cm}. \\
physics pulley axle radius & Axle-dot radius; default \texttt{2pt}. Use
  \key{none} to hide the dot. \\
physics pulley axle color & Axle-dot colour; default \texttt{black}. \\
physics string start solution & Start-side tangent, \texttt{1} or \texttt{2};
  default \texttt{2}. \\
physics string end solution & End-side tangent, \texttt{1} or \texttt{2};
  default \texttt{1}. \\
physics string route & \texttt{surface-right} (default), \texttt{over},
  \texttt{under}, or \texttt{shortest}. \\
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.

\noindent
\begin{minipage}[t]{0.48\linewidth}
\centering
\begin{tikzpicture}[scale=0.72,every node/.append style={transform shape}]
  \node[ground, physics ground width=5.6, physics ground depth=0.35] (G) at (0,0) {};
  \node[block, physics block width=0.9, physics block height=0.8,
        anchor=south] (B) at (G.top-30) {$m_1$};
  \coordinate (mount) at ($(G.top-right)+(0.4,0.05)$);
  \draw (G.top-right) -- (mount);
  \node[pulley, physics pulley diameter=0.7] (P) at (mount) {};
  \node[block, physics block width=0.75, physics block height=0.75]
    (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}[scale=0.72,every node/.append style={transform shape}]
  \node[wedge, wedge width=5, wedge angle=30] (W) at (0,0) {};
  \node[block, physics block width=0.9, physics block height=0.8,
        rotate=30, anchor=south] (B) at (W.slope-mid) {$m_1$};
  \coordinate (mount) at ($(W.top)+(30:0.5)+(120:0.075)$);
  \node[pulley, physics pulley diameter=0.65] (P) at (mount) {};
  \node[block, physics block width=0.75, physics block height=0.75]
    (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}[scale=0.72,every node/.append style={transform shape}]
  \node[platform-right, physics platform width=4.6, physics platform depth=1.9,
        physics strip width=0.28, physics wall angle=42,
        anchor=floor-top-mid] (S) at (0,0) {};
  \node[block, physics block width=0.85, physics block height=0.75,
        rotate=42, anchor=south]
    (B) at (S.wall-outer-42) {$m_1$};
  \coordinate (mount) at ($(S.wall-outer-100)+(42:0.5)+(132:0.025)$);
  \draw (S.wall-outer-100) -- (mount);
  \node[pulley, physics pulley diameter=0.7] (P) at (mount) {};
  \node[block, physics block width=0.75, physics block height=0.75]
    (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}[scale=0.72,every node/.append style={transform shape}]
  \node[ceiling, physics ceiling width=3.2, physics ceiling depth=0.3]
    (C) at (0,0) {};
  \draw (C.surface) -- ++(0,-0.5) coordinate (mount);
  \node[pulley, physics pulley diameter=0.85] (P) at (mount) {};
  \node[block, physics block width=0.75, physics block height=0.75]
    (L) at ($(P.west)+(0,-2.1)$) {$m_1$};
  \node[block, physics block width=0.75, physics block height=0.75]
    (R) at ($(P.east)+(0,-2.7)$) {$m_2$};
  \physicsstringoverpulley[physics 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
% -----------------------------------------------------------------------------
\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}

\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.

\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}.}

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

\subsection{Parametric anchors}

Integer parametric anchors make it easy to place an object at a repeatable
fraction of an edge without coordinate arithmetic:

\begin{minted}{latex}
\node[block, anchor=south] at (W.slope-50) {$m$};
\draw[->] (L.front-25) -- ++(-1,0);
\end{minted}

For a family \key{name-0..100}, 0 is the documented start of the edge or arc,
50 is its midpoint, and 100 is its endpoint.

\subsection{Debug overlays}

The core library can label registered anchors and display the keys accepted by
a shape:

\begin{minted}{latex}
\begin{tikzpicture}
  \node[block, minimum width=1.2cm, minimum height=0.8cm,
        physics debug/keys=true] (K) at (0,0) {$m$};
  \node[block, minimum width=1.2cm, minimum height=0.8cm,
        physics debug/all=true] (A) at (6,0) {$m$};
\end{tikzpicture}
\end{minted}

\begin{center}
\begin{tikzpicture}[font=\scriptsize]
  \node[block, minimum width=1.2cm, minimum height=0.8cm,
        physics debug/keys=true] (K) at (0,0) {$m$};
  \node[block, minimum width=1.2cm, minimum height=0.8cm,
        physics debug/all=true] (A) at (6,0) {$m$};
  \node[anchor=north] at ($(K.south)+(0,-1.35)$) {keys only};
  \node[anchor=north] at ($(A.south)+(0,-1.35)$) {keys and anchors};
\end{tikzpicture}
\end{center}

Use \key{physics debug/anchors=true}, \key{physics debug/keys=true}, or
\key{physics debug/all=true}. These options are intended for diagram development;
remove them from final artwork. Key panels prefer the native TikZ names
\key{minimum width}, \key{minimum height}, and \key{minimum size} for ordinary
sizing. They show a \key{physics ...} key only when it controls package-specific
geometry or behaviour. The convenience sizing aliases remain accepted even
when the panel presents their native equivalent. A key panel is an API reference:
it shows documented defaults, not the values supplied to that particular node.
Place a debug option on a node for a local overlay, on a \texttt{scope} for one
part of a diagram, or on a \texttt{tikzpicture} to inspect every node.

% -----------------------------------------------------------------------------
\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}:

\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{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}
