summaryrefslogtreecommitdiff
path: root/graphics/pgf/contrib/tikz-optics/tikzlibraryoptics.code.tex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /graphics/pgf/contrib/tikz-optics/tikzlibraryoptics.code.tex
Initial commit
Diffstat (limited to 'graphics/pgf/contrib/tikz-optics/tikzlibraryoptics.code.tex')
-rw-r--r--graphics/pgf/contrib/tikz-optics/tikzlibraryoptics.code.tex2496
1 files changed, 2496 insertions, 0 deletions
diff --git a/graphics/pgf/contrib/tikz-optics/tikzlibraryoptics.code.tex b/graphics/pgf/contrib/tikz-optics/tikzlibraryoptics.code.tex
new file mode 100644
index 0000000000..72f0d6491a
--- /dev/null
+++ b/graphics/pgf/contrib/tikz-optics/tikzlibraryoptics.code.tex
@@ -0,0 +1,2496 @@
+\iffalse
+The tikzoptics library
+
+Copyright (C) 2013-2016 by
+ Michel Fruchart <michel.fruchart@ens-lyon.org>
+
+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}},
+ -<n-/.prefix style={optics,/tikz/optics/-<n-={##1}},
+ }
+ }
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% We need some existing tikz libraries and tex packages.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\usetikzlibrary{decorations,decorations.markings, decorations.pathreplacing}
+\usepackage{etoolbox}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Key |object height|
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\pgfkeys{/tikz/optics/.cd,
+ object height/.initial=2cm,
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Shape [thin optics element]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pgfdeclareshape{thin optics element}
+{
+ \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}
+
+ \anchorborder{%
+ \pgf@xb=\pgf@x% xb/yb is target
+ \pgf@yb=\pgf@y%
+ \south%
+ \pgf@xa=\pgf@x% xa/ya is se
+ \pgf@ya=\pgf@y%
+ \north%
+ \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\pgfpoint{\the\pgf@xb}{\the\pgf@yb}}
+ {\noexpand\pgfpoint{\the\pgf@xc}{\the\pgf@yc}}%
+ }%
+ \pgf@process{\pgf@marshal}%
+ \advance\pgf@x by\pgf@xa%
+ \advance\pgf@y by\pgf@ya%
+ }
+
+ \backgroundpath
+ {
+ \north \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 [lens]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\newif\iftikz@optics@lens@converging
+\tikz@optics@lens@convergingtrue
+
+% keys
+% - focal lens is used to define anchors |east focus| and |west focus|
+% - lens height is used to define anchors |lens north| and |lens south|
+% - lens type (converging or diverging)
+\pgfkeys{/tikz/optics/.cd,
+ focal length/.initial=1cm,
+ lens height/.initial=0.8,
+ lens type/.is choice,
+ lens type/converging/.code={\tikz@optics@lens@convergingtrue},
+ lens type/diverging/.code={\tikz@optics@lens@convergingfalse}
+}
+\pgfdeclareshape{lens}
+{
+ \savedanchor{\center}{
+ \pgfpointorigin
+ }
+ \anchor{center}{\center}
+
+ \savedmacro\focalLength{%
+ \edef\focalLength{\pgfkeysvalueof{/tikz/optics/focal length}}%
+ }
+
+ \savedmacro\objectHeight{%
+ \edef\objectHeight{\pgfkeysvalueof{/tikz/optics/object height}}%
+ }
+
+ \savedmacro\lensHeight{%
+ \pgfmathparse{\pgfkeysvalueof{/tikz/optics/lens height}}%
+ \ifpgfmathunitsdeclared%
+ \pgfmathsetlengthmacro{\lensHeight}{\pgfkeysvalueof{/tikz/optics/lens height}}%
+ \else%
+ \pgfmathsetlengthmacro{\lensHeight}{\pgfkeysvalueof{/tikz/optics/lens height}*\pgfkeysvalueof{/tikz/optics/object height}}%
+ \fi%
+ }
+
+ \savedanchor{\lensnorth}{
+ \pgfpointorigin
+ \pgf@y=\lensHeight%
+ \pgf@y=0.5\pgf@y%
+ }
+ \anchor{lens north}{\lensnorth}
+
+ \savedanchor{\lenssouth}{
+ \pgfpointorigin
+ \pgf@y=\lensHeight%
+ \pgf@y=-0.5\pgf@y%
+ }
+ \anchor{lens south}{\lenssouth}
+
+ \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}
+
+ \savedanchor{\eastfocal}{
+ \pgf@x=\focalLength%
+ \pgf@y=0cm%
+ }
+ \anchor{east focal point}{\eastfocal}
+ \anchor{east focus}{\eastfocal}
+
+
+ \savedanchor{\westfocal}{
+ \pgf@x=-\focalLength%
+ \pgf@y=0cm%
+ }
+ \anchor{west focal point}{\westfocal}
+ \anchor{west focus}{\westfocal}
+
+ \anchor{east}{\center}
+ \anchor{west}{\center}
+
+ \inheritanchorborder[from=thin optics element]
+
+ \backgroundpath
+ {
+ \north \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ \south \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+
+ \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
+ \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
+
+ \iftikz@optics@lens@converging
+ \pgfsetarrowsstart{lens arrow}
+ \pgfsetarrowsend{lens arrow}
+ \else
+ \pgfsetarrowsstart{lens arrow reversed}
+ \pgfsetarrowsend{lens arrow reversed}
+ \fi
+ }
+}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Shape [slit]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% keys : slit height
+\pgfkeys{/tikz/optics/.cd,
+ slit height/.initial=0.1
+}
+
+\pgfdeclareshape{slit}
+{
+ \savedanchor{\center}{
+ \pgfpointorigin
+ }
+ \anchor{center}{\center}
+ \anchor{slit center}{\center}
+ % TODO par cohérence ?
+
+ \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%
+ }
+
+ \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}
+
+ \savedanchor{\slitnorth}{
+ \pgf@x=0cm%
+ \pgf@y=\slitHeight%
+ \pgf@y=0.5\pgf@y%
+ }
+ \anchor{slit north}{\slitnorth}
+
+ \savedanchor{\slitsouth}{
+ \pgf@x=0cm%
+ \pgf@y=\slitHeight%
+ \pgf@y=-0.5\pgf@y%
+ }
+ \anchor{slit south}{\slitsouth}
+
+ \anchor{east}{\center}
+ \anchor{west}{\center}
+
+ \inheritanchorborder[from=thin optics element]
+
+ \backgroundpath
+ {
+ % erreurs possibles dans la spécification du dessin
+ \pgfmathparse{notless(\slitHeight, \objectHeight)}
+ \ifnum\pgfmathresult=1
+ \opticserror{<slit height> should be strictly lower than <object height> (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{<slit separation> should be strictly lower than <slit height> (in double slit)}
+ \fi
+ \pgfmathparse{notless(\slitSeparation+\slitHeight, \objectHeight)}
+ \ifnum\pgfmathresult=1
+ \opticserror{<slit height> plus <slit separation> should be strictly lower than <object height> (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 </tikz/optics/object 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 .<angle> (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 <i> <subanchor> with <subanchor> 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 <i> <pos>
+ % pour <i> = 4, 2, ..., \pixelNumber
+ % et <pos> = 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=<coord> at <pos>] crée une node[coordinate]
+% à l'abscisse curviligne <pos> 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 </.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}}
+ },
+ ->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}}
+ },
+ -<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/-<n-={n=1, #1}},
+ ->>-/.style={/tikz/optics/->n-={n=2, #1}},
+ -<<-/.style={/tikz/optics/-<n-={n=2, #1}},
+ ->>>-/.style={/tikz/optics/->n-={n=3, #1}},
+ -<<<-/.style={/tikz/optics/-<n-={n=3, #1}},
+ ->>>>-/.style={/tikz/optics/->n-={n=4, #1}},
+ -<<<<-/.style={/tikz/optics/-<n-={n=4, #1}},
+}
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Styles [dim arrow] and [short dim arrow]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dimarrow@short@position{0}
+\newif\ifdimarrow@nearstart
+\dimarrow@nearstarttrue
+\tikzset{%
+ /tikz/dim arrow/.code={\tikzset{draw,/tikz/dim arrow/draw dim arrow}\pgfkeys{/tikz/dim arrow/.cd,#1}},
+ /tikz/dim arrow'/.code={\pgfkeysgetvalue{/tikz/dim arrow/raise}{\tmp@tdar}\tikzset{draw,/tikz/dim arrow/draw dim arrow,/tikz/dim arrow/raise=-\tmp@tdar}\pgfkeys{/tikz/dim arrow/.cd,#1}},
+ /tikz/short dim arrow/.code={\tikzset{draw,/tikz/dim arrow/draw short dim arrow}\pgfkeys{/tikz/dim arrow/.cd,#1}},
+ /tikz/short dim arrow'/.code={\pgfkeysgetvalue{/tikz/dim arrow/raise}{\tmp@tdar}\tikzset{draw,/tikz/dim arrow/draw short dim arrow,/tikz/dim arrow/raise=-\tmp@tdar}\pgfkeys{/tikz/dim arrow/.cd,#1}},
+ /tikz/dim arrow/.cd,
+ raise/.initial={0.5cm},
+ no raise/.style={raise=0},
+ label/.code={\pgfkeys{/tikz/dim arrow/label text=#1}},
+ label'/.code={\pgfkeys{/tikz/dim arrow/label text=#1,/tikz/dim arrow/label style/.append style={swap},}},
+ label text/.initial={},
+ label style/.style={},
+ label near start/.code={\def\dimarrow@short@position{0}}, % only short
+ label near middle/.code={\def\dimarrow@short@position{2}}, % only short
+ label near end/.code={\def\dimarrow@short@position{1}}, % only short
+ arrow length/.initial={5mm}, % only for short
+ draw short 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)!-\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-=<nombre>| (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 \ No newline at end of file