%% tikzlibrarytikzphysics.optics.code.tex
%% -----------------------------------------------------------
%% Optics module for tikzphysics.
%%
%% Optical components:
%%   - physicsmirror     : curved mirror geometry used by concave/convex styles
%%   - physicsconvexlens : symmetric biconvex lens
%%   - physicsconcavelens: symmetric biconcave lens
%%   - physicsslab       : rectangular glass slab
%%   - physicsprism      : isosceles triangular prism
%%
%% Internal namespace : \tikzphysics@optics@...
%% Requires           : tikz, patterns, calc, tikzphysics.core
%%
%% Author  : Vaibhav Blayer
%% Version : v1.2.0 (2026-09-05)
%% License : LPPL 1.3c
%% -----------------------------------------------------------

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

\makeatletter

\tikzphysics@declarehook{concave-mirror}
\tikzphysics@declarehook{convex-mirror}
\tikzphysics@declarehook{convex-lens}
\tikzphysics@declarehook{concave-lens}
\tikzphysics@declarehook{slab}
\tikzphysics@declarehook{prism}

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

\newdimen\tikzphysics@optics@R
\newdimen\tikzphysics@optics@T
\newdimen\tikzphysics@optics@Rout
\newdimen\tikzphysics@optics@y
\newdimen\tikzphysics@optics@frontxraw
\newdimen\tikzphysics@optics@backxraw
\newdimen\tikzphysics@optics@bcxraw
\newdimen\tikzphysics@optics@backmidraw
\newdimen\tikzphysics@optics@shift
\newdimen\tikzphysics@optics@fcx
\newdimen\tikzphysics@optics@frontx
\newdimen\tikzphysics@optics@backx
\newdimen\tikzphysics@optics@bcx
\newdimen\tikzphysics@optics@frontmid
\newdimen\tikzphysics@optics@backmid
\newdimen\tikzphysics@optics@capmid

\newdimen\tikzphysics@optics@convexR
\newdimen\tikzphysics@optics@convexT
\newdimen\tikzphysics@optics@convexy
\newdimen\tikzphysics@optics@convexsag
\newdimen\tikzphysics@optics@convexhx
\newdimen\tikzphysics@optics@convexedgehx
\newdimen\tikzphysics@optics@convexlcx
\newdimen\tikzphysics@optics@convexrcx

\newdimen\tikzphysics@optics@concaveR
\newdimen\tikzphysics@optics@concaveT
\newdimen\tikzphysics@optics@concavey
\newdimen\tikzphysics@optics@concavesag
\newdimen\tikzphysics@optics@concavehx
\newdimen\tikzphysics@optics@concavecenterhx
\newdimen\tikzphysics@optics@concavelcx
\newdimen\tikzphysics@optics@concavercx

\newdimen\tikzphysics@optics@slabdx
\newdimen\tikzphysics@optics@slabdy
\newdimen\tikzphysics@optics@slabhx
\newdimen\tikzphysics@optics@slabhy

\newdimen\tikzphysics@optics@prismdx
\newdimen\tikzphysics@optics@prismdy
\newdimen\tikzphysics@optics@prismhx
\newdimen\tikzphysics@optics@prismhy

\def\tikzphysics@optics@mirrorradius{5cm}
\def\tikzphysics@optics@mirrorthickness{0.25cm}
\def\tikzphysics@optics@mirrorapertureangle{30}
\def\tikzphysics@optics@mirrorarcflag{0}
\def\tikzphysics@optics@convexradius{5cm}
\def\tikzphysics@optics@convexthickness{0.2cm}
\def\tikzphysics@optics@convexapertureangle{25}
\def\tikzphysics@optics@concaveradius{5cm}
\def\tikzphysics@optics@concavethickness{0.2cm}
\def\tikzphysics@optics@concaveapertureangle{25}
\def\tikzphysics@optics@prismapexangle{60}
\def\tikzphysics@optics@prismangleflag{0}

%% ============================================================
%%  HELPERS
%% ============================================================

%% Resolve a length with tikzphysics semantics:
%% explicit units are respected; bare numbers are centimetres.
\newcommand{\tikzphysics@optics@resolvelength}[2]{%
  \tikzphysics@resolve@length{#1}{#2}%
}

%% Curved-mirror geometry.
%%
%% The front arc follows the reference construction:
%%   radius R, aperture angle A, path from -A to +A.
%%
%% The back arc has radius R + T.  Its angular aperture is solved
%% so the top and bottom caps remain horizontal while preserving
%% the requested cap thickness T.  This is the exact version of
%% the small-angle DA correction often used in hand-written TikZ.
\newcommand{\tikzphysics@optics@setmirrordims}{%
  \tikzphysics@optics@resolvelength{\tikzphysics@optics@R}{\tikzphysics@optics@mirrorradius}%
  \tikzphysics@optics@resolvelength{\tikzphysics@optics@T}{\tikzphysics@optics@mirrorthickness}%
  \tikzphysics@optics@Rout=\tikzphysics@optics@R
  \advance\tikzphysics@optics@Rout by \tikzphysics@optics@T
  \pgfmathsetmacro{\tikzphysics@optics@A}{\tikzphysics@optics@mirrorapertureangle}%
  \ifdim\tikzphysics@optics@A pt>0pt\relax\else
    \PackageError{tikzphysics}{mirror aperture angle must be greater than 0 degrees}%
      {Choose an aperture angle strictly between 0 and 90 degrees.}%
  \fi
  \ifdim\tikzphysics@optics@A pt<90pt\relax\else
    \PackageError{tikzphysics}{mirror aperture angle must be less than 90 degrees}%
      {Choose an aperture angle strictly between 0 and 90 degrees.}%
  \fi
  \edef\tikzphysics@optics@Rnum{\strip@pt\tikzphysics@optics@R}%
  \edef\tikzphysics@optics@Tnum{\strip@pt\tikzphysics@optics@T}%
  \pgfmathsetmacro{\tikzphysics@optics@B}{%
    asin(\tikzphysics@optics@Rnum*sin(\tikzphysics@optics@A)/
         (\tikzphysics@optics@Rnum+\tikzphysics@optics@Tnum))}%
  \pgfmathsetlength{\tikzphysics@optics@y}{\tikzphysics@optics@R*sin(\tikzphysics@optics@A)}%
  \pgfmathsetlength{\tikzphysics@optics@frontxraw}{\tikzphysics@optics@R*cos(\tikzphysics@optics@A)}%
  \tikzphysics@optics@backxraw=\tikzphysics@optics@frontxraw
  \advance\tikzphysics@optics@backxraw by \tikzphysics@optics@T
  \pgfmathsetlength{\tikzphysics@optics@bcxraw}{%
    \tikzphysics@optics@backxraw-\tikzphysics@optics@Rout*cos(\tikzphysics@optics@B)}%
  \tikzphysics@optics@backmidraw=\tikzphysics@optics@bcxraw
  \advance\tikzphysics@optics@backmidraw by \tikzphysics@optics@Rout
  %% Centre the node on the midpoint between the two on-axis vertices.
  \tikzphysics@optics@shift=\tikzphysics@optics@R
  \advance\tikzphysics@optics@shift by \tikzphysics@optics@backmidraw
  \divide\tikzphysics@optics@shift by 2
  \tikzphysics@optics@fcx=-\tikzphysics@optics@shift
  \tikzphysics@optics@frontx=\tikzphysics@optics@frontxraw
  \advance\tikzphysics@optics@frontx by -\tikzphysics@optics@shift
  \tikzphysics@optics@backx=\tikzphysics@optics@backxraw
  \advance\tikzphysics@optics@backx by -\tikzphysics@optics@shift
  \tikzphysics@optics@bcx=\tikzphysics@optics@bcxraw
  \advance\tikzphysics@optics@bcx by -\tikzphysics@optics@shift
  \tikzphysics@optics@frontmid=\tikzphysics@optics@R
  \advance\tikzphysics@optics@frontmid by -\tikzphysics@optics@shift
  \tikzphysics@optics@backmid=\tikzphysics@optics@backmidraw
  \advance\tikzphysics@optics@backmid by -\tikzphysics@optics@shift
  \tikzphysics@optics@capmid=\tikzphysics@optics@frontx
  \advance\tikzphysics@optics@capmid by \tikzphysics@optics@backx
  \divide\tikzphysics@optics@capmid by 2
}

%% Symmetric biconvex lens geometry.  The thickness key specifies the
%% material thickness at the top and bottom caps; the centre is thicker by
%% twice the circular sag.  This keeps every positive key combination valid.
\newcommand{\tikzphysics@optics@setconvexdims}{%
  \tikzphysics@optics@resolvelength{\tikzphysics@optics@convexR}{\tikzphysics@optics@convexradius}%
  \tikzphysics@optics@resolvelength{\tikzphysics@optics@convexT}{\tikzphysics@optics@convexthickness}%
  \pgfmathsetmacro{\tikzphysics@optics@convexA}{\tikzphysics@optics@convexapertureangle}%
  \ifdim\tikzphysics@optics@convexA pt>0pt\relax\else
    \PackageError{tikzphysics}{convex lens aperture angle must be greater than 0 degrees}%
      {Choose an aperture angle strictly between 0 and 90 degrees.}%
  \fi
  \ifdim\tikzphysics@optics@convexA pt<90pt\relax\else
    \PackageError{tikzphysics}{convex lens aperture angle must be less than 90 degrees}%
      {Choose an aperture angle strictly between 0 and 90 degrees.}%
  \fi
  \pgfmathsetlength{\tikzphysics@optics@convexy}{%
    \tikzphysics@optics@convexR*sin(\tikzphysics@optics@convexA)}%
  \pgfmathsetlength{\tikzphysics@optics@convexsag}{%
    \tikzphysics@optics@convexR*(1-cos(\tikzphysics@optics@convexA))}%
  \tikzphysics@optics@convexedgehx=.5\tikzphysics@optics@convexT
  \tikzphysics@optics@convexhx=\tikzphysics@optics@convexsag
  \advance\tikzphysics@optics@convexhx by \tikzphysics@optics@convexedgehx
  \tikzphysics@optics@convexlcx=-\tikzphysics@optics@convexhx
  \advance\tikzphysics@optics@convexlcx by \tikzphysics@optics@convexR
  \tikzphysics@optics@convexrcx=\tikzphysics@optics@convexhx
  \advance\tikzphysics@optics@convexrcx by -\tikzphysics@optics@convexR
}

%% Symmetric biconcave lens geometry.  The thickness key is the on-axis
%% centre thickness; the top and bottom edges are thicker by twice the sag.
\newcommand{\tikzphysics@optics@setconcavedims}{%
  \tikzphysics@optics@resolvelength{\tikzphysics@optics@concaveR}{\tikzphysics@optics@concaveradius}%
  \tikzphysics@optics@resolvelength{\tikzphysics@optics@concaveT}{\tikzphysics@optics@concavethickness}%
  \pgfmathsetmacro{\tikzphysics@optics@concaveA}{\tikzphysics@optics@concaveapertureangle}%
  \ifdim\tikzphysics@optics@concaveA pt>0pt\relax\else
    \PackageError{tikzphysics}{concave lens aperture angle must be greater than 0 degrees}%
      {Choose an aperture angle strictly between 0 and 90 degrees.}%
  \fi
  \ifdim\tikzphysics@optics@concaveA pt<90pt\relax\else
    \PackageError{tikzphysics}{concave lens aperture angle must be less than 90 degrees}%
      {Choose an aperture angle strictly between 0 and 90 degrees.}%
  \fi
  \pgfmathsetlength{\tikzphysics@optics@concavey}{%
    \tikzphysics@optics@concaveR*sin(\tikzphysics@optics@concaveA)}%
  \pgfmathsetlength{\tikzphysics@optics@concavesag}{%
    \tikzphysics@optics@concaveR*(1-cos(\tikzphysics@optics@concaveA))}%
  \tikzphysics@optics@concavecenterhx=.5\tikzphysics@optics@concaveT
  \tikzphysics@optics@concavehx=\tikzphysics@optics@concavecenterhx
  \advance\tikzphysics@optics@concavehx by \tikzphysics@optics@concavesag
  \tikzphysics@optics@concavelcx=-\tikzphysics@optics@concavecenterhx
  \advance\tikzphysics@optics@concavelcx by -\tikzphysics@optics@concaveR
  \tikzphysics@optics@concavercx=\tikzphysics@optics@concavecenterhx
  \advance\tikzphysics@optics@concavercx by \tikzphysics@optics@concaveR
}

\newcommand{\tikzphysics@optics@setslabdims}{%
  \pgfmathsetlength{\tikzphysics@optics@slabdx}{\pgfkeysvalueof{/pgf/minimum width}}%
  \pgfmathsetlength{\tikzphysics@optics@slabdy}{\pgfkeysvalueof{/pgf/minimum height}}%
  \tikzphysics@optics@slabhx=.5\tikzphysics@optics@slabdx
  \tikzphysics@optics@slabhy=.5\tikzphysics@optics@slabdy
}

%% Prism width and height use native TikZ minimum dimensions.  An explicitly
%% supplied apex angle is authoritative and derives the total height.
\newcommand{\tikzphysics@optics@setprismdims}{%
  \pgfmathsetlength{\tikzphysics@optics@prismdx}{\pgfkeysvalueof{/pgf/minimum width}}%
  \tikzphysics@optics@prismhx=.5\tikzphysics@optics@prismdx
  \ifnum\tikzphysics@optics@prismangleflag=1\relax
    \pgfmathsetmacro{\tikzphysics@optics@prismA}{\tikzphysics@optics@prismapexangle}%
    \ifdim\tikzphysics@optics@prismA pt>0pt\relax\else
      \PackageError{tikzphysics}{prism apex angle must be greater than 0 degrees}%
        {Choose an apex angle strictly between 0 and 180 degrees.}%
    \fi
    \ifdim\tikzphysics@optics@prismA pt<180pt\relax\else
      \PackageError{tikzphysics}{prism apex angle must be less than 180 degrees}%
        {Choose an apex angle strictly between 0 and 180 degrees.}%
    \fi
    \pgfmathsetlength{\tikzphysics@optics@prismdy}{%
      \tikzphysics@optics@prismhx/tan(0.5*\tikzphysics@optics@prismA)}%
  \else
    \pgfmathsetlength{\tikzphysics@optics@prismdy}{\pgfkeysvalueof{/pgf/minimum height}}%
  \fi
  \tikzphysics@optics@prismhy=.5\tikzphysics@optics@prismdy
}

%% Numeric circular-arc anchors, analogous to core's linear edge
%% anchors.  Angles are in degrees; t=0 is the start angle and
%% t=100 is the end angle.
\def\tikzphysics@optics@declarearcanchor@one#1#2#3#4#5#6#7{%
  \anchor{#1-#2}{%
    \pgfmathsetmacro{\tikzphysics@optics@@theta}{(#6)+((#2)/100)*((#7)-(#6))}%
    \pgfmathsetlength{\pgf@x}{(#3)+(#5)*cos(\tikzphysics@optics@@theta)}%
    \pgfmathsetlength{\pgf@y}{(#4)+(#5)*sin(\tikzphysics@optics@@theta)}%
  }%
}

\def\tikzphysics@optics@declarearcanchors#1#2#3#4#5#6{%
  \foreach \tikzphysics@optics@@t in {0,1,...,100} {%
    \edef\tikzphysics@optics@@partial{%
      \noexpand\tikzphysics@optics@declarearcanchor@one{#1}{\tikzphysics@optics@@t}%
    }%
    \tikzphysics@optics@@partial{#2}{#3}{#4}{#5}{#6}%
  }%
}

%% Short percentage anchors: (node.0) ... (node.100).  These intentionally
%% override TikZ's numeric border-angle fallback on optical shapes.
\def\tikzphysics@optics@declareprimaryarcanchor@one#1#2#3#4#5#6{%
  \anchor{#1}{%
    \pgfmathsetmacro{\tikzphysics@optics@@theta}{(#5)+((#1)/100)*((#6)-(#5))}%
    \pgfmathsetlength{\pgf@x}{(#2)+(#4)*cos(\tikzphysics@optics@@theta)}%
    \pgfmathsetlength{\pgf@y}{(#3)+(#4)*sin(\tikzphysics@optics@@theta)}%
  }%
}

\def\tikzphysics@optics@declareprimaryarcanchors#1#2#3#4#5{%
  \foreach \tikzphysics@optics@@t in {0,1,...,100} {%
    \edef\tikzphysics@optics@@partial{%
      \noexpand\tikzphysics@optics@declareprimaryarcanchor@one{\tikzphysics@optics@@t}%
    }%
    \tikzphysics@optics@@partial{#1}{#2}{#3}{#4}{#5}%
  }%
}

\def\tikzphysics@optics@declareprimarylinearanchor@one#1#2#3#4#5{%
  \anchor{#1}{%
    \pgfmathsetlength{\pgf@x}{(#2)+((#1)/100)*((#4)-(#2))}%
    \pgfmathsetlength{\pgf@y}{(#3)+((#1)/100)*((#5)-(#3))}%
  }%
}

\def\tikzphysics@optics@declareprimarylinearanchors#1#2#3#4{%
  \foreach \tikzphysics@optics@@t in {0,1,...,100} {%
    \edef\tikzphysics@optics@@partial{%
      \noexpand\tikzphysics@optics@declareprimarylinearanchor@one{\tikzphysics@optics@@t}%
    }%
    \tikzphysics@optics@@partial{#1}{#2}{#3}{#4}%
  }%
}

%% ============================================================
%%  TIKZ KEYS
%% ============================================================

\tikzset{
  physics mirror radius/.code         = {\def\tikzphysics@optics@mirrorradius{#1}},
  physics mirror thickness/.code      = {\def\tikzphysics@optics@mirrorthickness{#1}},
  physics mirror aperture angle/.code = {\def\tikzphysics@optics@mirrorapertureangle{#1}},
  mirror radius/.style = {physics mirror radius={#1}},
  mirror thickness/.style = {physics mirror thickness={#1}},
  mirror aperture angle/.style = {physics mirror aperture angle={#1}},
  physics convex lens radius/.code = {\def\tikzphysics@optics@convexradius{#1}},
  physics convex lens thickness/.code = {\def\tikzphysics@optics@convexthickness{#1}},
  physics convex lens aperture angle/.code = {\def\tikzphysics@optics@convexapertureangle{#1}},
  convex lens radius/.style = {physics convex lens radius={#1}},
  convex lens thickness/.style = {physics convex lens thickness={#1}},
  convex lens aperture angle/.style = {physics convex lens aperture angle={#1}},
  physics concave lens radius/.code = {\def\tikzphysics@optics@concaveradius{#1}},
  physics concave lens thickness/.code = {\def\tikzphysics@optics@concavethickness{#1}},
  physics concave lens aperture angle/.code = {\def\tikzphysics@optics@concaveapertureangle{#1}},
  concave lens radius/.style = {physics concave lens radius={#1}},
  concave lens thickness/.style = {physics concave lens thickness={#1}},
  concave lens aperture angle/.style = {physics concave lens aperture angle={#1}},
  physics slab width/.code = {\tikzphysics@length@keyhandler{/pgf/minimum width}{#1}},
  physics slab height/.code = {\tikzphysics@length@keyhandler{/pgf/minimum height}{#1}},
  slab width/.style = {physics slab width={#1}},
  slab height/.style = {physics slab height={#1}},
  physics prism width/.code = {\tikzphysics@length@keyhandler{/pgf/minimum width}{#1}},
  physics prism height/.code = {\tikzphysics@length@keyhandler{/pgf/minimum height}{#1}},
  physics prism apex angle/.code = {%
    \def\tikzphysics@optics@prismapexangle{#1}%
    \def\tikzphysics@optics@prismangleflag{1}%
  },
  prism width/.style = {physics prism width={#1}},
  prism height/.style = {physics prism height={#1}},
  prism apex angle/.style = {physics prism apex angle={#1}},
}

%% ============================================================
%%  CURVED MIRROR SHAPE
%% ============================================================

\pgfdeclareshape{physicsmirror}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchorborder[from=rectangle]

  \savedmacro{\tikzphysics@optics@l@R}{%
    \tikzphysics@optics@setmirrordims
    \edef\tikzphysics@optics@l@R{\the\tikzphysics@optics@R}%
  }
  \savedmacro{\tikzphysics@optics@l@Rout}{%
    \tikzphysics@optics@setmirrordims
    \edef\tikzphysics@optics@l@Rout{\the\tikzphysics@optics@Rout}%
  }
  \savedmacro{\tikzphysics@optics@l@A}{%
    \tikzphysics@optics@setmirrordims
    \edef\tikzphysics@optics@l@A{\tikzphysics@optics@A}%
  }
  \savedmacro{\tikzphysics@optics@l@B}{%
    \tikzphysics@optics@setmirrordims
    \edef\tikzphysics@optics@l@B{\tikzphysics@optics@B}%
  }
  \savedmacro{\tikzphysics@optics@l@y}{%
    \tikzphysics@optics@setmirrordims
    \edef\tikzphysics@optics@l@y{\the\tikzphysics@optics@y}%
  }
  \savedmacro{\tikzphysics@optics@l@fcx}{%
    \tikzphysics@optics@setmirrordims
    \edef\tikzphysics@optics@l@fcx{\the\tikzphysics@optics@fcx}%
  }
  \savedmacro{\tikzphysics@optics@l@frontx}{%
    \tikzphysics@optics@setmirrordims
    \edef\tikzphysics@optics@l@frontx{\the\tikzphysics@optics@frontx}%
  }
  \savedmacro{\tikzphysics@optics@l@backx}{%
    \tikzphysics@optics@setmirrordims
    \edef\tikzphysics@optics@l@backx{\the\tikzphysics@optics@backx}%
  }
  \savedmacro{\tikzphysics@optics@l@bcx}{%
    \tikzphysics@optics@setmirrordims
    \edef\tikzphysics@optics@l@bcx{\the\tikzphysics@optics@bcx}%
  }
  \savedmacro{\tikzphysics@optics@l@frontmid}{%
    \tikzphysics@optics@setmirrordims
    \edef\tikzphysics@optics@l@frontmid{\the\tikzphysics@optics@frontmid}%
  }
  \savedmacro{\tikzphysics@optics@l@backmid}{%
    \tikzphysics@optics@setmirrordims
    \edef\tikzphysics@optics@l@backmid{\the\tikzphysics@optics@backmid}%
  }
  \savedmacro{\tikzphysics@optics@l@capmid}{%
    \tikzphysics@optics@setmirrordims
    \edef\tikzphysics@optics@l@capmid{\the\tikzphysics@optics@capmid}%
  }
  \savedmacro{\tikzphysics@optics@l@surfacecx}{%
    \tikzphysics@optics@setmirrordims
    \ifnum\tikzphysics@optics@mirrorarcflag=0\relax
      \edef\tikzphysics@optics@l@surfacecx{\the\tikzphysics@optics@fcx}%
    \else
      \edef\tikzphysics@optics@l@surfacecx{\the\tikzphysics@optics@bcx}%
    \fi
  }
  \savedmacro{\tikzphysics@optics@l@surfaceR}{%
    \tikzphysics@optics@setmirrordims
    \ifnum\tikzphysics@optics@mirrorarcflag=0\relax
      \edef\tikzphysics@optics@l@surfaceR{\the\tikzphysics@optics@R}%
    \else
      \edef\tikzphysics@optics@l@surfaceR{\the\tikzphysics@optics@Rout}%
    \fi
  }
  \savedmacro{\tikzphysics@optics@l@surfaceA}{%
    \tikzphysics@optics@setmirrordims
    \ifnum\tikzphysics@optics@mirrorarcflag=0\relax
      \edef\tikzphysics@optics@l@surfaceA{\tikzphysics@optics@A}%
    \else
      \edef\tikzphysics@optics@l@surfaceA{\tikzphysics@optics@B}%
    \fi
  }
  \savedmacro{\tikzphysics@optics@l@surfacemid}{%
    \tikzphysics@optics@setmirrordims
    \ifnum\tikzphysics@optics@mirrorarcflag=0\relax
      \edef\tikzphysics@optics@l@surfacemid{\the\tikzphysics@optics@frontmid}%
    \else
      \edef\tikzphysics@optics@l@surfacemid{\the\tikzphysics@optics@backmid}%
    \fi
  }
  \savedmacro{\tikzphysics@optics@l@surfacex}{%
    \tikzphysics@optics@setmirrordims
    \ifnum\tikzphysics@optics@mirrorarcflag=0\relax
      \edef\tikzphysics@optics@l@surfacex{\the\tikzphysics@optics@frontx}%
    \else
      \edef\tikzphysics@optics@l@surfacex{\the\tikzphysics@optics@backx}%
    \fi
  }
  \savedmacro{\tikzphysics@optics@l@rearcx}{%
    \tikzphysics@optics@setmirrordims
    \ifnum\tikzphysics@optics@mirrorarcflag=0\relax
      \edef\tikzphysics@optics@l@rearcx{\the\tikzphysics@optics@bcx}%
    \else
      \edef\tikzphysics@optics@l@rearcx{\the\tikzphysics@optics@fcx}%
    \fi
  }
  \savedmacro{\tikzphysics@optics@l@rearR}{%
    \tikzphysics@optics@setmirrordims
    \ifnum\tikzphysics@optics@mirrorarcflag=0\relax
      \edef\tikzphysics@optics@l@rearR{\the\tikzphysics@optics@Rout}%
    \else
      \edef\tikzphysics@optics@l@rearR{\the\tikzphysics@optics@R}%
    \fi
  }
  \savedmacro{\tikzphysics@optics@l@rearA}{%
    \tikzphysics@optics@setmirrordims
    \ifnum\tikzphysics@optics@mirrorarcflag=0\relax
      \edef\tikzphysics@optics@l@rearA{\tikzphysics@optics@B}%
    \else
      \edef\tikzphysics@optics@l@rearA{\tikzphysics@optics@A}%
    \fi
  }
  \savedmacro{\tikzphysics@optics@l@rearmid}{%
    \tikzphysics@optics@setmirrordims
    \ifnum\tikzphysics@optics@mirrorarcflag=0\relax
      \edef\tikzphysics@optics@l@rearmid{\the\tikzphysics@optics@backmid}%
    \else
      \edef\tikzphysics@optics@l@rearmid{\the\tikzphysics@optics@frontmid}%
    \fi
  }
  \savedmacro{\tikzphysics@optics@l@rearx}{%
    \tikzphysics@optics@setmirrordims
    \ifnum\tikzphysics@optics@mirrorarcflag=0\relax
      \edef\tikzphysics@optics@l@rearx{\the\tikzphysics@optics@backx}%
    \else
      \edef\tikzphysics@optics@l@rearx{\the\tikzphysics@optics@frontx}%
    \fi
  }
  %% ---- bounding-box / compass anchors ----
  \anchor{center}{\pgf@x=0pt \pgf@y=0pt}
  \anchor{north}{\pgf@x=0pt \pgf@y=\tikzphysics@optics@l@y}
  \anchor{south}{\pgf@x=0pt \pgf@y=-\tikzphysics@optics@l@y}
  \anchor{east}{\pgf@x=\tikzphysics@optics@l@backmid \pgf@y=0pt}
  \anchor{west}{\pgf@x=\tikzphysics@optics@l@frontx \pgf@y=0pt}
  \anchor{north east}{\pgf@x=\tikzphysics@optics@l@backmid \pgf@y=\tikzphysics@optics@l@y}
  \anchor{north west}{\pgf@x=\tikzphysics@optics@l@frontx \pgf@y=\tikzphysics@optics@l@y}
  \anchor{south east}{\pgf@x=\tikzphysics@optics@l@backmid \pgf@y=-\tikzphysics@optics@l@y}
  \anchor{south west}{\pgf@x=\tikzphysics@optics@l@frontx \pgf@y=-\tikzphysics@optics@l@y}

  %% ---- optics anchors ----
  \anchor{vertex}{\pgf@x=\tikzphysics@optics@l@surfacemid \pgf@y=0pt}
  \anchor{arc-mid}{\pgf@x=\tikzphysics@optics@l@surfacemid \pgf@y=0pt}
  \anchor{surface-mid}{\pgf@x=\tikzphysics@optics@l@surfacemid \pgf@y=0pt}
  \anchor{front-mid}{\pgf@x=\tikzphysics@optics@l@frontmid \pgf@y=0pt}
  \anchor{back-mid}{\pgf@x=\tikzphysics@optics@l@rearmid \pgf@y=0pt}
  \anchor{front-top}{\pgf@x=\tikzphysics@optics@l@frontx \pgf@y=\tikzphysics@optics@l@y}
  \anchor{front-bottom}{\pgf@x=\tikzphysics@optics@l@frontx \pgf@y=-\tikzphysics@optics@l@y}
  \anchor{surface-top}{\pgf@x=\tikzphysics@optics@l@surfacex \pgf@y=\tikzphysics@optics@l@y}
  \anchor{surface-bottom}{\pgf@x=\tikzphysics@optics@l@surfacex \pgf@y=-\tikzphysics@optics@l@y}
  \anchor{back-top}{\pgf@x=\tikzphysics@optics@l@rearx \pgf@y=\tikzphysics@optics@l@y}
  \anchor{back-bottom}{\pgf@x=\tikzphysics@optics@l@rearx \pgf@y=-\tikzphysics@optics@l@y}
  \anchor{top}{\pgf@x=\tikzphysics@optics@l@capmid \pgf@y=\tikzphysics@optics@l@y}
  \anchor{bottom}{\pgf@x=\tikzphysics@optics@l@capmid \pgf@y=-\tikzphysics@optics@l@y}

  %% ---- background (fill/pattern) path ----
  \backgroundpath{%
    \pgfpathmoveto{\pgfpoint{\tikzphysics@optics@l@frontx}{-\tikzphysics@optics@l@y}}%
    \pgfpatharc{-\tikzphysics@optics@l@A}{\tikzphysics@optics@l@A}{\tikzphysics@optics@l@R}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@optics@l@backx}{\tikzphysics@optics@l@y}}%
    \pgfpatharc{\tikzphysics@optics@l@B}{-\tikzphysics@optics@l@B}{\tikzphysics@optics@l@Rout}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@optics@l@frontx}{-\tikzphysics@optics@l@y}}%
    \pgfpathclose%
  }

  %% Foreground: the optical surface arc from the reference shape.
  \foregroundpath{%
    \pgfsetlinewidth{0.5pt}%
    \pgfpathmoveto{\pgfpoint{\tikzphysics@optics@l@surfacex}{-\tikzphysics@optics@l@y}}%
    \pgfpatharc{-\tikzphysics@optics@l@surfaceA}{\tikzphysics@optics@l@surfaceA}{\tikzphysics@optics@l@surfaceR}%
    \pgfusepath{stroke}%
  }

  %% Reflective surface and rear arc anchors, bottom to top.
  \tikzphysics@optics@declarearcanchors{surface}
    {\tikzphysics@optics@l@surfacecx}{0pt}{\tikzphysics@optics@l@surfaceR}
    {-\tikzphysics@optics@l@surfaceA}{\tikzphysics@optics@l@surfaceA}
  \tikzphysics@optics@declarearcanchors{front}
    {\tikzphysics@optics@l@fcx}{0pt}{\tikzphysics@optics@l@R}
    {-\tikzphysics@optics@l@A}{\tikzphysics@optics@l@A}
  \tikzphysics@optics@declarearcanchors{back}
    {\tikzphysics@optics@l@rearcx}{0pt}{\tikzphysics@optics@l@rearR}
    {-\tikzphysics@optics@l@rearA}{\tikzphysics@optics@l@rearA}
  \tikzphysics@optics@declareprimaryarcanchors
    {\tikzphysics@optics@l@surfacecx}{0pt}{\tikzphysics@optics@l@surfaceR}
    {-\tikzphysics@optics@l@surfaceA}{\tikzphysics@optics@l@surfaceA}
}

%% ============================================================
%%  SYMMETRIC BICONVEX LENS
%% ============================================================

\pgfdeclareshape{physicsconvexlens}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchorborder[from=rectangle]

  \savedmacro{\tikzphysics@optics@cv@R}{%
    \tikzphysics@optics@setconvexdims
    \edef\tikzphysics@optics@cv@R{\the\tikzphysics@optics@convexR}%
  }
  \savedmacro{\tikzphysics@optics@cv@A}{%
    \tikzphysics@optics@setconvexdims
    \edef\tikzphysics@optics@cv@A{\tikzphysics@optics@convexA}%
  }
  \savedmacro{\tikzphysics@optics@cv@y}{%
    \tikzphysics@optics@setconvexdims
    \edef\tikzphysics@optics@cv@y{\the\tikzphysics@optics@convexy}%
  }
  \savedmacro{\tikzphysics@optics@cv@hx}{%
    \tikzphysics@optics@setconvexdims
    \edef\tikzphysics@optics@cv@hx{\the\tikzphysics@optics@convexhx}%
  }
  \savedmacro{\tikzphysics@optics@cv@edgehx}{%
    \tikzphysics@optics@setconvexdims
    \edef\tikzphysics@optics@cv@edgehx{\the\tikzphysics@optics@convexedgehx}%
  }
  \savedmacro{\tikzphysics@optics@cv@lcx}{%
    \tikzphysics@optics@setconvexdims
    \edef\tikzphysics@optics@cv@lcx{\the\tikzphysics@optics@convexlcx}%
  }
  \savedmacro{\tikzphysics@optics@cv@rcx}{%
    \tikzphysics@optics@setconvexdims
    \edef\tikzphysics@optics@cv@rcx{\the\tikzphysics@optics@convexrcx}%
  }

  \anchor{center}{\pgf@x=0pt \pgf@y=0pt}
  \anchor{north}{\pgf@x=0pt \pgf@y=\tikzphysics@optics@cv@y}
  \anchor{south}{\pgf@x=0pt \pgf@y=-\tikzphysics@optics@cv@y}
  \anchor{east}{\pgf@x=\tikzphysics@optics@cv@hx \pgf@y=0pt}
  \anchor{west}{\pgf@x=-\tikzphysics@optics@cv@hx \pgf@y=0pt}
  \anchor{north east}{\pgf@x=\tikzphysics@optics@cv@edgehx \pgf@y=\tikzphysics@optics@cv@y}
  \anchor{north west}{\pgf@x=-\tikzphysics@optics@cv@edgehx \pgf@y=\tikzphysics@optics@cv@y}
  \anchor{south east}{\pgf@x=\tikzphysics@optics@cv@edgehx \pgf@y=-\tikzphysics@optics@cv@y}
  \anchor{south west}{\pgf@x=-\tikzphysics@optics@cv@edgehx \pgf@y=-\tikzphysics@optics@cv@y}

  \anchor{front-mid}{\pgf@x=-\tikzphysics@optics@cv@hx \pgf@y=0pt}
  \anchor{back-mid}{\pgf@x=\tikzphysics@optics@cv@hx \pgf@y=0pt}
  \anchor{front-top}{\pgf@x=-\tikzphysics@optics@cv@edgehx \pgf@y=\tikzphysics@optics@cv@y}
  \anchor{front-bottom}{\pgf@x=-\tikzphysics@optics@cv@edgehx \pgf@y=-\tikzphysics@optics@cv@y}
  \anchor{back-top}{\pgf@x=\tikzphysics@optics@cv@edgehx \pgf@y=\tikzphysics@optics@cv@y}
  \anchor{back-bottom}{\pgf@x=\tikzphysics@optics@cv@edgehx \pgf@y=-\tikzphysics@optics@cv@y}
  \anchor{top}{\pgf@x=0pt \pgf@y=\tikzphysics@optics@cv@y}
  \anchor{bottom}{\pgf@x=0pt \pgf@y=-\tikzphysics@optics@cv@y}

  \backgroundpath{%
    \pgfpathmoveto{\pgfpoint{-\tikzphysics@optics@cv@edgehx}{-\tikzphysics@optics@cv@y}}%
    \pgfpatharc{180+\tikzphysics@optics@cv@A}{180-\tikzphysics@optics@cv@A}{\tikzphysics@optics@cv@R}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@optics@cv@edgehx}{\tikzphysics@optics@cv@y}}%
    \pgfpatharc{\tikzphysics@optics@cv@A}{-\tikzphysics@optics@cv@A}{\tikzphysics@optics@cv@R}%
    \pgfpathclose%
  }

  %% Both optical surfaces expose bottom-to-top parametric anchors.
  \tikzphysics@optics@declarearcanchors{front}
    {\tikzphysics@optics@cv@lcx}{0pt}{\tikzphysics@optics@cv@R}
    {180+\tikzphysics@optics@cv@A}{180-\tikzphysics@optics@cv@A}
  \tikzphysics@optics@declarearcanchors{back}
    {\tikzphysics@optics@cv@rcx}{0pt}{\tikzphysics@optics@cv@R}
    {-\tikzphysics@optics@cv@A}{\tikzphysics@optics@cv@A}
  \tikzphysics@optics@declareprimaryarcanchors
    {\tikzphysics@optics@cv@lcx}{0pt}{\tikzphysics@optics@cv@R}
    {180+\tikzphysics@optics@cv@A}{180-\tikzphysics@optics@cv@A}
}

%% ============================================================
%%  SYMMETRIC BICONCAVE LENS
%% ============================================================

\pgfdeclareshape{physicsconcavelens}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchorborder[from=rectangle]

  \savedmacro{\tikzphysics@optics@cc@R}{%
    \tikzphysics@optics@setconcavedims
    \edef\tikzphysics@optics@cc@R{\the\tikzphysics@optics@concaveR}%
  }
  \savedmacro{\tikzphysics@optics@cc@A}{%
    \tikzphysics@optics@setconcavedims
    \edef\tikzphysics@optics@cc@A{\tikzphysics@optics@concaveA}%
  }
  \savedmacro{\tikzphysics@optics@cc@y}{%
    \tikzphysics@optics@setconcavedims
    \edef\tikzphysics@optics@cc@y{\the\tikzphysics@optics@concavey}%
  }
  \savedmacro{\tikzphysics@optics@cc@hx}{%
    \tikzphysics@optics@setconcavedims
    \edef\tikzphysics@optics@cc@hx{\the\tikzphysics@optics@concavehx}%
  }
  \savedmacro{\tikzphysics@optics@cc@centerhx}{%
    \tikzphysics@optics@setconcavedims
    \edef\tikzphysics@optics@cc@centerhx{\the\tikzphysics@optics@concavecenterhx}%
  }
  \savedmacro{\tikzphysics@optics@cc@lcx}{%
    \tikzphysics@optics@setconcavedims
    \edef\tikzphysics@optics@cc@lcx{\the\tikzphysics@optics@concavelcx}%
  }
  \savedmacro{\tikzphysics@optics@cc@rcx}{%
    \tikzphysics@optics@setconcavedims
    \edef\tikzphysics@optics@cc@rcx{\the\tikzphysics@optics@concavercx}%
  }

  \anchor{center}{\pgf@x=0pt \pgf@y=0pt}
  \anchor{north}{\pgf@x=0pt \pgf@y=\tikzphysics@optics@cc@y}
  \anchor{south}{\pgf@x=0pt \pgf@y=-\tikzphysics@optics@cc@y}
  \anchor{east}{\pgf@x=\tikzphysics@optics@cc@centerhx \pgf@y=0pt}
  \anchor{west}{\pgf@x=-\tikzphysics@optics@cc@centerhx \pgf@y=0pt}
  \anchor{north east}{\pgf@x=\tikzphysics@optics@cc@hx \pgf@y=\tikzphysics@optics@cc@y}
  \anchor{north west}{\pgf@x=-\tikzphysics@optics@cc@hx \pgf@y=\tikzphysics@optics@cc@y}
  \anchor{south east}{\pgf@x=\tikzphysics@optics@cc@hx \pgf@y=-\tikzphysics@optics@cc@y}
  \anchor{south west}{\pgf@x=-\tikzphysics@optics@cc@hx \pgf@y=-\tikzphysics@optics@cc@y}

  \anchor{front-mid}{\pgf@x=-\tikzphysics@optics@cc@centerhx \pgf@y=0pt}
  \anchor{back-mid}{\pgf@x=\tikzphysics@optics@cc@centerhx \pgf@y=0pt}
  \anchor{front-top}{\pgf@x=-\tikzphysics@optics@cc@hx \pgf@y=\tikzphysics@optics@cc@y}
  \anchor{front-bottom}{\pgf@x=-\tikzphysics@optics@cc@hx \pgf@y=-\tikzphysics@optics@cc@y}
  \anchor{back-top}{\pgf@x=\tikzphysics@optics@cc@hx \pgf@y=\tikzphysics@optics@cc@y}
  \anchor{back-bottom}{\pgf@x=\tikzphysics@optics@cc@hx \pgf@y=-\tikzphysics@optics@cc@y}
  \anchor{top}{\pgf@x=0pt \pgf@y=\tikzphysics@optics@cc@y}
  \anchor{bottom}{\pgf@x=0pt \pgf@y=-\tikzphysics@optics@cc@y}

  \backgroundpath{%
    \pgfpathmoveto{\pgfpoint{-\tikzphysics@optics@cc@hx}{-\tikzphysics@optics@cc@y}}%
    \pgfpatharc{-\tikzphysics@optics@cc@A}{\tikzphysics@optics@cc@A}{\tikzphysics@optics@cc@R}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@optics@cc@hx}{\tikzphysics@optics@cc@y}}%
    \pgfpatharc{180-\tikzphysics@optics@cc@A}{180+\tikzphysics@optics@cc@A}{\tikzphysics@optics@cc@R}%
    \pgfpathclose%
  }

  \tikzphysics@optics@declarearcanchors{front}
    {\tikzphysics@optics@cc@lcx}{0pt}{\tikzphysics@optics@cc@R}
    {-\tikzphysics@optics@cc@A}{\tikzphysics@optics@cc@A}
  \tikzphysics@optics@declarearcanchors{back}
    {\tikzphysics@optics@cc@rcx}{0pt}{\tikzphysics@optics@cc@R}
    {180+\tikzphysics@optics@cc@A}{180-\tikzphysics@optics@cc@A}
  \tikzphysics@optics@declareprimaryarcanchors
    {\tikzphysics@optics@cc@lcx}{0pt}{\tikzphysics@optics@cc@R}
    {-\tikzphysics@optics@cc@A}{\tikzphysics@optics@cc@A}
}

%% ============================================================
%%  RECTANGULAR OPTICAL SLAB
%% ============================================================

\pgfdeclareshape{physicsslab}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchorborder[from=rectangle]

  \savedmacro{\tikzphysics@optics@sl@hx}{%
    \tikzphysics@optics@setslabdims
    \edef\tikzphysics@optics@sl@hx{\the\tikzphysics@optics@slabhx}%
  }
  \savedmacro{\tikzphysics@optics@sl@hy}{%
    \tikzphysics@optics@setslabdims
    \edef\tikzphysics@optics@sl@hy{\the\tikzphysics@optics@slabhy}%
  }

  \anchor{center}{\pgf@x=0pt \pgf@y=0pt}
  \anchor{north}{\pgf@x=0pt \pgf@y=\tikzphysics@optics@sl@hy}
  \anchor{south}{\pgf@x=0pt \pgf@y=-\tikzphysics@optics@sl@hy}
  \anchor{east}{\pgf@x=\tikzphysics@optics@sl@hx \pgf@y=0pt}
  \anchor{west}{\pgf@x=-\tikzphysics@optics@sl@hx \pgf@y=0pt}
  \anchor{north east}{\pgf@x=\tikzphysics@optics@sl@hx \pgf@y=\tikzphysics@optics@sl@hy}
  \anchor{north west}{\pgf@x=-\tikzphysics@optics@sl@hx \pgf@y=\tikzphysics@optics@sl@hy}
  \anchor{south east}{\pgf@x=\tikzphysics@optics@sl@hx \pgf@y=-\tikzphysics@optics@sl@hy}
  \anchor{south west}{\pgf@x=-\tikzphysics@optics@sl@hx \pgf@y=-\tikzphysics@optics@sl@hy}

  \anchor{front}{\pgf@x=-\tikzphysics@optics@sl@hx \pgf@y=0pt}
  \anchor{back}{\pgf@x=\tikzphysics@optics@sl@hx \pgf@y=0pt}
  \anchor{front-top}{\pgf@x=-\tikzphysics@optics@sl@hx \pgf@y=\tikzphysics@optics@sl@hy}
  \anchor{front-bottom}{\pgf@x=-\tikzphysics@optics@sl@hx \pgf@y=-\tikzphysics@optics@sl@hy}
  \anchor{back-top}{\pgf@x=\tikzphysics@optics@sl@hx \pgf@y=\tikzphysics@optics@sl@hy}
  \anchor{back-bottom}{\pgf@x=\tikzphysics@optics@sl@hx \pgf@y=-\tikzphysics@optics@sl@hy}
  \anchor{top}{\pgf@x=0pt \pgf@y=\tikzphysics@optics@sl@hy}
  \anchor{bottom}{\pgf@x=0pt \pgf@y=-\tikzphysics@optics@sl@hy}

  \backgroundpath{%
    \pgfpathrectanglecorners
      {\pgfpoint{-\tikzphysics@optics@sl@hx}{-\tikzphysics@optics@sl@hy}}%
      {\pgfpoint{\tikzphysics@optics@sl@hx}{\tikzphysics@optics@sl@hy}}%
  }

  \tikzphysics@declareedgeanchors{front}
    {-\tikzphysics@optics@sl@hx}{-\tikzphysics@optics@sl@hy}
    {-\tikzphysics@optics@sl@hx}{\tikzphysics@optics@sl@hy}
  \tikzphysics@declareedgeanchors{back}
    {\tikzphysics@optics@sl@hx}{-\tikzphysics@optics@sl@hy}
    {\tikzphysics@optics@sl@hx}{\tikzphysics@optics@sl@hy}
  \tikzphysics@declareedgeanchors{top}
    {\tikzphysics@optics@sl@hx}{\tikzphysics@optics@sl@hy}
    {-\tikzphysics@optics@sl@hx}{\tikzphysics@optics@sl@hy}
  \tikzphysics@declareedgeanchors{bottom}
    {-\tikzphysics@optics@sl@hx}{-\tikzphysics@optics@sl@hy}
    {\tikzphysics@optics@sl@hx}{-\tikzphysics@optics@sl@hy}
  \tikzphysics@optics@declareprimarylinearanchors
    {-\tikzphysics@optics@sl@hx}{-\tikzphysics@optics@sl@hy}
    {-\tikzphysics@optics@sl@hx}{\tikzphysics@optics@sl@hy}
}

%% ============================================================
%%  ISOSCELES TRIANGULAR PRISM
%% ============================================================

\pgfdeclareshape{physicsprism}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchorborder[from=rectangle]

  \savedmacro{\tikzphysics@optics@pr@hx}{%
    \tikzphysics@optics@setprismdims
    \edef\tikzphysics@optics@pr@hx{\the\tikzphysics@optics@prismhx}%
  }
  \savedmacro{\tikzphysics@optics@pr@hy}{%
    \tikzphysics@optics@setprismdims
    \edef\tikzphysics@optics@pr@hy{\the\tikzphysics@optics@prismhy}%
  }

  \anchor{center}{\pgf@x=0pt \pgf@y=0pt}
  \anchor{centroid}{\pgf@x=0pt \pgfmathsetlength{\pgf@y}{-\tikzphysics@optics@pr@hy/3}}
  \anchor{north}{\pgf@x=0pt \pgf@y=\tikzphysics@optics@pr@hy}
  \anchor{south}{\pgf@x=0pt \pgf@y=-\tikzphysics@optics@pr@hy}
  \anchor{east}{\pgf@x=\tikzphysics@optics@pr@hx \pgf@y=-\tikzphysics@optics@pr@hy}
  \anchor{west}{\pgf@x=-\tikzphysics@optics@pr@hx \pgf@y=-\tikzphysics@optics@pr@hy}
  \anchor{north east}{\pgf@x=0pt \pgf@y=\tikzphysics@optics@pr@hy}
  \anchor{north west}{\pgf@x=0pt \pgf@y=\tikzphysics@optics@pr@hy}
  \anchor{south east}{\pgf@x=\tikzphysics@optics@pr@hx \pgf@y=-\tikzphysics@optics@pr@hy}
  \anchor{south west}{\pgf@x=-\tikzphysics@optics@pr@hx \pgf@y=-\tikzphysics@optics@pr@hy}

  \anchor{apex}{\pgf@x=0pt \pgf@y=\tikzphysics@optics@pr@hy}
  \anchor{base-left}{\pgf@x=-\tikzphysics@optics@pr@hx \pgf@y=-\tikzphysics@optics@pr@hy}
  \anchor{base-right}{\pgf@x=\tikzphysics@optics@pr@hx \pgf@y=-\tikzphysics@optics@pr@hy}
  \anchor{base-mid}{\pgf@x=0pt \pgf@y=-\tikzphysics@optics@pr@hy}
  \anchor{left-mid}{\pgfmathsetlength{\pgf@x}{-.5*\tikzphysics@optics@pr@hx} \pgf@y=0pt}
  \anchor{right-mid}{\pgfmathsetlength{\pgf@x}{.5*\tikzphysics@optics@pr@hx} \pgf@y=0pt}
  \anchor{entry-mid}{\pgfmathsetlength{\pgf@x}{-.5*\tikzphysics@optics@pr@hx} \pgf@y=0pt}
  \anchor{exit-mid}{\pgfmathsetlength{\pgf@x}{.5*\tikzphysics@optics@pr@hx} \pgf@y=0pt}

  \backgroundpath{%
    \pgfpathmoveto{\pgfpoint{-\tikzphysics@optics@pr@hx}{-\tikzphysics@optics@pr@hy}}%
    \pgfpathlineto{\pgfpoint{\tikzphysics@optics@pr@hx}{-\tikzphysics@optics@pr@hy}}%
    \pgfpathlineto{\pgfpoint{0pt}{\tikzphysics@optics@pr@hy}}%
    \pgfpathclose%
  }

  \tikzphysics@declareedgeanchors{base}
    {-\tikzphysics@optics@pr@hx}{-\tikzphysics@optics@pr@hy}
    {\tikzphysics@optics@pr@hx}{-\tikzphysics@optics@pr@hy}
  \tikzphysics@declareedgeanchors{right}
    {\tikzphysics@optics@pr@hx}{-\tikzphysics@optics@pr@hy}
    {0pt}{\tikzphysics@optics@pr@hy}
  \tikzphysics@declareedgeanchors{left}
    {0pt}{\tikzphysics@optics@pr@hy}
    {-\tikzphysics@optics@pr@hx}{-\tikzphysics@optics@pr@hy}
  \tikzphysics@optics@declareprimarylinearanchors
    {0pt}{\tikzphysics@optics@pr@hy}
    {-\tikzphysics@optics@pr@hx}{-\tikzphysics@optics@pr@hy}
}

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

\tikzphysics@registeranchors{physicsconcavemirror}{%
  center, vertex, surface-mid, surface-top, surface-bottom,
  back-mid, back-top, back-bottom, top, bottom, east, west}
\tikzphysics@registerdisplayname{physicsconcavemirror}{concave-mirror}
\tikzphysics@registerkeys{physicsconcavemirror}{%
  mirror radius, mirror thickness, mirror aperture angle}
\tikzphysics@registerkeydefaults{physicsconcavemirror}{%
  mirror radius/5cm, mirror thickness/0.25cm, mirror aperture angle/$30^\circ$}

\tikzphysics@registeranchors{physicsconvexmirror}{%
  center, vertex, surface-mid, surface-top, surface-bottom,
  back-mid, back-top, back-bottom, top, bottom, east, west}
\tikzphysics@registerdisplayname{physicsconvexmirror}{convex-mirror}
\tikzphysics@registerkeys{physicsconvexmirror}{%
  mirror radius, mirror thickness, mirror aperture angle}
\tikzphysics@registerkeydefaults{physicsconvexmirror}{%
  mirror radius/5cm, mirror thickness/0.25cm, mirror aperture angle/$30^\circ$}

\tikzphysics@registeranchors{physicsconvexlens}{%
  center, front-mid, back-mid, front-top, front-bottom,
  back-top, back-bottom, top, bottom, east, west}
\tikzphysics@registerdisplayname{physicsconvexlens}{convex-lens}
\tikzphysics@registerkeys{physicsconvexlens}{%
  convex lens radius, convex lens thickness, convex lens aperture angle}
\tikzphysics@registerkeydefaults{physicsconvexlens}{%
  convex lens radius/5cm, convex lens thickness/0.2cm,
  convex lens aperture angle/$25^\circ$}

\tikzphysics@registeranchors{physicsconcavelens}{%
  center, front-mid, back-mid, front-top, front-bottom,
  back-top, back-bottom, top, bottom, east, west}
\tikzphysics@registerdisplayname{physicsconcavelens}{concave-lens}
\tikzphysics@registerkeys{physicsconcavelens}{%
  concave lens radius, concave lens thickness, concave lens aperture angle}
\tikzphysics@registerkeydefaults{physicsconcavelens}{%
  concave lens radius/5cm, concave lens thickness/0.2cm,
  concave lens aperture angle/$25^\circ$}

\tikzphysics@registeranchors{physicsslab}{%
  center, front, back, front-top, front-bottom, back-top, back-bottom,
  top, bottom, east, west}
\tikzphysics@registerdisplayname{physicsslab}{slab}
\tikzphysics@registerkeys{physicsslab}{minimum width, minimum height}
\tikzphysics@registerkeydefaults{physicsslab}{minimum width/1.2cm, minimum height/3cm}

\tikzphysics@registeranchors{physicsprism}{%
  center, centroid, apex, base-left, base-right, base-mid,
  left-mid, right-mid, entry-mid, exit-mid}
\tikzphysics@registerdisplayname{physicsprism}{prism}
\tikzphysics@registerkeys{physicsprism}{minimum width, minimum height, prism apex angle}
\tikzphysics@registerkeydefaults{physicsprism}{%
  minimum width/3cm, minimum height/2.6cm, prism apex angle/derived}

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

\tikzset{
  physicsconcavemirror/.style={
    /utils/exec={\def\tikzphysics@optics@mirrorarcflag{0}},
    shape=physicsmirror,
    physics logical shape=physicsconcavemirror,
    physics logical shape=physicsconcavemirror,
    anchor=center,
    draw=none,
    fill=white,
    pattern=north east lines,
    pattern color=black,
    inner sep=0pt,
    outer sep=0pt,
    physics debug setup, every physics object, every concave-mirror,
  },
  physicsconvexmirror/.style={
    /utils/exec={\def\tikzphysics@optics@mirrorarcflag{1}},
    shape=physicsmirror,
    physics logical shape=physicsconvexmirror,
    physics logical shape=physicsconvexmirror,
    anchor=center,
    xscale=-1,
    draw=none,
    fill=white,
    pattern=north east lines,
    pattern color=black,
    inner sep=0pt,
    outer sep=0pt,
    physics debug setup, every physics object, every convex-mirror,
  },
  physicsconvexlens/.style={
    shape=physicsconvexlens,
    physics logical shape=physicsconvexlens,
    anchor=center,
    draw=black,
    fill=white,
    pattern=north east lines,
    pattern color=black,
    inner sep=0pt,
    outer sep=0pt,
    physics debug setup, every physics object, every convex-lens,
  },
  physicsconcavelens/.style={
    shape=physicsconcavelens,
    physics logical shape=physicsconcavelens,
    anchor=center,
    draw=black,
    fill=white,
    pattern=north east lines,
    pattern color=black,
    inner sep=0pt,
    outer sep=0pt,
    physics debug setup, every physics object, every concave-lens,
  },
  physicsslab/.style={
    shape=physicsslab,
    physics logical shape=physicsslab,
    anchor=center,
    draw=black,
    fill=none,
    minimum width=1.2cm,
    minimum height=3cm,
    inner sep=0pt,
    outer sep=0pt,
    physics debug setup, every physics object, every slab,
  },
  physicsprism/.style={
    /utils/exec={\def\tikzphysics@optics@prismangleflag{0}},
    shape=physicsprism,
    physics logical shape=physicsprism,
    anchor=center,
    draw=black,
    fill=none,
    minimum width=3cm,
    minimum height=2.6cm,
    inner sep=0pt,
    outer sep=0pt,
    physics debug setup, every physics object, every prism,
  },
}

%% Short public names; physics... forms remain collision-safe alternatives.
\tikzset{
  concave-mirror/.style={physicsconcavemirror},
  convex-mirror/.style={physicsconvexmirror},
  convex-lens/.style={physicsconvexlens},
  concave-lens/.style={physicsconcavelens},
  slab/.style={physicsslab},
  prism/.style={physicsprism},
}

\tikzset{
  physics mirror radius/.value required,
  physics mirror thickness/.value required,
  physics mirror aperture angle/.value required,
  physics convex lens radius/.value required,
  physics convex lens thickness/.value required,
  physics convex lens aperture angle/.value required,
  physics concave lens radius/.value required,
  physics concave lens thickness/.value required,
  physics concave lens aperture angle/.value required,
  physics slab width/.value required,
  physics slab height/.value required,
  physics prism width/.value required,
  physics prism height/.value required,
  physics prism apex angle/.value required,
}
\makeatother
\endinput
%%
%% End of file `tikzlibrarytikzphysics.optics.code.tex'.
