\iffalse The tikzoptics library Copyright (C) 2013-2016 by Michel Fruchart This work may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), version 1.3c, which can be found at the address: https://www.latex-project.org/lppl/lppl-1-3c/ Alternatively, it may be distributed and/or modified under the conditions of the GNU General Public License (GNU GPL), version 2, which can be found at the address: https://www.gnu.org/licenses/gpl-2.0.en.html or any later version published by the Free Software Foundation. \fi \makeatletter \def\tikzopticsversion{0.2.3} \def\tikzopticsversiondate{2017-03-11} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % errors from this library %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \def\opticserror#1{\pgfutil@packageerror{tikz/optics}{#1}{}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % handler |collect unknowns| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % from http://tex.stackexchange.com/questions/81821/filtering-options-with-pgfkeys/81985#81985 % used by /tikz/optics/->n- % \pgfkeys{ /handlers/.collect unknowns/.style = { unknown options/.initial = {}, .unknown/.code = {% \letcs\reserved{pgfk@\pgfkeyscurrentpath/unknown options}% \csedef{pgfk@\pgfkeyscurrentpath/unknown options}{% \ifx\reserved\empty\else\expandonce\reserved,\fi \expandonce\pgfkeyscurrentname \ifx\pgfkeysnovalue##1\else=\expandonce\pgfkeyscurrentvalue\fi }% } } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % defining |optics| family %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \pgfkeys{ /tikz/.cd, optics/.is family, optics/.search also={/tikz}, } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [use optics] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \pgfkeys{ /tikz/use optics/.append code={ \pgfkeys{ /tikz/.cd, % shapes % FIXME il ne devrait pas y avoir de logique (ni de valeurs par défaut) ici, seulement l'export dans l'espace de nom commun lens/.prefix style={shape=lens,optics,draw}, slit/.prefix style={shape=slit,optics,draw}, double slit/.prefix style={shape=double slit,optics,draw}, thin optics element/.prefix style={shape=thin optics element,optics,draw}, polarizer/.prefix style={shape=polarizer,optics,draw,object aspect ratio=0.1}, generic optics io/.prefix style={shape=generic optics io,optics,draw}, sensor/.prefix style={shape=sensor,optics,object aspect ratio=1,draw}, sensor line/.prefix style={shape=sensor line,optics,draw}, mirror/.prefix style={shape=mirror,optics,draw}, spherical mirror/.prefix style={shape=spherical mirror,optics,draw}, thick optics element/.prefix style={shape=thick optics element,optics,draw,object aspect ratio=0.1}, heat filter/.prefix style={shape=thick optics element,optics,draw, object aspect ratio=0.05}, double amici prism/.prefix style={shape=double amici prism,optics,draw, prism height=1cm, prism apex angle=60}, % styles screen/.prefix style={optics,/tikz/optics/screen}, diffraction grating/.style={optics,/tikz/optics/diffraction grating}, grid/.style={optics, /tikz/optics/grid}, semi-transparent mirror/.style={optics, /tikz/optics/semi-transparent mirror}, diaphragm/.style={optics, /tikz/optics/diaphragm}, beam splitter/.prefix style={optics,/tikz/optics/beam splitter}, generic lamp/.prefix style={optics,/tikz/optics/generic lamp}, generic sensor/.prefix style={optics,/tikz/optics/generic sensor}, halogen lamp/.prefix style={optics,/tikz/optics/halogen lamp}, spectral lamp/.prefix style={optics,/tikz/optics/spectral lamp}, laser/.prefix style={optics,/tikz/optics/laser}, laser'/.prefix style={optics,/tikz/optics/laser'}, concave mirror/.prefix style={optics, /tikz/optics/concave mirror}, convex mirror/.prefix style={optics, /tikz/optics/convex mirror}, % arrows (styles) ->-/.prefix style={optics,/tikz/optics/->-={##1}}, -<-/.prefix style={optics,/tikz/optics/-<-={##1}}, ->>-/.prefix style={optics,/tikz/optics/->>-={##1}}, -<<-/.prefix style={optics,/tikz/optics/-<<-={##1}}, ->>>-/.prefix style={optics,/tikz/optics/->>>-={##1}}, -<<<-/.prefix style={optics,/tikz/optics/-<<<-={##1}}, ->>>>-/.prefix style={optics,/tikz/optics/->>>>-={##1}}, -<<<<-/.prefix style={optics,/tikz/optics/-<<<<-={##1}}, ->n-/.prefix style={optics,/tikz/optics/->n-={##1}}, - should be strictly lower than (in slit)} \fi \north \pgf@xa=\pgf@x \pgf@ya=\pgf@y \slitnorth \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}} \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}} \south \pgf@xa=\pgf@x \pgf@ya=\pgf@y \slitsouth \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}} \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}} } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Shape [double slit] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % keys : % - slit height : (relative) height of the holes (each) % - slit separation : (relative) distance between the centers of the holes \pgfkeys{/tikz/optics/.cd, object height/.initial=2cm, slit height/.initial=0.075, slit separation/.initial=0.2 } \pgfdeclareshape{double slit} { \savedanchor{\center}{ \pgfpointorigin } \anchor{center}{\center} \savedmacro\objectHeight{% \edef\objectHeight{\pgfkeysvalueof{/tikz/optics/object height}}% } \savedmacro\slitHeight{% \pgfmathparse{\pgfkeysvalueof{/tikz/optics/slit height}}% \ifpgfmathunitsdeclared% \pgfmathsetlengthmacro{\slitHeight}{\pgfkeysvalueof{/tikz/optics/slit height}}% \else% \pgfmathsetlengthmacro{\slitHeight}{\pgfkeysvalueof{/tikz/optics/slit height}*\pgfkeysvalueof{/tikz/optics/object height}}% \fi% } \savedmacro\slitSeparation{% \pgfmathparse{\pgfkeysvalueof{/tikz/optics/slit separation}}% \ifpgfmathunitsdeclared% \pgfmathsetlengthmacro{\slitSeparation}{\pgfkeysvalueof{/tikz/optics/slit separation}}% \else% \pgfmathsetlengthmacro{\slitSeparation}{\pgfkeysvalueof{/tikz/optics/slit separation}*\pgfkeysvalueof{/tikz/optics/object height}}% \fi% } \savedmacro\macro@slitOneCenter{ \def\macro@slitOneCenter{ \pgfpointorigin \pgf@ya=\slitSeparation \pgf@ya=0.5\pgf@ya \advance \pgf@y by \pgf@ya } } \savedmacro\macro@slitTwoCenter{ \def\macro@slitTwoCenter{ \pgfpointorigin \pgf@ya=\slitSeparation \pgf@ya=-0.5\pgf@ya \advance \pgf@y by \pgf@ya } } \savedanchor{\north}{ \pgf@x=0cm% \pgf@y=\objectHeight% \pgf@y=0.5\pgf@y% } \anchor{north}{\north} \savedanchor{\south}{ \pgf@x=0cm% \pgf@y=\objectHeight% \pgf@y=-0.5\pgf@y% } \anchor{south}{\south} % slit 1 \savedanchor{\slitOneCenter}{ \macro@slitOneCenter } \anchor{slit 1 center}{\slitOneCenter} \savedanchor{\slitOneNorth}{ \macro@slitOneCenter \pgf@ya = \slitHeight \pgf@ya = 0.5\pgf@ya \advance \pgf@y by \pgf@ya } \anchor{slit 1 north}{\slitOneNorth} \savedanchor{\slitOneSouth}{ \macro@slitOneCenter \pgf@ya = \slitHeight \pgf@ya = -0.5\pgf@ya \advance \pgf@y by \pgf@ya } \anchor{slit 1 south}{\slitOneSouth} % slit 2 \savedanchor{\slitTwoCenter}{ \macro@slitTwoCenter } \anchor{slit 2 center}{\slitTwoCenter} \savedanchor{\slitTwoNorth}{ \macro@slitTwoCenter \pgf@ya = \slitHeight \pgf@ya = 0.5\pgf@ya \advance \pgf@y by \pgf@ya } \anchor{slit 2 north}{\slitTwoNorth} \savedanchor{\slitTwoSouth}{ \macro@slitTwoCenter \pgf@ya = \slitHeight \pgf@ya = -0.5\pgf@ya \advance \pgf@y by \pgf@ya } \anchor{slit 2 south}{\slitTwoSouth} \anchor{east}{\center} \anchor{west}{\center} \inheritanchorborder[from=thin optics element] \backgroundpath { % erreurs possibles dans les spécifications du dessin \pgfmathparse{notgreater(\slitSeparation, \slitHeight)} \ifnum\pgfmathresult=1 \opticserror{ should be strictly lower than (in double slit)} \fi \pgfmathparse{notless(\slitSeparation+\slitHeight, \objectHeight)} \ifnum\pgfmathresult=1 \opticserror{ plus should be strictly lower than (in double slit)} \fi \north \pgf@xa=\pgf@x \pgf@ya=\pgf@y \slitOneNorth \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}} \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}} \slitOneSouth \pgf@xa=\pgf@x \pgf@ya=\pgf@y \slitTwoNorth \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}} \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}} \slitTwoSouth \pgf@xa=\pgf@x \pgf@ya=\pgf@y \south \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}} \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}} } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Shape [mirror] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % keys % - mirror decoration separation % - mirror decoration amplitude \pgfkeys{/tikz/optics/.cd, object height/.initial=2cm, mirror decoration separation/.initial=0.15cm, mirror decoration amplitude/.initial=0.125cm, } \pgfdeclareshape{mirror} { \savedanchor{\center}{ \pgfpointorigin } \anchor{center}{\center} \savedmacro\objectHeight{% \edef\objectHeight{\pgfkeysvalueof{/tikz/optics/object height}}% } \savedanchor{\north}{ \pgf@x=0cm% \pgf@y=\objectHeight% \pgf@y=0.5\pgf@y% } \anchor{north}{\north} \savedanchor{\south}{ \pgf@x=0cm% \pgf@y=\objectHeight% \pgf@y=-0.5\pgf@y% } \anchor{south}{\south} \anchor{east}{\center} \anchor{west}{\center} % bof \inheritanchorborder[from=thin optics element] \backgroundpath { \north \pgf@xa=\pgf@x \pgf@ya=\pgf@y \south \pgf@xb=\pgf@x \pgf@yb=\pgf@y % We use a border decoration to make a mirror (hachures). % First set the decoration parameters : % - decoration angle % l'angle est 45-180 et on multiplie l'amplitude par -1 pour que la décoration commence et finisse par un trait (c'est un peu louche mais bon) \def\pgfdecorationsegmentangle{45-180}% % - decoration step length \pgfmathparse{\pgfkeysvalueof{/tikz/optics/mirror decoration separation}} \ifpgfmathunitsdeclared% \pgfmathsetlengthmacro{\pgfdecorationsegmentlength}{\pgfkeysvalueof{/tikz/optics/mirror decoration separation}}% \else% \pgfmathsetlengthmacro{\pgfdecorationsegmentlength}{\pgfkeysvalueof{/tikz/optics/mirror decoration separation}*\pgfkeysvalueof{/tikz/optics/object height}}% \fi% % magouillons pour que \pgfdecorationsegmentlength soit un multiple de la longueur ... \pgfmathsetmacro\initialstep{\pgfdecorationsegmentlength} \pgfmathsetmacro\totallength{\pgfkeysvalueof{/tikz/optics/object height}} \pgfmathsetmacro\newstep{\totallength/floor(\totallength/\initialstep)} \pgfmathsetlengthmacro{\pgfdecorationsegmentlength}{\newstep} % fin magouille % - decoration amplitude % on multiplie par -1 pour que ça aille dans le bon sens (pour éviter des problèmes louches) \pgfmathparse{\pgfkeysvalueof{/tikz/optics/mirror decoration amplitude}} \ifpgfmathunitsdeclared% \pgfmathsetlengthmacro{\pgfdecorationsegmentamplitude}{-1*\pgfkeysvalueof{/tikz/optics/mirror decoration amplitude}}% \else% \pgfmathsetlengthmacro{\pgfdecorationsegmentamplitude}{-1*\pgfkeysvalueof{/tikz/optics/mirror decoration amplitude}*\pgfkeysvalueof{/tikz/optics/object height}}% \fi% % Use decoration. \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}} \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}} \pgfdecoratecurrentpath{border} % % dessin du miroir (trait) \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}} \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}} } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Shape [spherical mirror] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % keys : % - spherical mirror angle : the aperture angle of the mirror % - spherical mirror type (concave or convex) % - spherical mirror orientation (ltr or rtl) % The properties of the decoration are controled by the same parameters as in [mirror]. % Height is controled by |object height|, as usual. \pgfkeys{/tikz/optics/spherical mirror angle/.initial=150} \newif\iftikz@optics@sphericalmirror@concave \tikz@optics@sphericalmirror@concavetrue \pgfkeys{/tikz/optics/.cd, spherical mirror type/.is choice, spherical mirror type/concave/.code={\tikz@optics@sphericalmirror@concavetrue}, spherical mirror type/convex/.code={\tikz@optics@sphericalmirror@concavefalse} } \newif\iftikz@optics@sphericalmirror@ltr \tikz@optics@sphericalmirror@ltrtrue \pgfkeys{/tikz/optics/.cd, spherical mirror orientation/.is choice, spherical mirror orientation/ltr/.code={\tikz@optics@sphericalmirror@ltrtrue}, spherical mirror orientation/rtl/.code={\tikz@optics@sphericalmirror@ltrfalse} } % shortcuts (styles) : [concave mirror] and [convex mirror] \pgfkeys{/tikz/optics/.cd, concave mirror/.style={optics, spherical mirror, /tikz/optics/spherical mirror type=concave}, convex mirror/.style={optics, spherical mirror, /tikz/optics/spherical mirror type=convex}, } \pgfdeclareshape{spherical mirror}{% \savedmacro\installsphericalmirrorparameters{% % % Define a \centerpoint % \pgfextract@process\centerpoint{% \pgfpointorigin }% % % Define height % \pgfmathsetlengthmacro\height{\pgfkeysvalueof{/tikz/optics/object height}}% % % Function to define angle from radius % use e.g. [spherical mirror angle=from_radius(2cm)] instead of e.g. [spherical mirror angle=90] % This can seem somewhat ridiculous as we will undo this when calculating \radius, however it helps providing a simpler API. % This function has to be defined before parsing \pgfkeysvalueof{/tikz/optics/spherical mirror angle}. % \pgfmathdeclarefunction{from_radius}{1}{ \begingroup \pgfmathparse{notless(2*#1,\height)} \ifnum\pgfmathresult=0 \opticserror{(in /tikz/optics/spherical mirror angle=from_radius(R)) : for a spherical mirror, the radius R cannot be smaller than half the height . Set a bigger radius of a smaller height.} \fi \newdimen\angle \pgfmathsetlength\angle{2*asin(\height/(2*#1))} \pgf@x=\angle \pgfmathreturn\pgf@x \endgroup } % % Define angle % \pgfmathsetmacro\angle{\pgfkeysvalueof{/tikz/optics/spherical mirror angle}} % % Compute radius from height and angle % \pgfmathsetlengthmacro\radius{\height/(2*sin(\angle/2))} % % Half of the sector angle is more useful. % \pgfmathmod{\angle}{360}% \ifdim\pgfmathresult pt<0pt\relax% \pgfmathadd@{\pgfmathresult}{360}% \fi% \let\angle\pgfmathresult% \pgfmathdivide@{\pgfmathresult}{2}% \let\halfangle\pgfmathresult% % % Get the start and end angles of the arc. % \iftikz@optics@sphericalmirror@concave \iftikz@optics@sphericalmirror@ltr \pgfmathsetmacro\startangle{-\halfangle} \pgfmathsetmacro\endangle{+\halfangle} \else \pgfmathsetmacro\startangle{180-\halfangle} \pgfmathsetmacro\endangle{180+\halfangle} \fi \else \iftikz@optics@sphericalmirror@ltr \pgfmathsetmacro\startangle{180-\halfangle} \pgfmathsetmacro\endangle{180+\halfangle} \else \pgfmathsetmacro\startangle{-\halfangle} \pgfmathsetmacro\endangle{+\halfangle} \fi \fi % % Calculate R cos(angle/2) and R sin(angle/2) % \pgfmathabs@{\halfangle}% \pgfmathcos@{\pgfmathresult}% \let\coshalfangle\pgfmathresult% \pgfmathabs@{\halfangle}% \pgfmathsin@{\pgfmathresult}% \let\sinhalfangle\pgfmathresult% \pgfmathsetlength\pgf@xa{\radius*\coshalfangle} \edef\rcoshalfangle{\the\pgf@xa}% \pgfmathsetlength\pgf@xa{\radius*\sinhalfangle} \edef\rsinhalfangle{\the\pgf@xa}% % % Calculate the arc coordinates % \pgfextract@process\arcstart{% \pgfqpointpolar{\startangle}{\radius}% \pgf@xa\pgf@x% \pgf@ya\pgf@y% \centerpoint% \advance\pgf@x\pgf@xa% \advance\pgf@y\pgf@ya% }% \pgfextract@process\arcend{% \pgfqpointpolar{\endangle}{\radius}% \pgf@xa\pgf@x% \pgf@ya\pgf@y% \centerpoint% \advance\pgf@x\pgf@xa% \advance\pgf@y\pgf@ya% }% \def\convexrtlsetx#1#2{ \iftikz@optics@sphericalmirror@concave% \iftikz@optics@sphericalmirror@ltr% \advance\pgf@x by #1 \else% % => rtl \advance\pgf@x by #2 \fi% \else% % => convex \iftikz@optics@sphericalmirror@ltr% \advance\pgf@x by #2 \else% % => rtl \advance\pgf@x by #1 \fi% \fi% } \def\convexrtlinvert{% \iftikz@optics@sphericalmirror@concave% \iftikz@optics@sphericalmirror@ltr% %nothing \else% % => rtl \pgf@x=-\pgf@x% \fi% \else% % => convex \iftikz@optics@sphericalmirror@ltr% \pgf@x=-\pgf@x% \else% % => rtl %nothing \fi% \fi% }% % % Save everything. % "NB \addtosavedmacro is currently experimental. May get changed." d'après le code où je l'ai piqué % \addtosavedmacro{\radius}% % \addtosavedmacro{\rcoshalfangle}% \addtosavedmacro{\rsinhalfangle}% % \addtosavedmacro{\endangle}% \addtosavedmacro{\startangle}% % \addtosavedmacro{\centerpoint}% \addtosavedmacro{\arcstart}% \addtosavedmacro{\arcend}% \addtosavedmacro{\convexrtlinvert}% % }% % % Define anchors % \savedanchor\mirrorcenterpoint{% \pgfpointorigin }% \savedanchor\centerpoint{% \pgfpointorigin% \advance\pgf@x by \radius% \advance\pgf@x by \rcoshalfangle% \iftikz@optics@sphericalmirror@concave% \iftikz@optics@sphericalmirror@ltr% %nothing \else% % => rtl \pgf@x=-\pgf@x% \fi% \else% % => convex \iftikz@optics@sphericalmirror@ltr% \pgf@x=-\pgf@x% \else% % => rtl %nothing \fi% \fi% \divide\pgf@x by 2% }% \savedanchor\focalpoint{% \pgfpointorigin% \pgf@xa=\radius% \advance\pgf@x by .5\pgf@xa% \iftikz@optics@sphericalmirror@concave% \iftikz@optics@sphericalmirror@ltr% %nothing \else% % => rtl \pgf@x=-\pgf@x% \fi% \else% % => convex \iftikz@optics@sphericalmirror@ltr% \pgf@x=-\pgf@x% \else% % => rtl %nothing \fi% \fi% }% \savedanchor\north{% \pgfpointorigin \pgf@xa=0pt \advance\pgf@xa by \rcoshalfangle \advance\pgf@xa by \radius \divide\pgf@xa by 2 \advance\pgf@x by \pgf@xa \advance\pgf@y by \rsinhalfangle \convexrtlinvert }% \savedanchor\arccenter{% \centerpoint \advance\pgf@x by \radius \convexrtlinvert } \savedanchor\south{% \pgfpointorigin \pgf@xa=0pt \advance\pgf@xa by \rcoshalfangle \advance\pgf@xa by \radius \divide\pgf@xa by 2 \advance\pgf@x by \pgf@xa \advance\pgf@y by -\rsinhalfangle \convexrtlinvert } \savedanchor\east{% \pgfpointorigin \convexrtlsetx{\radius}{\rcoshalfangle} \convexrtlinvert } \savedanchor\west{% \pgfpointorigin \convexrtlsetx{\rcoshalfangle}{\radius} \convexrtlinvert } \savedanchor\northwest{% \pgfpointorigin \convexrtlsetx{\rcoshalfangle}{\radius} \advance\pgf@y by \rsinhalfangle \convexrtlinvert } \savedanchor\southwest{% \pgfpointorigin \convexrtlsetx{\rcoshalfangle}{\radius} \advance\pgf@y by -\rsinhalfangle \convexrtlinvert } \savedanchor\northeast{% \pgfpointorigin \convexrtlsetx{\radius}{\rcoshalfangle} \advance\pgf@y by \rsinhalfangle \convexrtlinvert } \savedanchor\southeast{% \pgfpointorigin \convexrtlsetx{\radius}{\rcoshalfangle} \advance\pgf@y by -\rsinhalfangle \convexrtlinvert } \anchor{arc start}{% \installsphericalmirrorparameters% \arcstart% } \anchor{arc end}{% \installsphericalmirrorparameters% \arcend% } \anchor{focal point}{% \installsphericalmirrorparameters% \focalpoint } \anchor{focus}{% \installsphericalmirrorparameters% \focalpoint } \anchor{mirror center}{\mirrorcenterpoint} \anchor{center}{\centerpoint} \anchor{arc center}{\arccenter} \anchor{north}{\north}% \anchor{south}{\south}% \anchor{east}{\east}% \anchor{west}{\west}% \anchor{north west}{\northwest}% \anchor{south west}{\southwest}% \anchor{north east}{\northeast}% \anchor{south east}{\southeast}% % % Draw backgroundpath % \backgroundpath{% \installsphericalmirrorparameters% % We use a border decoration to make a mirror. % First set the decoration parameters : % - decoration angle \iftikz@optics@sphericalmirror@concave \def\pgfdecorationsegmentangle{45}% \else \def\pgfdecorationsegmentangle{-90-45}% \fi % - decoration step length \pgfmathparse{\pgfkeysvalueof{/tikz/optics/mirror decoration separation}} \ifpgfmathunitsdeclared% \pgfmathsetlengthmacro{\pgfdecorationsegmentlength}{\pgfkeysvalueof{/tikz/optics/mirror decoration separation}}% \else% \pgfmathsetlengthmacro{\pgfdecorationsegmentlength}{\pgfkeysvalueof{/tikz/optics/mirror decoration separation}*\pgfkeysvalueof{/tikz/optics/object height}}% \fi% % magouillons pour que \pgfdecorationsegmentlength soit un multiple de la longueur ... \pgfmathsetmacro\initialstep{\pgfdecorationsegmentlength} \pgfmathsetmacro\totallength{(2*pi/360)*\angle*\radius} \pgfmathsetmacro\newstep{\totallength/floor(\totallength/\initialstep)} \pgfmathsetlengthmacro{\pgfdecorationsegmentlength}{\newstep} % fin magouille % - decoration amplitude % on multiplie par -1 pour que ça aille dans le bon sens sans devoir modifier l'angle (pour éviter des problèmes louches) \pgfmathparse{\pgfkeysvalueof{/tikz/optics/mirror decoration amplitude}} \ifpgfmathunitsdeclared% \pgfmathsetlengthmacro{\pgfdecorationsegmentamplitude}{-1*\pgfkeysvalueof{/tikz/optics/mirror decoration amplitude}}% \else% \pgfmathsetlengthmacro{\pgfdecorationsegmentamplitude}{-1*\pgfkeysvalueof{/tikz/optics/mirror decoration amplitude}*\pgfkeysvalueof{/tikz/optics/object height}}% \fi% % Now use decoration. % Draw decoration of path : an arc of radius \radius from \arcstart to \arcend \pgfpathmoveto{\arcstart}% \pgfpatharc{\startangle}{\endangle}{\radius}% \pgfdecoratecurrentpath{border} % % Now draw the path. \pgfpathmoveto{\arcstart}% \pgfpatharc{\startangle}{\endangle}{\radius}% } % % Anchor border % This is needed for anchors . (like mirror.0, mirror.90, etc.) to work. % \anchorborder{% % Save x and y \edef\externalx{\the\pgf@x}% \edef\externaly{\the\pgf@y}% \installsphericalmirrorparameters% % Use circular border \pgfpointborderellipse{ \pgfpoint{\externalx}{\externaly} }{ \pgfpoint{\radius}{\radius} }% }% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Shape [thick optics element] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % keys : % - object aspect ratio (alias : object width) % ar = largeur/hauteur => largeur = ar * hauteur \pgfkeys{/tikz/optics/.cd, object aspect ratio/.initial=0.2, object width/.style={/tikz/optics/object aspect ratio=#1} } \pgfdeclareshape{thick optics element} { \savedanchor{\center}{ \pgfpointorigin } \anchor{center}{\center} \savedmacro\objectHeight{% \edef\objectHeight{\pgfkeysvalueof{/tikz/optics/object height}}% } \savedmacro\objectWidth{% \pgfmathparse{\pgfkeysvalueof{/tikz/optics/object aspect ratio}} \ifpgfmathunitsdeclared% \pgfmathsetlengthmacro{\objectWidth}{\pgfkeysvalueof{/tikz/optics/object aspect ratio}}% \else% \pgfmathsetlengthmacro{\objectWidth}{\pgfkeysvalueof{/tikz/optics/object aspect ratio}*\pgfkeysvalueof{/tikz/optics/object height}}% \fi% } \savedanchor{\northeast}{ \pgf@x=\objectWidth% \pgf@y=\objectHeight% \pgf@y=0.5\pgf@y% \pgf@x=0.5\pgf@x% } \anchor{north east}{\northeast} \savedanchor{\southwest}{ \pgf@x=\objectWidth% \pgf@y=\objectHeight% \pgf@y=-0.5\pgf@y% \pgf@x=-0.5\pgf@x% } \anchor{south west}{\southwest} \anchor{north}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } \anchor{south}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \southwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } \anchor{east}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xb \pgf@y=\pgf@ya } \anchor{west}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \southwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xb \pgf@y=\pgf@ya } \anchor{north west}{ \northeast \pgf@xa=\pgf@x \pgf@ya=\pgf@y \southwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xb \pgf@y=\pgf@ya } \anchor{south east}{ \northeast \pgf@xa=\pgf@x \pgf@ya=\pgf@y \southwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } \inheritanchorborder[from=rectangle] \backgroundpath { % rectangle \pgfpathrectanglecorners{\northeast}{\southwest} } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Shape [polarizer] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \pgfdeclareshape{polarizer} { \savedanchor{\center}{ \pgfpointorigin } \anchor{center}{\center} \savedmacro\objectHeight{% \edef\objectHeight{\pgfkeysvalueof{/tikz/optics/object height}}% } \savedmacro\objectWidth{% \pgfmathparse{\pgfkeysvalueof{/tikz/optics/object aspect ratio}} \ifpgfmathunitsdeclared% \pgfmathsetlengthmacro{\objectWidth}{\pgfkeysvalueof{/tikz/optics/object aspect ratio}}% \else% \pgfmathsetlengthmacro{\objectWidth}{\pgfkeysvalueof{/tikz/optics/object aspect ratio}*\pgfkeysvalueof{/tikz/optics/object height}}% \fi% } \savedanchor{\northeast}{ \pgf@x=\objectWidth% \pgf@y=\objectHeight% \pgf@y=0.5\pgf@y% \pgf@x=0.5\pgf@x% } \anchor{north east}{\northeast} \savedanchor{\southwest}{ \pgf@x=\objectWidth% \pgf@y=\objectHeight% \pgf@y=-0.5\pgf@y% \pgf@x=-0.5\pgf@x% } \anchor{south west}{\southwest} \anchor{north}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } \anchor{south}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \southwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } \anchor{east}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xb \pgf@y=\pgf@ya } \anchor{west}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \southwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xb \pgf@y=\pgf@ya } \anchor{north west}{ \northeast \pgf@xa=\pgf@x \pgf@ya=\pgf@y \southwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xb \pgf@y=\pgf@ya } \anchor{south east}{ \northeast \pgf@xa=\pgf@x \pgf@ya=\pgf@y \southwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } \inheritanchorborder[from=rectangle] \backgroundpath { % rectangle \pgfpathrectanglecorners{\northeast}{\southwest} % diagonale du polariseur \northeast \pgf@xa=\pgf@x \pgf@ya=\pgf@y \southwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}} \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}} } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Shape [double amici prism] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % keys : % - prism height % - prism apex angle \pgfkeys{/tikz/optics/.cd, prism height/.initial=1.5cm, prism apex angle/.initial=60, } % Idea : we get % apexAngle % prismHeight % demiPrismWidth = tan(apexAngle/2)*prismHeight % % so we compute % % C = (0,0) % NE = (demiPrismWidth,0.5*prismHeight) % SW = (-2*demiPrismWidth,-0.5*prismHeight) % NW = (-demiPrismWidth,0.5*prismHeight) % SE = (2*demiPrismWidth,-0.5*prismHeight) % % N = (0,0.5*prismHeight) % S = (0,-0.5*prismHeight) % E = (3*0.5*demiPrismWidth,0) % W = (-3.0.5*demiPrismWidth,0) \pgfdeclareshape{double amici prism} { \savedanchor{\center}{ \pgfpointorigin } \anchor{center}{\center} \savedmacro\prismHeight{% \edef\prismHeight{\pgfkeysvalueof{/tikz/optics/prism height}}% } \savedmacro\apexAngle{% \pgfmathsetlengthmacro{\apexAngle}{\pgfkeysvalueof{/tikz/optics/prism apex angle}} } \savedmacro\demiPrismWidth{% \pgfmathsetlengthmacro{\demiPrismWidth}{tan(0.5*\pgfkeysvalueof{/tikz/optics/prism apex angle})*\pgfkeysvalueof{/tikz/optics/prism height}} } \savedanchor{\northeast}{ \pgf@x=\demiPrismWidth% \pgf@y=\prismHeight% \pgf@y=0.5\pgf@y% } \anchor{north east}{\northeast} \savedanchor{\southwest}{ \pgf@x=\demiPrismWidth% \pgf@y=\prismHeight% \pgf@x=-2\pgf@x% \pgf@y=-0.5\pgf@y% } \anchor{south west}{\southwest} \savedanchor{\northwest}{ \pgf@x=\demiPrismWidth% \pgf@y=\prismHeight% \pgf@x=-\pgf@x% \pgf@y=0.5\pgf@y% } \anchor{north west}{\northwest} \savedanchor{\southeast}{ \pgf@x=\demiPrismWidth% \pgf@y=\prismHeight% \pgf@x=2\pgf@x% \pgf@y=-0.5\pgf@y% } \anchor{south east}{\southeast} \anchor{north}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } \savedanchor{\south}{ \pgfpointorigin \pgf@y=\prismHeight% \pgf@y=-0.5\pgf@y% } \anchor{south}{\south} \anchor{east}{ \southeast \pgf@xa=\pgf@x \pgf@ya=\pgf@y \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \advance\pgf@x by\pgf@xb \pgf@x=0.5\pgf@x \pgf@y=\pgf@ya \advance\pgf@y by\pgf@yb \pgf@y=0.5\pgf@y } \anchor{west}{ \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y \northwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \advance\pgf@x by\pgf@xb \pgf@x=0.5\pgf@x \pgf@y=\pgf@ya \advance\pgf@y by\pgf@yb \pgf@y=0.5\pgf@y } \inheritanchorborder[from=rectangle] \backgroundpath { \northwest \pgfpathmoveto{\pgfpoint{\pgf@x}{\pgf@y}} \southwest \pgfpathlineto{\pgfpoint{\pgf@x}{\pgf@y}} \southeast \pgfpathlineto{\pgfpoint{\pgf@x}{\pgf@y}} \northeast \pgfpathlineto{\pgfpoint{\pgf@x}{\pgf@y}} \pgfpathclose % % FIXME : ceci devrait s'appliquer seulement au triangle intérieur -> un fgpath ou assimilé \pgfsetbeveljoin \northwest \pgfpathmoveto{\pgfpoint{\pgf@x}{\pgf@y}} \south \pgfpathlineto{\pgfpoint{\pgf@x}{\pgf@y}} \northeast \pgfpathlineto{\pgfpoint{\pgf@x}{\pgf@y}} } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Shape [generic optics io] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % keys : % - io body height : height of the body of the io body % - io body aspect ratio (alias io body width) : width/height of the body of the io body % - io aperture width : width of the output device (condenser, etc.) [in units of io body height] % - io aperture height : height of the output device (condenser, etc.) [in units of io body height] % - io aperture shift : vertical shift of the output device [in units of io body height] % - io orientation (ltr or rtl) \pgfkeys{/tikz/optics/.cd, io body height/.initial=0.75cm, io body aspect ratio/.initial=2, io aperture width/.initial=0.33, io aperture height/.initial=0.66, io aperture shift/.initial=0, } \pgfkeys{/tikz/optics/io body width/.style={/tikz/optics/io body aspect ratio=#1}} % \newif\if@tikz@optics@io@ltr \@tikz@optics@io@ltrtrue % \pgfkeys{/tikz/optics/io orientation/.is choice} \pgfkeys{/tikz/optics/io orientation/ltr/.code={\@tikz@optics@io@ltrtrue}} \pgfkeys{/tikz/optics/io orientation/rtl/.code={\@tikz@optics@io@ltrfalse}} % \pgfdeclareshape{generic optics io} { \savedanchor{\center}{ \pgfpointorigin } \anchor{center}{\center} \savedmacro\objectHeight{% \edef\objectHeight{\pgfkeysvalueof{/tikz/optics/io body height}}% } \savedmacro\objectWidth{% \pgfmathparse{\pgfkeysvalueof{/tikz/optics/io body aspect ratio}} \ifpgfmathunitsdeclared% \pgfmathsetlengthmacro{\objectWidth}{\pgfkeysvalueof{/tikz/optics/io body aspect ratio}}% \else% \pgfmathsetlengthmacro{\objectWidth}{\pgfkeysvalueof{/tikz/optics/io body aspect ratio}*\pgfkeysvalueof{/tikz/optics/io body height}}% \fi% } \savedmacro\outHeight{% \pgfmathparse{\pgfkeysvalueof{/tikz/optics/io aperture height}} \ifpgfmathunitsdeclared% \pgfmathsetlengthmacro{\outHeight}{\pgfkeysvalueof{/tikz/optics/io aperture height}}% \else% \pgfmathsetlengthmacro{\outHeight}{\pgfkeysvalueof{/tikz/optics/io aperture height}*\pgfkeysvalueof{/tikz/optics/io body height}}% \fi% } \savedmacro\outWidth{% \pgfmathparse{\pgfkeysvalueof{/tikz/optics/io aperture width}} \ifpgfmathunitsdeclared% \pgfmathsetlengthmacro{\outWidth}{\pgfkeysvalueof{/tikz/optics/io aperture width}}% \else% \pgfmathsetlengthmacro{\outWidth}{\pgfkeysvalueof{/tikz/optics/io aperture width}*\pgfkeysvalueof{/tikz/optics/io body height}}% \fi% } \savedmacro\outShift{% \pgfmathparse{\pgfkeysvalueof{/tikz/optics/io aperture shift}} \ifpgfmathunitsdeclared% \pgfmathsetlengthmacro{\outShift}{\pgfkeysvalueof{/tikz/optics/io aperture shift}}% \else% \pgfmathsetlengthmacro{\outShift}{\pgfkeysvalueof{/tikz/optics/io aperture shift}*\pgfkeysvalueof{/tikz/optics/io body height}}% \fi% } \savedanchor{\bodynortheast}{ \pgf@x=\objectWidth% \pgf@y=\objectHeight% \pgf@y=0.5\pgf@y% \pgf@x=0.5\pgf@x% } \anchor{body north east}{\bodynortheast} \savedanchor{\bodysouthwest}{ \pgf@x=\objectWidth% \pgf@y=\objectHeight% \pgf@y=-0.5\pgf@y% \pgf@x=-0.5\pgf@x% } \anchor{body south west}{\bodysouthwest} \savedanchor{\outnortheast}{ \if@tikz@optics@io@ltr % Left To Right (LTR) \pgf@x=\objectWidth% \pgf@x=0.5\pgf@x% \advance\pgf@x by\outWidth \else % Right To Left (RTL) \pgf@x=\objectWidth% \pgf@x=0.5\pgf@x% \pgf@x=-\pgf@x% \fi \pgf@y=0pt% \advance\pgf@y by\outHeight \pgf@y=0.5\pgf@y% \advance\pgf@y by\outShift } \anchor{aperture north east}{\outnortheast} \savedanchor{\outsouthwest}{ \if@tikz@optics@io@ltr % Left To Right (LTR) \pgf@x=\objectWidth% \pgf@x=0.5\pgf@x% \else % Right To Left (RTL) \pgf@x=\objectWidth% \pgf@x=0.5\pgf@x% \advance\pgf@x by\outWidth \pgf@x=-\pgf@x% \fi \pgf@y=0pt% \advance\pgf@y by\outHeight \pgf@y=-0.5\pgf@y% \advance\pgf@y by\outShift } \anchor{aperture south west}{\outsouthwest} \savedanchor{\outcenter}{ \if@tikz@optics@io@ltr % Left To Right (LTR) \pgf@x=\objectWidth% \advance\pgf@x by\outWidth \else % Right To Left (RTL) \pgf@x=\objectWidth% \advance\pgf@x by\outWidth \pgf@x=-\pgf@x% \fi \pgf@x=0.5\pgf@x% \pgf@y=0pt% \advance\pgf@y by\outShift } \anchor{aperture center}{\outcenter} \anchor{body center}{\center} \anchor{text}{ \pgfpointorigin \advance\pgf@x by -.5\wd\pgfnodeparttextbox% \advance\pgf@y by -.5\ht\pgfnodeparttextbox% \advance\pgf@y by +.5\dp\pgfnodeparttextbox% } \anchor{body north}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \bodynortheast \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } % north = body north \anchor{north}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \bodynortheast \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } \anchor{body south}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \bodysouthwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } % south = body south \anchor{south}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \bodysouthwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } \anchor{body east}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \bodynortheast \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xb \pgf@y=\pgf@ya } \anchor{body west}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \bodysouthwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xb \pgf@y=\pgf@ya } \anchor{body north west}{ \bodynortheast \pgf@xa=\pgf@x \pgf@ya=\pgf@y \bodysouthwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xb \pgf@y=\pgf@ya } \anchor{body south east}{ \bodynortheast \pgf@xa=\pgf@x \pgf@ya=\pgf@y \bodysouthwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } \anchor{aperture north}{ \outcenter \pgf@xa=\pgf@x \pgf@ya=\pgf@y \outnortheast \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } \anchor{aperture south}{ \outcenter \pgf@xa=\pgf@x \pgf@ya=\pgf@y \outsouthwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } \anchor{aperture east}{ \outcenter \pgf@xa=\pgf@x \pgf@ya=\pgf@y \outnortheast \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xb \pgf@y=\pgf@ya } \anchor{aperture west}{ \outcenter \pgf@xa=\pgf@x \pgf@ya=\pgf@y \outsouthwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xb \pgf@y=\pgf@ya } \anchor{aperture north west}{ \outnortheast \pgf@xa=\pgf@x \pgf@ya=\pgf@y \outsouthwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xb \pgf@y=\pgf@ya } \anchor{aperture south east}{ \outnortheast \pgf@xa=\pgf@x \pgf@ya=\pgf@y \outsouthwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } \anchor{center}{\center} \savedanchor{\realeast}{ \pgfpointorigin \if@tikz@optics@io@ltr % Left To Right (LTR) %ltr : aperture east (<- out north east) \pgf@x=\objectWidth% \pgf@x=0.5\pgf@x% \advance\pgf@x by\outWidth %\pgf@y=0pt% \else % Right To Left (rtl) \pgf@x=\objectWidth% \pgf@x=0.5\pgf@x% \fi } \anchor{east}{\realeast} \savedanchor{\realwest}{ \pgfpointorigin \if@tikz@optics@io@ltr % Left To Right (LTR) \pgf@x=\objectWidth% \pgf@x=-0.5\pgf@x% \else % Right To Left (rtl) \pgf@x=\objectWidth% \pgf@x=0.5\pgf@x% \advance\pgf@x by\outWidth \pgf@x=-\pgf@x% \fi } \anchor{west}{\realwest} % this is used only for the anchorborder \savedanchor{\anchorbordersouthwest}{ \if@tikz@optics@io@ltr % Left To Right (LTR) \pgf@x=\objectWidth% \pgf@x=-0.5\pgf@x% \else % Right To Left (rtl) \pgf@x=\objectWidth% \pgf@x=0.5\pgf@x% \advance\pgf@x by\outWidth \pgf@x=-\pgf@x% \fi \pgf@y=\objectHeight% \pgf@y=-0.5\pgf@y% } % this is used only for the anchorborder \savedanchor{\anchorbordernortheast}{ \if@tikz@optics@io@ltr % Left To Right (LTR) \pgf@x=\objectWidth% \pgf@x=0.5\pgf@x% \advance\pgf@x by\outWidth \else % Right To Left (RTL) \pgf@x=\objectWidth% \pgf@x=0.5\pgf@x% %\pgf@x=-\pgf@x% \fi \pgf@y=\objectHeight% \pgf@y=0.5\pgf@y% } % anchorborder % c'est celui de rectangle, mais un peu ajusté \anchorborder{% \pgf@xb=\pgf@x% xb/yb is target \pgf@yb=\pgf@y% \anchorbordersouthwest% \pgf@xa=\pgf@x% xa/ya is se \pgf@ya=\pgf@y% \anchorbordernortheast% \advance\pgf@x by-\pgf@xa% \advance\pgf@y by-\pgf@ya% \pgf@xc=.5\pgf@x% x/y is half width/height \pgf@yc=.5\pgf@y% \advance\pgf@xa by\pgf@xc% xa/ya becomes center \advance\pgf@ya by\pgf@yc% \edef\pgf@marshal{% \noexpand\pgfpointborderrectangle {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}} {\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}% }% \pgf@process{\pgf@marshal}% % \advance\pgf@x by\pgf@xa% % \advance\pgf@y by\pgf@ya% } \backgroundpath { % corps \pgfpathrectanglecorners{\bodynortheast}{\bodysouthwest} % out \pgfpathrectanglecorners{\outnortheast}{\outsouthwest} %\pgfusepath{draw} % il ne faut PAS mettre ça pour pouvoir utiliser des styles correctement après (genre double) } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Sensors %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Shape [sensor line] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Sensor line. % % This defines anchors center, north, south, east, west, north east % north west, south east, south west, as well as % pixel with is any of the former. % ça va être horrible à faire % % keys : % - sensor line height % - sensor line aspect ratio (largeur en unités de la hauteur du capteur) % - sensor line pixel number % - sensor line pixel width (en unités de la largeur du capteur) % - sensor line inner ysep (en unités de la hauteur du capteur) \pgfkeys{/tikz/optics/.cd, sensor line height/.initial=2cm, sensor line aspect ratio/.initial=0.2, sensor line pixel number/.initial=5, sensor line pixel width/.initial=0.4, sensor line inner ysep/.initial=0.05, % entre le bord et les capteurs } \pgfdeclareshape{sensor line} { \savedanchor{\center}{ \pgfpointorigin } \anchor{center}{\center} \savedmacro\objectHeight{% \edef\objectHeight{\pgfkeysvalueof{/tikz/optics/sensor line height}}% } \savedmacro\objectWidth{% \pgfmathsetlengthmacro{\objectWidth}{\pgfkeysvalueof{/tikz/optics/sensor line aspect ratio}*\pgfkeysvalueof{/tikz/optics/sensor line height}} } \savedmacro\pixelNumber{% \pgfmathtruncatemacro\pixelNumber{\pgfkeysvalueof{/tikz/optics/sensor line pixel number}}% } \savedmacro\innerysep{% \pgfmathparse{\pgfkeysvalueof{/tikz/optics/sensor line inner ysep}} \ifpgfmathunitsdeclared% \pgfmathsetlengthmacro{\innerysep}{\pgfkeysvalueof{/tikz/optics/sensor line inner ysep}}% \else% \pgfmathsetlengthmacro{\innerysep}{\pgfkeysvalueof{/tikz/optics/sensor line inner ysep}*\pgfkeysvalueof{/tikz/optics/sensor line height}}% \fi% } \savedmacro\pixelWidth{% \pgfmathparse{\pgfkeysvalueof{/tikz/optics/sensor line pixel width}} \ifpgfmathunitsdeclared% \pgfmathsetlengthmacro{\pixelWidth}{\pgfkeysvalueof{/tikz/optics/sensor line pixel width}}% \else% \pgfmathsetlengthmacro{\pixelWidth}{\pgfkeysvalueof{/tikz/optics/sensor line pixel width}*\objectWidth}% \fi% } \savedmacro\pixelHeight{% \pgfmathparse{(\objectHeight-2*\innerysep)/\pixelNumber} \edef\pixelHeight{\pgfmathresult pt}% } \savedanchor{\northeast}{ \pgf@x=\objectWidth% \pgf@y=\objectHeight% \pgf@y=0.5\pgf@y% \pgf@x=0.5\pgf@x% } \anchor{north east}{\northeast} \savedanchor{\southwest}{ \pgf@x=\objectWidth% \pgf@y=\objectHeight% \pgf@y=-0.5\pgf@y% \pgf@x=-0.5\pgf@x% } \anchor{south west}{\southwest} \anchor{north}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } \anchor{south}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \southwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } \anchor{east}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xb \pgf@y=\pgf@ya } \anchor{west}{ \center \pgf@xa=\pgf@x \pgf@ya=\pgf@y \southwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xb \pgf@y=\pgf@ya } \anchor{north west}{ \northeast \pgf@xa=\pgf@x \pgf@ya=\pgf@y \southwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xb \pgf@y=\pgf@ya } \anchor{south east}{ \northeast \pgf@xa=\pgf@x \pgf@ya=\pgf@y \southwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y \pgf@x=\pgf@xa \pgf@y=\pgf@yb } % ok, idée : % HAUT (north) du pixel n (allant de 1 à N) % \objectHeight/2 - \innerysep - (n-1) * \pixelHeight % BAS (south) du pixel n % \objectHeight/2 - \innerysep - n * \pixelHeight % west = le même que la boite, donc utiliser \southwest % east = west + \pixelWidth % Le but de ce code est de définir des ancres % pixel % pour = 4, 2, ..., \pixelNumber % et = north, south, east, west, north west, south west, north east south east, center % Comme \pixelNumber est défini dynamiquement, il faut passer par cette horreur. % Le code est inspiré de pfglibraryshapes.geometric.code.tex (shape regular polygon). \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@sensor line\endcsname{% \c@pgf@counta\pixelNumber\relax% \pgfmathloop% \ifnum\c@pgf@counta>0\relax% \pgfutil@ifundefined{pgf@anchor@sensor line@pixel\space\the\c@pgf@counta\space north west}{% % % ...(manually \xdef as \gdef is normally used by \anchor)... % % % pixel surface north \expandafter\xdef\csname pgf@anchor@sensor line@pixel\space\the\c@pgf@counta\space north\endcsname{% \noexpand\northeast \noexpand\pgf@xa=\noexpand\pgf@x \noexpand\pgf@ya=\noexpand\pgf@y \noexpand\southwest \noexpand\pgf@xb=\noexpand\pgf@x \noexpand\pgf@yb=\noexpand\pgf@y \noexpand\pgf@x=\noexpand\pixelWidth \noexpand\pgf@x=.5\noexpand\pgf@x \noexpand\advance\noexpand\pgf@x by\noexpand\pgf@xb \noexpand\pgf@y=\noexpand\pgf@ya \noexpand\newdimen\noexpand\temp@y \noexpand\pgfmathsetlength\noexpand\temp@y{(\the\c@pgf@counta-\noexpand\pixelNumber)*\noexpand\pixelHeight-\noexpand\innerysep} \noexpand\advance\noexpand\pgf@y by\noexpand\temp@y }% % % % pixel surface north east \expandafter\xdef\csname pgf@anchor@sensor line@pixel\space\the\c@pgf@counta\space north east\endcsname{% \noexpand\northeast \noexpand\pgf@xa=\noexpand\pgf@x \noexpand\pgf@ya=\noexpand\pgf@y \noexpand\southwest \noexpand\pgf@xb=\noexpand\pgf@x \noexpand\pgf@yb=\noexpand\pgf@y \noexpand\pgf@x=\noexpand\pixelWidth \noexpand\advance\noexpand\pgf@x by\noexpand\pgf@xb \noexpand\pgf@y=\noexpand\pgf@ya \noexpand\newdimen\noexpand\temp@y \noexpand\pgfmathsetlength\noexpand\temp@y{(\the\c@pgf@counta-\noexpand\pixelNumber)*\noexpand\pixelHeight-\noexpand\innerysep} \noexpand\advance\noexpand\pgf@y by\noexpand\temp@y }% % % % pixel surface north west \expandafter\xdef\csname pgf@anchor@sensor line@pixel\space\the\c@pgf@counta\space north west\endcsname{% \noexpand\northeast \noexpand\pgf@xa=\noexpand\pgf@x \noexpand\pgf@ya=\noexpand\pgf@y \noexpand\southwest \noexpand\pgf@xb=\noexpand\pgf@x \noexpand\pgf@yb=\noexpand\pgf@y \noexpand\pgf@x=\noexpand\pgf@xb \noexpand\pgf@y=\noexpand\pgf@ya \noexpand\newdimen\noexpand\temp@y \noexpand\pgfmathsetlength\noexpand\temp@y{(\the\c@pgf@counta-\noexpand\pixelNumber)*\noexpand\pixelHeight-\noexpand\innerysep} \noexpand\advance\noexpand\pgf@y by\noexpand\temp@y }% % % % pixel surface south \expandafter\xdef\csname pgf@anchor@sensor line@pixel\space\the\c@pgf@counta\space south\endcsname{% \noexpand\northeast \noexpand\pgf@xa=\noexpand\pgf@x \noexpand\pgf@ya=\noexpand\pgf@y \noexpand\southwest \noexpand\pgf@xb=\noexpand\pgf@x \noexpand\pgf@yb=\noexpand\pgf@y \noexpand\pgf@x=\noexpand\pixelWidth \noexpand\pgf@x=.5\noexpand\pgf@x \noexpand\advance\noexpand\pgf@x by\noexpand\pgf@xb \noexpand\pgf@y=\noexpand\pgf@ya \noexpand\newdimen\noexpand\temp@y \noexpand\pgfmathsetlength\noexpand\temp@y{(\the\c@pgf@counta-\noexpand\pixelNumber-1)*\noexpand\pixelHeight-\noexpand\innerysep} \noexpand\advance\noexpand\pgf@y by\noexpand\temp@y }% % % % pixel surface south east \expandafter\xdef\csname pgf@anchor@sensor line@pixel\space\the\c@pgf@counta\space south east\endcsname{% \noexpand\northeast \noexpand\pgf@xa=\noexpand\pgf@x \noexpand\pgf@ya=\noexpand\pgf@y \noexpand\southwest \noexpand\pgf@xb=\noexpand\pgf@x \noexpand\pgf@yb=\noexpand\pgf@y \noexpand\pgf@x=\noexpand\pixelWidth \noexpand\advance\noexpand\pgf@x by\noexpand\pgf@xb \noexpand\pgf@y=\noexpand\pgf@ya \noexpand\newdimen\noexpand\temp@y \noexpand\pgfmathsetlength\noexpand\temp@y{(\the\c@pgf@counta-\noexpand\pixelNumber-1)*\noexpand\pixelHeight-\noexpand\innerysep} \noexpand\advance\noexpand\pgf@y by\noexpand\temp@y }% % % % pixel surface south west \expandafter\xdef\csname pgf@anchor@sensor line@pixel\space\the\c@pgf@counta\space south west\endcsname{% \noexpand\northeast \noexpand\pgf@xa=\noexpand\pgf@x \noexpand\pgf@ya=\noexpand\pgf@y \noexpand\southwest \noexpand\pgf@xb=\noexpand\pgf@x \noexpand\pgf@yb=\noexpand\pgf@y \noexpand\pgf@x=\noexpand\pgf@xb \noexpand\pgf@y=\noexpand\pgf@ya \noexpand\newdimen\noexpand\temp@y \noexpand\pgfmathsetlength\noexpand\temp@y{(\the\c@pgf@counta-\noexpand\pixelNumber-1)*\noexpand\pixelHeight-\noexpand\innerysep} \noexpand\advance\noexpand\pgf@y by\noexpand\temp@y }% % % % pixel surface east \expandafter\xdef\csname pgf@anchor@sensor line@pixel\space\the\c@pgf@counta\space east\endcsname{% \noexpand\northeast \noexpand\pgf@xa=\noexpand\pgf@x \noexpand\pgf@ya=\noexpand\pgf@y \noexpand\southwest \noexpand\pgf@xb=\noexpand\pgf@x \noexpand\pgf@yb=\noexpand\pgf@y \noexpand\pgf@x=\noexpand\pixelWidth \noexpand\advance\noexpand\pgf@x by\noexpand\pgf@xb \noexpand\pgf@y=\noexpand\pgf@ya \noexpand\newdimen\noexpand\temp@y \noexpand\pgfmathsetlength\noexpand\temp@y{(\the\c@pgf@counta-\noexpand\pixelNumber-0.5)*\noexpand\pixelHeight-\noexpand\innerysep} \noexpand\advance\noexpand\pgf@y by\noexpand\temp@y }% % % % pixel surface center \expandafter\xdef\csname pgf@anchor@sensor line@pixel\space\the\c@pgf@counta\space center\endcsname{% \noexpand\northeast \noexpand\pgf@xa=\noexpand\pgf@x \noexpand\pgf@ya=\noexpand\pgf@y \noexpand\southwest \noexpand\pgf@xb=\noexpand\pgf@x \noexpand\pgf@yb=\noexpand\pgf@y \noexpand\pgf@x=\noexpand\pixelWidth \noexpand\pgf@x=.5\noexpand\pgf@x \noexpand\advance\noexpand\pgf@x by\noexpand\pgf@xb \noexpand\pgf@y=\noexpand\pgf@ya \noexpand\newdimen\noexpand\temp@y \noexpand\pgfmathsetlength\noexpand\temp@y{(\the\c@pgf@counta-\noexpand\pixelNumber-0.5)*\noexpand\pixelHeight-\noexpand\innerysep} \noexpand\advance\noexpand\pgf@y by\noexpand\temp@y }% % % % pixel surface west \expandafter\xdef\csname pgf@anchor@sensor line@pixel\space\the\c@pgf@counta\space west\endcsname{% \noexpand\northeast \noexpand\pgf@xa=\noexpand\pgf@x \noexpand\pgf@ya=\noexpand\pgf@y \noexpand\southwest \noexpand\pgf@xb=\noexpand\pgf@x \noexpand\pgf@yb=\noexpand\pgf@y \noexpand\pgf@x=\noexpand\pgf@xb \noexpand\pgf@y=\noexpand\pgf@ya \noexpand\newdimen\noexpand\temp@y \noexpand\pgfmathsetlength\noexpand\temp@y{(\the\c@pgf@counta-\noexpand\pixelNumber-0.5)*\noexpand\pixelHeight-\noexpand\innerysep} \noexpand\advance\noexpand\pgf@y by\noexpand\temp@y }% }{\c@pgf@counta0\relax}% \advance\c@pgf@counta-1\relax% \repeatpgfmathloop% }% \inheritanchorborder[from=rectangle] \backgroundpath { % rectangle contour \pgfpathrectanglecorners{\northeast}{\southwest} % dessin des pixels \c@pgf@counta\pixelNumber\relax% \pgfmathloop% \ifnum\c@pgf@counta>0\relax% \newdimen\pixel@northeast@x \newdimen\pixel@northeast@y \newdimen\pixel@southwest@x \newdimen\pixel@southwest@y \northeast \pgf@xa=\pgf@x \pgf@ya=\pgf@y \southwest \pgf@xb=\pgf@x \pgf@yb=\pgf@y % calcul pixel@northeast %% calcul x \pixel@northeast@x=\pgf@xb \advance\pixel@northeast@x by\pixelWidth %% calcul y \pixel@northeast@y=\pgf@ya \newdimen\temp@y \pgfmathsetlength\temp@y{(\the\c@pgf@counta-\pixelNumber)*\pixelHeight-\innerysep} \advance\pixel@northeast@y by\noexpand\temp@y % calcul pixel@southwest \pixel@southwest@x=\pgf@xb \pixel@southwest@y=\pgf@ya \newdimen\temp@y \pgfmathsetlength\temp@y{(\the\c@pgf@counta-\pixelNumber-1)*\pixelHeight-\innerysep} \advance\pixel@southwest@y by\temp@y % dessin \pgfpathrectanglecorners{\pgfpoint{\pixel@northeast@x}{\pixel@northeast@y}}{\pgfpoint{\pixel@southwest@x}{\pixel@southwest@y}} \advance\c@pgf@counta-1\relax% \repeatpgfmathloop% } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Styles defining optics elements in terms of the existing shapes. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Style [screen] \pgfkeys{/tikz/optics/screen/.style={thin optics element, very thick}} % Style [diffraction grating] \pgfkeys{/tikz/optics/diffraction grating/.style={thin optics element, /tikz/optics/cheating dash={on 4pt off 2pt}}} % Style [grid] \pgfkeys{/tikz/optics/grid/.style={thin optics element, /tikz/optics/cheating dash={on 4pt off 2pt}, ultra thick}} % Style [semi-transparent mirror] \pgfkeys{/tikz/optics/semi-transparent mirror/.style={thin optics element, densely dotted, thick}} % Style [diaphragm] \pgfkeys{/tikz/optics/diaphragm/.style={slit,/tikz/optics/slit height=0.4}} % Style [generic lamp] \pgfkeys{/tikz/optics/generic lamp/.style={shape=generic optics io,optics,draw}} % Style [generic sensor] \pgfkeys{/tikz/optics/generic sensor/.style={shape=generic optics io,optics,io orientation=rtl,draw, io body height=1cm, io body aspect ratio=0.5, io aperture width=0.15}} % Style [halogen lamp] \pgfkeys{/tikz/optics/halogen lamp/.style={/tikz/optics/generic lamp, io body height=0.75cm, io body aspect ratio=2,io aperture width=0.33,io aperture height=0.66,io aperture shift=0}} % Style [spectral lamp] \pgfkeys{/tikz/optics/spectral lamp/.style={/tikz/optics/generic lamp, io body height=2.25cm, io body aspect ratio=2/3,io aperture width=0.11,io aperture height=0.22,io aperture shift=0.25,/tikz/optics/io multiline}} % Style [laser] \pgfkeys{/tikz/optics/laser/.style={/tikz/optics/generic lamp, io body height=0.5cm, io body aspect ratio=3,io aperture width=0.22,io aperture height=0.5,io aperture shift=0}} % Style [laser'] \pgfkeys{/tikz/optics/laser'/.style={/tikz/optics/generic lamp, io body height=0.5cm, io body aspect ratio=3,io aperture width=0,io aperture height=0.5,io aperture shift=0}} % Style [beam splitter] \pgfkeys{/tikz/optics/beam splitter/.style={shape=polarizer, optics, draw, object height=1cm, object aspect ratio=1}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Helper style to draw correctly dashed paths. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % source : http://tex.stackexchange.com/questions/133271/can-tikz-dashed-lines-emulate-pstricks-dashed-lines % le but est d'avoir des dash symétriques par rapport au milieu et surtout avec un trait entier de chaque côté \tikzset{ /tikz/optics/cheating dash/.code args={on #1 off #2}{ % Use csname so catcode of @ doesn't have do be changed. \csname tikz@addoption\endcsname{% \pgfgetpath\currentpath% \pgfprocessround{\currentpath}{\currentpath}% \csname pgf@decorate@parsesoftpath\endcsname{\currentpath}{\currentpath}% \pgfmathparse{\csname pgf@decorate@totalpathlength\endcsname-#1}\let\rest=\pgfmathresult% \pgfmathparse{#1+#2}\let\onoff=\pgfmathresult% \pgfmathparse{max(floor(\rest/\onoff), 1)}\let\nfullonoff=\pgfmathresult% \pgfmathparse{max((\rest-\onoff*\nfullonoff)/\nfullonoff+#2, #2)}\let\offexpand=\pgfmathresult% \pgfsetdash{{#1}{\offexpand}}{0pt}}% } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Helper style for multiline io elements. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \pgfkeys{/tikz/optics/io multiline/.code={\newdimen\tmplen\pgfmathsetlength{\tmplen}{\pgfkeysvalueof{/tikz/optics/io body aspect ratio}*\pgfkeysvalueof{/tikz/optics/io body height}}\tikzset{text width=\the\tmplen,align=center}}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Helper styles to mark interesing points %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Style [mark point] % Describes how interesting points should be drawn (e.g. by [draw focal points], [draw mirror focus], [draw mirror center]) \pgfkeys{/tikz/optics/mark point/.style={optics/mark a cross}} % Style [draw focal points] % Should be applied to a [shape=lens] node to draw its focal points according to the style [mark point]. \pgfkeys{/tikz/optics/draw focal points/.style={append after command={ \pgfextra{ \begin{pgfinterruptpath} \node[/tikz/optics/mark point,#1] at (\tikzlastnode.west focal point) {}; \node[/tikz/optics/mark point,#1] at (\tikzlastnode.east focal point) {}; \end{pgfinterruptpath} } } }} % Style [draw mirror focus] % Should be applied to a [shape=spherical mirror] node to draw its focal point according to the style [mark point]. \pgfkeys{/tikz/optics/draw mirror focus/.style={append after command={ \pgfextra{ \begin{pgfinterruptpath} \node[/tikz/optics/mark point,#1] at (\tikzlastnode.focus) {}; \end{pgfinterruptpath} } } }} % Style [draw mirror center] % Should be applied to a [shape=spherical mirror] node to draw its center according to the style [mark point]. \pgfkeys{/tikz/optics/draw mirror center/.style={append after command={ \pgfextra{ \begin{pgfinterruptpath} \node[/tikz/optics/mark point,#1] at (\tikzlastnode.mirror center) {}; \end{pgfinterruptpath} } } }} % Style [mark a cross] % Draws a cross at the node \pgfkeys{/tikz/optics/mark a cross/.style={cross out,draw,inner sep=0pt,minimum width=2pt,minimum height=2pt}} % idée : utiliser pgfextra pour les flèches, si on peut avoir les deux dernières nodes ? %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Helper styles to easily put things on paths. % It is often needed in optics to have e.g. arrows in the middle of a path. % It is often needed everywhere to be able to put a coordinate somewhere on % a path. % This is the aim of these helpers. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Style [put coordinate] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Le style [put coordinate= at ] crée une node[coordinate] % à l'abscisse curviligne sur le chemin auquel est appliqué le style. % % Exemple : % \draw[put coordinate=P at 0.3] (0,0) to[bend left] (2cm,0); % \draw[red] (P) -- (0,0); % \tikzset{ put coordinate/.style args={#1 at #2}{decoration={markings, mark=at position #2 with {\node[coordinate] (#1) {};}},postaction={decorate}} } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Style [put arrow] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % The aim of this horrible mess is that I want expansion to take place at the right time, so I can ask for something like % \draw[/tikz/optics/->-={at=0.25}, /tikz/optics/->-={at=0.75}] (0,0) -- (2cm,2cm) -- (4cm,0); % and have it work. Obviously, I want more complicated things (several arrows with different directions, colors, number of >, etc. on the same path). % With a naive implementation, this does not work and the last setting always wins. % A possible solution would be positional arguments, however keywords arguments are Better (tm). % Hence the need to take care of expansion order, so the specifications apply only to the currently drawn arrow tip. % The main idea behing this code is to use Magic (tm) so that Things Work (tm) and never touch it again. % However, it is obvious from a trivial application of Murphy Law that this will backfire sometime. % Indeed, a key with positional arguments are used internally (|ordered draw key|), which is called from the parsed arguments. \tikzset{/tikz/put arrow/.cd, pos/.initial=0.5, at/.style={pos=#1}, pos var/.initial={}, style/.initial={}, style var/.initial={}, postaction style/.initial={}, % more expansion magic needed for ->n- and friends (\arrow[thing=stuff] does not seem to work, probably because of the =) arrow macro/.initial={arrow}, arrow macro var/.initial={}, arrow type/.initial={>}, arrow type var/.initial={}, reversed/.style={arrow macro=arrowreversed}, arrow/.style={arrow type=#1}, arrow'/.style={arrow type=#1, reversed}, every arrow/.style={}, } \tikzset{put arrow/.code={ % parse arguments correctly \tikzset{/tikz/put arrow/.cd, #1} \tikzset{/tikz/put arrow/pos var/.expand once={\pgfkeysvalueof{/tikz/put arrow/pos}}} \tikzset{/tikz/put arrow/style var/.expanded={\pgfkeysvalueof{/tikz/put arrow/style}}} \tikzset{/tikz/put arrow/arrow macro var/.expand once={\pgfkeysvalueof{/tikz/put arrow/arrow macro}}} \tikzset{/tikz/put arrow/arrow type var/.expand once={\pgfkeysvalueof{/tikz/put arrow/arrow type}}} % call |ordered draw key| which does the real job \tikzset{/tikz/put arrow/ordered draw key/.expanded=% {\pgfkeysvalueof{/tikz/put arrow/pos var}}% {\pgfkeysvalueof{/tikz/put arrow/style var}}% {\pgfkeysvalueof{/tikz/put arrow/arrow macro var}}% {\pgfkeysvalueof{/tikz/put arrow/arrow type var}}% {\pgfkeysvalueof{/tikz/put arrow/postaction style}}% } % restore initial values \tikzset{/tikz/put arrow/pos=0.5} \tikzset{/tikz/put arrow/style={}} \tikzset{/tikz/put arrow/arrow macro={arrow}} \tikzset{/tikz/put arrow/arrow type={>}} }} \tikzset{/tikz/put arrow/ordered draw key/.code n args={5}{ \tikzset{postaction={#5,decorate, decoration={markings, mark=at position #1 with {\csname #3\endcsname[/tikz/put arrow/every arrow,#2]{#4}};}}} }} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Styles to mark light rays %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \tikzset{/tikz/optics/multiple ray arrow/.cd, n/.initial=1, n var/.initial=1, set n/.code={\pgfsetarrowoptions{multiple ray arrow}{#1}}, } \pgfkeys{ /tikz/optics/.cd, use ray arrow >/.code 2 args={ \pgfsetarrowoptions{ray arrow@length}{4pt} \pgfsetarrowoptions{ray arrow@angle}{50} \tikzset{/tikz/put arrow/postaction style/.expanded={/tikz/optics/multiple ray arrow/set n=#1}} \tikzset{/tikz/put arrow/.expanded={arrow={multiple ray arrow}, #2}} }, use ray arrow n-/.code={ \tikzset{/tikz/optics/multiple ray arrow/.cd, .collect unknowns,% #1, unknown options/.get = \arrowkeys} \tikzset{/tikz/optics/multiple ray arrow/n var/.expand once={\pgfkeysvalueof{/tikz/optics/multiple ray arrow/n}}} \tikzset{/tikz/optics/use ray arrow >={\pgfkeysvalueof{/tikz/optics/multiple ray arrow/n var}}{\arrowkeys}} }, --/.style={/tikz/optics/->n-={n=1, #1}}, -<-/.style={/tikz/optics/->-/.style={/tikz/optics/->n-={n=2, #1}}, -<<-/.style={/tikz/optics/->>-/.style={/tikz/optics/->n-={n=3, #1}}, -<<<-/.style={/tikz/optics/->>>-/.style={/tikz/optics/->n-={n=4, #1}}, -<<<<-/.style={/tikz/optics/-=technical,->|] \pgfextra{\let\tikz@mode=\tikz@mode@save\let\tikz@options=\tikz@options@save} let \p1=($(\tikztostart)!\pgfkeysvalueof{/tikz/dim arrow/raise}!90:(\tikztotarget)$), \p2=($(\tikztotarget)!\pgfkeysvalueof{/tikz/dim arrow/raise}!-90:(\tikztostart)$) in ($(\p1)!-\pgfkeysvalueof{/tikz/dim arrow/arrow length}!(\p2)$) -- ($(\p1)!0!(\p2)$); \draw[>=technical,->|] \pgfextra{\let\tikz@mode=\tikz@mode@save\let\tikz@options=\tikz@options@save} let \p1=($(\tikztostart)!\pgfkeysvalueof{/tikz/dim arrow/raise}!90:(\tikztotarget)$), \p2=($(\tikztotarget)!\pgfkeysvalueof{/tikz/dim arrow/raise}!-90:(\tikztostart)$) in ($(\p2)!-\pgfkeysvalueof{/tikz/dim arrow/arrow length}!(\p1)$) -- ($(\p2)!0!(\p1)$); \ifnum\dimarrow@short@position=0 \path let \p1=($(\tikztostart)!\labelTotalRaise!90:(\tikztotarget)$), \p2=($(\tikztotarget)!\labelTotalRaise!-90:(\tikztostart)$) in let \p3=($(\p1)!-1*\pgfkeysvalueof{/tikz/dim arrow/arrow length}!(\p2)$), \p4=($(\p1)!-0*\pgfkeysvalueof{/tikz/dim arrow/arrow length}!(\p2)$) in (\p3) -- (\p4) node[pos=0.5,auto=left,/tikz/dim arrow/label style] {\pgfkeysvalueof{/tikz/dim arrow/label text}}; \fi \ifnum\dimarrow@short@position=1 \path let \p1=($(\tikztostart)!\labelTotalRaise!90:(\tikztotarget)$), \p2=($(\tikztotarget)!\labelTotalRaise!-90:(\tikztostart)$) in let \p3=($(\p2)!-1*\pgfkeysvalueof{/tikz/dim arrow/arrow length}!(\p1)$), \p4=($(\p2)!-0*\pgfkeysvalueof{/tikz/dim arrow/arrow length}!(\p1)$) in (\p4) -- (\p3) node[pos=0.5,auto=left,/tikz/dim arrow/label style] {\pgfkeysvalueof{/tikz/dim arrow/label text}}; \fi \ifnum\dimarrow@short@position=2 \path let \p1=($(\tikztostart)!\labelTotalRaise!90:(\tikztotarget)$), \p2=($(\tikztotarget)!\labelTotalRaise!-90:(\tikztostart)$) in (\p1) -- (\p2) node[pos=0.5,/tikz/dim arrow/label style] {\pgfkeysvalueof{/tikz/dim arrow/label text}}; \fi \endpgfinterruptpath }(\tikztostart) (\tikztotarget) \tikztonodes } }, draw dim arrow/.style={to path={\pgfextra{% \let\tikz@mode@save=\tikz@mode% \let\tikz@options@save=\tikz@options% \newdimen\labelTotalRaise \pgfmathsetlength\labelTotalRaise{\pgfkeysvalueof{/tikz/dim arrow/raise}} \pgfinterruptpath \draw[>=technical,|<->|] \pgfextra{\let\tikz@mode=\tikz@mode@save\let\tikz@options=\tikz@options@save} let \p1=($(\tikztostart)!\pgfkeysvalueof{/tikz/dim arrow/raise}!90:(\tikztotarget)$), \p2=($(\tikztotarget)!\pgfkeysvalueof{/tikz/dim arrow/raise}!-90:(\tikztostart)$) in (\p1) -- (\p2); \path let \p1=($(\tikztostart)!\labelTotalRaise!90:(\tikztotarget)$), \p2=($(\tikztotarget)!\labelTotalRaise!-90:(\tikztostart)$) in (\p1) -- (\p2) node[pos=0.5,auto=left,/tikz/dim arrow/label style] {\pgfkeysvalueof{/tikz/dim arrow/label text}}; % rq : inner sep controle la distance chemin-node \endpgfinterruptpath }(\tikztostart) (\tikztotarget) \tikztonodes } }, } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Arrows %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Arrow lens arrow % used to draw lenses (perhaps not the best idea). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \pgfsetarrowoptions{lens arrow@length}{6pt} \pgfsetarrowoptions{lens arrow@angle}{50} \pgfarrowsdeclare{lens arrow}{lens arrow} { \pgfarrowsleftextend{0pt} \pgfarrowsrightextend{0pt} } { \pgfsetroundcap \pgfsetmiterjoin \pgfmathsetlength{\pgfutil@tempdimb}{\pgfgetarrowoptions{lens arrow@length}*sin(\pgfgetarrowoptions{lens arrow@angle}/2)} \def\arrow@origin{\pgfpoint{0pt}{0pt}} \pgfutil@tempdima=\pgfgetarrowoptions{lens arrow@length}% \pgfmathsetmacro{\tmp@lens@angle}{90+\pgfgetarrowoptions{lens arrow@angle}} \pgfmathsetmacro{\tmp@lens@anglediv}{\pgfgetarrowoptions{lens arrow@angle}/2} \advance\pgfutil@tempdima by -1.5\pgflinewidth% \pgfmathsetlength{\pgfutil@tempdima}{\pgfutil@tempdima/cos(\pgfgetarrowoptions{lens arrow@angle}/2)} \pgfpathmoveto{\pgfpointadd{\arrow@origin}{\pgfqpointpolar{\tmp@lens@angle}{\pgfutil@tempdima}}} \pgfpathlineto{\arrow@origin} \pgfpathlineto{\pgfpointadd{\arrow@origin}{\pgfqpointpolar{-\tmp@lens@angle}{\pgfutil@tempdima}}} \pgfusepathqstroke } \pgfarrowsdeclarereversed{lens arrow reversed}{lens arrow reversed}{lens arrow}{lens arrow} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ray arrow % It is useful to have an arrow which goes on the exact middle of a path. % This is used on ->-, etc. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % flèche utilisée pour marquer les rayons lumineux (avec les styles ->-, etc.) \pgfsetarrowoptions{ray arrow@length}{4pt} \pgfsetarrowoptions{ray arrow@angle}{45} \makeatletter \pgfsetarrowoptions{multiple ray arrow}{0} \pgfarrowsdeclare{multiple ray arrow}{multiple ray arrow} { \pgfarrowsleftextend{0pt} \pgfarrowsrightextend{0pt} } { \pgfsetroundcap \pgfsetmiterjoin \pgfutil@tempdima=\pgfgetarrowoptions{ray arrow@length}% \pgfmathsetmacro{\tmp@ray@angle}{90+\pgfgetarrowoptions{ray arrow@angle}} \pgfmathsetmacro{\tmp@ray@anglediv}{\pgfgetarrowoptions{ray arrow@angle}/2} \advance\pgfutil@tempdima by -1.5\pgflinewidth% \pgfmathsetlength{\pgfutil@tempdima}{\pgfutil@tempdima/cos(\pgfgetarrowoptions{ray arrow@angle}/2)} % \foreach \i in {1,...,\pgfgetarrowoptions{multiple ray arrow}} { \pgfmathsetlength{\pgfutil@tempdimb}{(2*\i-\pgfgetarrowoptions{multiple ray arrow})*\pgfgetarrowoptions{ray arrow@length}*sin(\pgfgetarrowoptions{ray arrow@angle}/2)} % \def\arrow@origin{\pgfpoint{\pgfutil@tempdimb}{0pt}} % \pgfpathmoveto{\pgfpointadd{\arrow@origin}{\pgfqpointpolar{\tmp@ray@angle}{\pgfutil@tempdima}}} \pgfpathlineto{\arrow@origin} \pgfpathlineto{\pgfpointadd{\arrow@origin}{\pgfqpointpolar{-\tmp@ray@angle}{\pgfutil@tempdima}}} \pgfusepathqstroke } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Arrow technical %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \makeatletter \pgfarrowsdeclare{technical}{technical} {% \pgfutil@tempdima=0.48pt% \pgfutil@tempdimb=\pgflinewidth% \ifdim\pgfinnerlinewidth>0pt% \pgfmathsetlength\pgfutil@tempdimb{.6\pgflinewidth-.4*\pgfinnerlinewidth}% \fi% \advance\pgfutil@tempdima by.3\pgfutil@tempdimb% \pgfarrowsleftextend{+-3\pgfutil@tempdima}% \pgfarrowsrightextend{+8\pgfutil@tempdima}% } {% \pgfutil@tempdima=0.48pt% \pgfutil@tempdimb=\pgflinewidth% \ifdim\pgfinnerlinewidth>0pt% \pgfmathsetlength\pgfutil@tempdimb{.6\pgflinewidth-.4*\pgfinnerlinewidth}% \fi% \advance\pgfutil@tempdima by.3\pgfutil@tempdimb% \pgfpathmoveto{\pgfqpoint{8\pgfutil@tempdima}{0pt}}% \pgfpathlineto{\pgfqpoint{-3\pgfutil@tempdima}{3\pgfutil@tempdima}}% \pgfpathlineto{\pgfpointorigin}% \pgfpathlineto{\pgfqpoint{-3\pgfutil@tempdima}{-3\pgfutil@tempdima}}% \pgfusepathqfill% } \pgfarrowsdeclare{technical reversed}{technical reversed} {% \pgfutil@tempdima=0.48pt% \pgfutil@tempdimb=\pgflinewidth% \ifdim\pgfinnerlinewidth>0pt% \pgfmathsetlength\pgfutil@tempdimb{.6\pgflinewidth-.4*\pgfinnerlinewidth}% \fi% \advance\pgfutil@tempdima by.3\pgfutil@tempdimb% \pgfarrowsleftextend{-8\pgfutil@tempdima} \pgfarrowsrightextend{-8\pgfutil@tempdima} } {% \pgfutil@tempdima=0.48pt% \pgfutil@tempdimb=\pgflinewidth% \ifdim\pgfinnerlinewidth>0pt% \pgfmathsetlength\pgfutil@tempdimb{.6\pgflinewidth-.4*\pgfinnerlinewidth}% \fi% \advance\pgfutil@tempdima by.3\pgfutil@tempdimb% \pgfpathmoveto{\pgfqpoint{-8\pgfutil@tempdima}{0pt}}% \pgfpathlineto{\pgfqpoint{3\pgfutil@tempdima}{3\pgfutil@tempdima}}% \pgfpathlineto{\pgfpointorigin}% \pgfpathlineto{\pgfqpoint{3\pgfutil@tempdima}{-3\pgfutil@tempdima}}% \pgfusepathqfill% } % Changelog: % 2013-10-21 : ajout du style |distance arrow| et de la décoration |line| correspondante. % 2013-11-19 : suppression de |distance arrow| et ajout à la place de |dim arrow| et assimilés % 2013-11-22 : choix entre distances relatives et absolues (http://www.texample.net/tikz/examples/supersonic-nozzle/) % 2013-11-24 : styles de flèches |->-|, |-<-|, |->>-|, |-<<-| (et flèches pgf |ray arrow|, etc. correspondantes) % 2013-11-24 : flèches pgf |lens arrow| et |lens arrow reversed| % 2013-11-24 : |generic optics element| -> |thin optics element| et |thick optics element| ; conséquences. |beam splitter| % 2014-01-01 : ajout de |double amici prism|, |optics| -> |use optics| et |one arrow| -> |put arrow| ; |mark a *| supprimés % 2014-03-19 : anchorborder pour |generic optics io| (les labels devraient donc être placés correctement) % |io body aspect ratio| accepte désormais aussi des longueurs absolues, ajout d'un alias |io body width| pour |io body aspect ratio| % 2014-06-26 : modification du code des flèches |->-|, |->>-|, etc. et ajout de |->>>-|, |->>>>-|,|->n-=| (idem dans l'autre sens) % 2014-07-08 : ajout de |arrow style| à |put arrow| % 2014-09-20 : ajout de |spherical mirror| et quelques modifications à |mirror| (ajustement de la décoration et de ses réglages par défaut) % 2014-09-22 : ajustements de |spherical mirror| (concave et convexe), et ajout des styles correspondants |convex mirror| et |concave mirror| % 2014-09-24 : ajustements de |spherical mirror| (ltr/rtl) ; correction des ancres de generic optics io (aperture north, aperture center, aperture south étaient incorrectes) % 2014-09-25 : corrections à |spherical mirror| (ltr/rtl vs concave/convex) ; % 2014-10-02 : ajout d'une fonction |from_radius| pour définir l'angle d'ouverture de |spherical mirror|, encore des corrections à |spherical mirror| (ltr/rtl vs concave/convex) ; % macro pour les messages d'erreur % 2014-10-03 : vérifications de cohérence des grandeurs pour |slit| et |double slit| ; messages d'erreur au besoin % 2014-12-07 : modifications substantielles à |put arrow| et |optics/->n-|, etc. pour pouvoir avoir plusieurs flèches sur le même chemin ; la compatibilité arrière est brisée. % 2014-12-11 : nettoyage % 2015-03-10 : ajout d'un alias |object width| pour |object aspect ratio|, qui accepte désormais aussi des longueurs absolues % 2015-06-13 : mise en cohérence des noms des points focaux pour le miroir et la lentille (désormais, "focus" et "focal point") % 2016-11-21 : appel aux biblothèques tikz |decorations| et |decorations.pathreplacing| qui sont nécessaires \makeatother