\input regression-test.tex \documentclass{article} \usepackage{tikz} \usetikzlibrary{tikzphysics} \newdimen\tikzphysicstestx \newdimen\tikzphysicstesty \newdimen\tikzphysicstestxx \newdimen\tikzphysicstestyy \newdimen\tikzphysicstestdiff \newdimen\tikzphysicstestexpected \newcommand{\tikzphysicsgetpoint}[2]{% \pgfextractx{\tikzphysicstestx}{\pgfpointanchor{#1}{#2}}% \pgfextracty{\tikzphysicstesty}{\pgfpointanchor{#1}{#2}}% } \newcommand{\tikzphysicsassertdim}[3]{% \tikzphysicstestexpected=#2\relax \tikzphysicstestdiff=#1\relax \advance\tikzphysicstestdiff by -\tikzphysicstestexpected\relax \ifdim\tikzphysicstestdiff<0pt \tikzphysicstestdiff=-\tikzphysicstestdiff\fi \ifdim\tikzphysicstestdiff<0.02pt \TYPE{PASS: #3}% \else \TYPE{FAIL: #3 (got \the#1, expected \the\tikzphysicstestexpected)}% \fi } \newcommand{\tikzphysicsassertpoint}[5]{% \tikzphysicsgetpoint{#1}{#2}% \tikzphysicstestxx=\tikzphysicstestx \tikzphysicstestyy=\tikzphysicstesty \tikzphysicsgetpoint{#3}{#4}% \tikzphysicsassertdim{\tikzphysicstestxx}{\tikzphysicstestx}{#5 x}% \tikzphysicsassertdim{\tikzphysicstestyy}{\tikzphysicstesty}{#5 y}% } \newcommand{\tikzphysicsassertnumber}[3]{% \pgfmathparse{abs((#1)-(#2))}% \ifdim\pgfmathresult pt<0.001pt \TYPE{PASS: #3}% \else \TYPE{FAIL: #3 (difference \pgfmathresult)}% \fi } \begin{document} \START \begin{tikzpicture} \node[physicsplatform-left, physics platform width=5, physics platform depth=2, physics wall angle=-90, anchor=floor-tl] (Ldown) at (0,0) {}; \node[physicsplatform-left, physics platform width=5, physics platform depth=2, physics wall angle=45, anchor=floor-tl] (Lup) at (0,0) {}; \node[physicsplatform-right, physics platform width=5, physics platform depth=2, physics wall angle=-90, anchor=floor-tr] (Rdown) at (0,0) {}; \node[physicsplatform-left, physics platform width=5, physics platform depth=2, physics strip width=0.3, physics wall angle=135, anchor=floor-tl] (Lmiter) at (0,0) {}; \node[physicsplatform-right, physics platform width=5, physics platform depth=2, physics strip width=0.3, physics wall angle=45, anchor=floor-tr] (Rmiter) at (0,0) {}; \node[platform-left, anchor=floor-tl] (DefaultStrip) at (0,0) {}; \tikzphysicsassertpoint{Ldown}{corner}{Ldown}{floor-tl}{left corner at -90 degrees} \tikzphysicsassertpoint{Lup}{corner}{Lup}{floor-tl}{left corner at 45 degrees} \tikzphysicsassertpoint{Rdown}{corner}{Rdown}{floor-tr}{right corner at -90 degrees} \tikzphysicsassertpoint{Ldown}{wall-A}{Ldown}{floor-tl}{default left wall A equals floor top-left} \tikzphysicsassertpoint{Lup}{wall-A}{Lup}{floor-tl}{bent left wall stays continuous at corner} \tikzphysicsgetpoint{Ldown}{wall-D} \tikzphysicsassertdim{\tikzphysicstestx}{0pt}{default left wall D x} \tikzphysicsassertdim{\tikzphysicstesty}{-2cm}{default left wall spans platform depth} \tikzphysicsgetpoint{Lmiter}{wall-B} \tikzphysicsassertdim{\tikzphysicstestx}{-0.124264cm}{left wall B is exact 135-degree miter} \tikzphysicsassertdim{\tikzphysicstesty}{-0.3cm}{left miter meets floor inner edge} \tikzphysicsgetpoint{Rmiter}{wall-B} \tikzphysicsassertdim{\tikzphysicstestx}{0.124264cm}{right wall B is exact 45-degree miter} \tikzphysicsassertdim{\tikzphysicstesty}{-0.3cm}{right miter meets floor inner edge} \tikzphysicsgetpoint{DefaultStrip}{floor-bl} \tikzphysicsassertdim{\tikzphysicstesty}{-0.25cm}{default platform strip width is 0.25cm} \tikzphysicsassertpoint{Ldown}{floor-top-0}{Ldown}{floor-tr}{floor-top-0 endpoint} \tikzphysicsassertpoint{Ldown}{floor-top-100}{Ldown}{floor-tl}{floor-top-100 endpoint} \tikzphysicsassertpoint{Lup}{wall-outer-0}{Lup}{wall-A}{wall-outer-0 endpoint} \tikzphysicsassertpoint{Lup}{wall-outer-100}{Lup}{wall-D}{wall-outer-100 endpoint} \end{tikzpicture} \begin{tikzpicture} \node[physicswedge, physics wedge width=4, physics wedge angle=30, anchor=bl] (W) at (0,0) {}; \tikzphysicsassertpoint{W}{base-0}{W}{bl}{wedge base-0 endpoint} \tikzphysicsassertpoint{W}{base-100}{W}{br}{wedge base-100 endpoint} \tikzphysicsassertpoint{W}{slope-0}{W}{top}{wedge slope-0 endpoint} \tikzphysicsassertpoint{W}{slope-100}{W}{bl}{wedge slope-100 endpoint} \node[wedge, wedge width=4, wedge angle=40, wedge right angle at=bl] (WBL) at (0,-4) {}; \node[wedge, wedge width=4, wedge angle=25, wedge right angle at=top] (WTOP) at (0,-8) {}; \node[block, rotate=\geometryvalue{W}{slope angle}] at (W.slope-mid) {}; \tikzphysicsassertnumber{\geometryvalue{W}{left angle}}{30} {named wedge retains left interior angle} \tikzphysicsassertnumber{\geometryvalue{W}{right angle}}{90} {named wedge reports right interior angle} \tikzphysicsassertnumber{\geometryvalue{W}{top angle}}{60} {named wedge reports top interior angle} \tikzphysicsassertnumber{\geometryvalue{W}{slope angle}}{30} {named wedge slope angle is directly usable by rotate} \tikzphysicsassertnumber{\geometryvalue{WBL}{left angle}}{90} {bottom-left mode reports its right angle} \tikzphysicsassertnumber{\geometryvalue{WBL}{right angle}}{40} {bottom-left mode reports opposite base angle} \tikzphysicsassertnumber{\geometryvalue{WBL}{right edge direction}}{140} {bottom-left mode reports rising right-edge direction} \tikzphysicsassertnumber{\geometryvalue{WBL}{left edge direction}}{90} {bottom-left mode reports its vertical left edge} \tikzphysicsassertnumber{\geometryvalue{WBL}{slope angle}}{-40} {bottom-left mode reports the slope-mid placement angle} \tikzphysicsassertnumber{\geometryvalue{WTOP}{left angle}}{25} {top mode reports left base angle} \tikzphysicsassertnumber{\geometryvalue{WTOP}{right angle}}{65} {top mode reports right base angle} \tikzphysicsassertnumber{\geometryvalue{WTOP}{top angle}}{90} {top mode reports apex right angle} \tikzphysicsassertnumber{\geometryvalue{WTOP}{slope angle}}{25} {top mode reports the slope-mid placement angle} \tikzphysicsassertnumber{\geometryvalue{WTOP}{right slope angle}}{-65} {top mode reports the slope-right-mid placement angle} \tikzphysicsassertnumber{\tikzphysicsgeometryvalue{WTOP}{right edge angle}}{115} {collision-safe accessor reports right-edge direction} \tikzphysicsassertdim{\geometryvalue{W}{width}}{4cm} {named wedge reports resolved width} \pgfmathsetlength{\tikzphysicstestexpected}{4cm*tan(30)} \tikzphysicsassertdim{\geometryvalue{W}{height}}{\tikzphysicstestexpected} {named wedge reports resolved height} \edef\tikzphysicstestmode{\geometryvalue{WTOP}{right angle at}} \def\tikzphysicstestexpectedmode{top} \ifx\tikzphysicstestmode\tikzphysicstestexpectedmode \TYPE{PASS: named wedge reports right-angle vertex}% \else \TYPE{FAIL: named wedge reports wrong right-angle vertex}% \fi \end{tikzpicture} \begin{tikzpicture} \node[ramp, minimum width=8.6cm, ramp run=2.6cm, ramp rise=1.5cm] (Ramp) at (0,0) {}; \tikzphysicsassertpoint{Ramp}{surface-0}{Ramp}{surface-start} {straight ramp surface-0 endpoint} \tikzphysicsassertpoint{Ramp}{surface-100}{Ramp}{surface-end} {straight ramp surface-100 endpoint} \tikzphysicsassertpoint{Ramp}{50}{Ramp}{surface-50} {straight ramp shorthand 50 uses contact surface} \tikzphysicsgetpoint{Ramp}{floor-end} \tikzphysicsassertdim{\tikzphysicstestx}{6cm}{straight ramp flat length} \tikzphysicsassertdim{\tikzphysicstesty}{0pt}{straight ramp floor is horizontal} \tikzphysicsgetpoint{Ramp}{ramp-top} \tikzphysicsassertdim{\tikzphysicstestx}{8.6cm}{straight ramp overall width} \tikzphysicsassertdim{\tikzphysicstesty}{1.5cm}{straight ramp explicit rise} \tikzphysicsgetpoint{Ramp}{normal-0} \tikzphysicsassertdim{\tikzphysicstestx}{0pt}{straight ramp start normal x} \tikzphysicsassertdim{\tikzphysicstesty}{0.5cm}{straight ramp start normal y} \physicsrampangle{Ramp}{$30^\circ$} \TYPE{PASS: straight ramp angle marker compiles} \node[ramp-left, minimum width=8.6cm, ramp run=2.6cm, ramp rise=1.5cm] (RampLeft) at (0,-2) {}; \tikzphysicsgetpoint{RampLeft}{surface-end} \tikzphysicsassertdim{\tikzphysicstestx}{-8.6cm}{left straight ramp mirrors x} \tikzphysicsassertdim{\tikzphysicstesty}{-0.5cm}{left straight ramp retains rise} \end{tikzpicture} \begin{tikzpicture} \node[curved-ramp, curved ramp floor length=2cm, curved ramp radius=4cm, curved ramp angle=90, curved ramp back extension=1cm] (Curve) at (0,0) {}; \tikzphysicsassertpoint{Curve}{surface-0}{Curve}{surface-start} {curved ramp surface-0 endpoint} \tikzphysicsassertpoint{Curve}{surface-100}{Curve}{surface-end} {curved ramp surface-100 endpoint} \tikzphysicsassertpoint{Curve}{80}{Curve}{surface-80} {curved ramp shorthand 80 uses contact surface} \tikzphysicsgetpoint{Curve}{surface-end} \tikzphysicsassertdim{\tikzphysicstestx}{6cm}{quarter-circle ramp end x} \tikzphysicsassertdim{\tikzphysicstesty}{4cm}{quarter-circle ramp end y} \tikzphysicsgetpoint{Curve}{surface-start} \tikzphysicsassertdim{\tikzphysicstestx}{0cm}{curved ramp floor starts at node position} \tikzphysicsassertdim{\tikzphysicstesty}{0pt}{curved ramp floor remains horizontal} \tikzphysicstestxx=\tikzphysicstestx \tikzphysicsgetpoint{Curve}{curve-start} \advance\tikzphysicstestx by -\tikzphysicstestxx \tikzphysicsassertdim{\tikzphysicstestx}{2cm}{curved ramp floor length} \tikzphysicsassertpoint{Curve}{floor-end}{Curve}{curve-start} {curved ramp floor meets circular arc continuously} \tikzphysicsgetpoint{Curve}{curve-50} \tikzphysicsassertdim{\tikzphysicstestx}{4.828427cm}{curved ramp arc midpoint x} \tikzphysicsassertdim{\tikzphysicstesty}{1.171573cm}{curved ramp arc midpoint y} \tikzphysicsassertpoint{Curve}{curve-0}{Curve}{curve-start} {curved ramp curve-0 endpoint} \tikzphysicsassertpoint{Curve}{curve-100}{Curve}{curve-end} {curved ramp curve-100 endpoint} \tikzphysicsgetpoint{Curve}{normal-100} \tikzphysicsassertdim{\tikzphysicstestx}{5.5cm}{curved ramp top outward normal x} \tikzphysicsassertdim{\tikzphysicstesty}{4cm}{curved ramp top outward normal y} \node[curved-ramp-left, curved ramp radius=4cm, curved ramp angle=90] (CurveLeft) at (0,-5) {}; \tikzphysicsgetpoint{CurveLeft}{surface-end} \tikzphysicsassertdim{\tikzphysicstestx}{-6.5cm}{left curved ramp uses 2.5cm default floor and mirrors x} \tikzphysicsassertdim{\tikzphysicstesty}{-1cm}{left curved ramp retains rise} \end{tikzpicture} \begin{tikzpicture}[scale=0.2,every node/.append style={transform shape}] \node[concave-mirror, mirror radius=5, mirror thickness=0.25, mirror aperture angle=30] (Mirror) at (0,0) {}; \tikzphysicsassertpoint{Mirror}{surface-0}{Mirror}{surface-bottom} {concave mirror surface-0 endpoint} \tikzphysicsassertpoint{Mirror}{surface-100}{Mirror}{surface-top} {concave mirror surface-100 endpoint} \tikzphysicsassertpoint{Mirror}{back-0}{Mirror}{back-bottom} {concave mirror back-0 endpoint} \tikzphysicsassertpoint{Mirror}{back-100}{Mirror}{back-top} {concave mirror back-100 endpoint} \tikzphysicsassertpoint{Mirror}{80}{Mirror}{surface-80} {concave mirror shorthand 80 uses reflecting surface} \node[convex-mirror, mirror radius=5, mirror thickness=0.25, mirror aperture angle=30] (ConvexMirror) at (0,-5) {}; \tikzphysicsgetpoint{ConvexMirror}{surface-mid} \ifdim\tikzphysicstestx<0pt \TYPE{PASS: convex mirror reflecting arc is on the left} \else \TYPE{FAIL: convex mirror reflecting arc is not on the left} \fi \TYPE{PASS: concave and convex mirror styles compile} \end{tikzpicture} \begin{tikzpicture}[scale=0.2,every node/.append style={transform shape}] \node[convex-lens, convex lens radius=5, convex lens thickness=0.2, convex lens aperture angle=25] (Convex) at (0,0) {}; \tikzphysicsassertpoint{Convex}{front-0}{Convex}{front-bottom} {convex lens front-0 endpoint} \tikzphysicsassertpoint{Convex}{front-100}{Convex}{front-top} {convex lens front-100 endpoint} \tikzphysicsassertpoint{Convex}{back-0}{Convex}{back-bottom} {convex lens back-0 endpoint} \tikzphysicsassertpoint{Convex}{back-100}{Convex}{back-top} {convex lens back-100 endpoint} \tikzphysicsassertpoint{Convex}{50}{Convex}{front-50} {convex lens shorthand 50 uses front surface} \node[concave-lens, concave lens radius=5, concave lens thickness=0.2, concave lens aperture angle=25] (Concave) at (2,0) {}; \tikzphysicsassertpoint{Concave}{front-0}{Concave}{front-bottom} {concave lens front-0 endpoint} \tikzphysicsassertpoint{Concave}{front-100}{Concave}{front-top} {concave lens front-100 endpoint} \tikzphysicsassertpoint{Concave}{back-0}{Concave}{back-bottom} {concave lens back-0 endpoint} \tikzphysicsassertpoint{Concave}{back-100}{Concave}{back-top} {concave lens back-100 endpoint} \tikzphysicsassertpoint{Concave}{80}{Concave}{front-80} {concave lens shorthand 80 uses front surface} \node[slab, slab width=1.2, slab height=3] (Slab) at (4,0) {}; \tikzphysicsassertpoint{Slab}{front-0}{Slab}{front-bottom} {slab front-0 endpoint} \tikzphysicsassertpoint{Slab}{front-100}{Slab}{front-top} {slab front-100 endpoint} \tikzphysicsassertpoint{Slab}{back-0}{Slab}{back-bottom} {slab back-0 endpoint} \tikzphysicsassertpoint{Slab}{back-100}{Slab}{back-top} {slab back-100 endpoint} \tikzphysicsassertpoint{Slab}{50}{Slab}{front-50} {slab shorthand 50 uses front surface} \node[prism, prism width=3, prism apex angle=60] (Prism) at (8,0) {}; \tikzphysicsassertpoint{Prism}{base-0}{Prism}{base-left} {prism base-0 endpoint} \tikzphysicsassertpoint{Prism}{base-100}{Prism}{base-right} {prism base-100 endpoint} \tikzphysicsassertpoint{Prism}{right-100}{Prism}{apex} {prism right-100 endpoint} \tikzphysicsassertpoint{Prism}{left-0}{Prism}{apex} {prism left-0 endpoint} \tikzphysicsassertpoint{Prism}{80}{Prism}{left-80} {prism shorthand 80 uses left entry face} \end{tikzpicture} \begin{tikzpicture} \node[physicsblock, physics block width=1, physics block height=10mm] (Block) at (0,0) {}; \tikzphysicsgetpoint{Block}{east} \tikzphysicsassertdim{\tikzphysicstestx}{0.5cm}{bare block width is centimetres} \tikzphysicsgetpoint{Block}{north} \tikzphysicsassertdim{\tikzphysicstesty}{5mm}{explicit block height unit is preserved} \end{tikzpicture} \begin{tikzpicture} \coordinate (SpringA) at (0,0); \coordinate (SpringB) at (4,0); \draw[spring, pre length=5mm, post length=7mm, amplitude=4.5pt, segment length=4.5pt] (SpringA) -- node[above] {$k$} (SpringB); \draw[physicsspring, physics spring amplitude=3pt] (0,-1) -- (3,-1); \TYPE{PASS: spring is a configurable path style in concise and collision-safe forms} \end{tikzpicture} \begin{tikzpicture} \coordinate (StringA) at (-3,-1); \coordinate (StringB) at (3,-1); \node[physicspulley, physics pulley diameter=1] (StringPulley) at (0,0) {}; \physicsstringoverpulley{StringA}{StringPulley}{StringB} \physicsstringoverpulley[ physics string start solution=1, physics string end solution=2, physics string wrap=shortest, dashed] {StringA}{StringPulley}{StringB} \physicsstringoverpulley[string route=over]{StringA}{StringPulley}{StringB} \physicsstringoverpulley[string route=under]{StringA}{StringPulley}{StringB} \physicsstringoverpulley[string route=shortest]{StringA}{StringPulley}{StringB} \TYPE{PASS: tangent pulley string default, explicit, and named routes compile} \end{tikzpicture} \begin{tikzpicture}[scale=0.5,every node/.append style={transform shape}] \node[platform, minimum width=5cm, minimum height=2cm, left wall angle=135, right wall angle=45] (ShortPlatform) at (0,0) {}; \node[physicsplatform-both, minimum width=5cm, minimum height=2cm, physics left wall angle=135, physics right wall angle=45] (LongPlatform) at (0,0) {}; \tikzphysicsassertpoint{ShortPlatform}{left-corner}{LongPlatform}{left-corner} {short platform matches collision-safe platform} \tikzphysicsassertpoint{ShortPlatform}{right-corner}{LongPlatform}{right-corner} {short platform right corner matches collision-safe platform} \node[platform-left-up, minimum width=3cm, minimum height=1.5cm] (UpShort) at (0,-9) {}; \node[physicsplatform-left, minimum width=3cm, minimum height=1.5cm, physics wall angle=90] (UpLong) at (0,-9) {}; \tikzphysicsassertpoint{UpShort}{wall-D}{UpLong}{wall-D} {platform-left-up equals a 90-degree left wall} \node[platform-right-up, minimum width=3cm, minimum height=1.5cm] (RightUpShort) at (5,-9) {}; \node[physicsplatform-right, minimum width=3cm, minimum height=1.5cm, physics wall angle=90] (RightUpLong) at (5,-9) {}; \tikzphysicsassertpoint{RightUpShort}{wall-D}{RightUpLong}{wall-D} {platform-right-up equals a 90-degree right wall} \node[wedge, wedge width=4cm, wedge angle=30] (ShortWedge) at (0,-3) {}; \node[physicswedge, physics wedge width=4cm, physics wedge angle=30] (LongWedge) at (0,-3) {}; \tikzphysicsassertpoint{ShortWedge}{slope-mid}{LongWedge}{slope-mid} {concise wedge keys match collision-safe aliases} \node[wedge, wedge width=4cm, wedge height=2cm] (ShortHeightWedge) at (0,-6) {}; \TYPE{PASS: wedge height concise key compiles} \node[block, minimum width=1cm, minimum height=8mm] (ShortBlock) at (5,-3) {}; \draw[spring] (4,-5) -- (6,-5); \node[pulley, minimum size=1cm, pulley axle radius=1.5pt] (ShortPulley) at (7,-3) {}; \node[concave-mirror, mirror radius=5cm] at (10,-3) {}; \node[convex-mirror, mirror radius=5cm] at (10,-3) {}; \node[convex-lens, convex lens radius=5cm] at (10,-3) {}; \node[concave-lens, concave lens radius=5cm] at (10,-3) {}; \node[slab, minimum width=1cm, minimum height=2cm] at (10,-3) {}; \node[prism, minimum width=2cm, minimum height=1.7cm] at (10,-3) {}; \node[ground, ground width=2cm] at (0,-6) {}; \node[ceiling, ceiling width=2cm] at (3,-6) {}; \node[wall-left, wall height=2cm] at (6,-6) {}; \node[wall-right, wall height=2cm] at (9,-6) {}; \TYPE{PASS: all concise public styles compile, including optics components} \end{tikzpicture} \END \end{document}