diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex')
-rw-r--r-- | Master/texmf-dist/tex/latex/tikz-optics/tikzlibraryoptics.code.tex | 2492 |
1 files changed, 2492 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/tikz-optics/tikzlibraryoptics.code.tex b/Master/texmf-dist/tex/latex/tikz-optics/tikzlibraryoptics.code.tex new file mode 100644 index 00000000000..e542a9ee86f --- /dev/null +++ b/Master/texmf-dist/tex/latex/tikz-optics/tikzlibraryoptics.code.tex @@ -0,0 +1,2492 @@ +\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 + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 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. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\usetikzlibrary{decorations,decorations.pathreplacing} + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 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 |