Is there a library (or something similar) available for optics including e.g. convex and concave lenses? I fount this but it seems that this is not available as an official library …
-
3This appears to has been sitting there for a while: https://launchpad.net/optikz. Good name by the way. – Roelof Spijker Nov 02 '11 at 15:12
-
3Now this would be a real nice feature request for a future version of TikZ! – Count Zero Nov 02 '11 at 16:32
-
@CountZero: So there is none yet? If you post this as an answer I’ll accept it … Is there an official way to ask for a new feature? – Tobi Nov 02 '11 at 17:17
-
@Tobi https://sourceforge.net/tracker/?group_id=142562&atid=752795 – cjorssen Nov 02 '11 at 17:46
-
there was a similar request for chemical lab equipment library http://tex.stackexchange.com/questions/3878/chemical-laboratory-equipment which also would be a handy feature... – Leeser Nov 03 '11 at 15:31
-
Any updates to this yet? Would be really interested in this! – Martijn Jun 19 '15 at 15:23
-
Not that I know of … – Tobi Jun 22 '15 at 18:09
6 Answers
There is an extensive library in pstricks - maybe it helps. http://www.ctan.org/tex-archive/graphics/pstricks/contrib/pst-optic
- 38,129
AFAIK, such a library does not exist yet.
As you mentioned, I started something a while ago, but I did not have, at that time, enough tikz/pgf knowledge to circumvent some difficulties I found.
The idea is to use the shapes/nodes mechanism to define anchors (such as image focus, center, etc.) and then use them to draw useful light rays.
Here is an example of the syntax I would have liked to have (hope it is clear enough).
\begin{tikzpicture}
\node[converging lens,anchor=center,image focal length=2.5cm] (L1) at (0,0)
{$\mathcal{L}_1$};
\node[diverging lens,anchor=center,image focal length=-1.5cm] (L2)
at ($(L1.center)!5cm!(L1.optical axis forward)$) {$\mathcal{L}_2$};
\node[object for lens=L1,height=1.5cm,anchor=bottom] (Object1) at
($(L1.center)!-2*\pgfkeysvalueof{pgf/optics/L1/focal
length}!(L1.optical axis forward)$) {};
\draw[LR>] (Object1.top) -- ($(L1.top)!(Object1.top)!(L1.bottom)$)
-- (Object1.image top by L1);
\draw[LR>>] (Object1.top) -- (L1.center) -- (Object1.image top by L1);
\draw[LR>>>] (Object1.top) --
($(L1.top)!(Object1.image top by L1)!(L1.bottom)$) --
(Object1.image top by L1);
\node[object for lens=L2,height={TO BE COMPUTED},anchor=bottom] (Object2) at
(Object1.image top by L1) {};
\end{tikzpicture}
One of the not-so-easy part is to have anchor names depending on node names (such as in the above example Object1.image top by L1). It should also be possible to know if an image is real or virtual and draw the light rays (LR) consistently.
Unfortunately, lack of time led me to a more rustic solution. Here I give a (too?) verbose example of what can be done with tikz (not a library but a kind of template):
\documentclass{standalone}
\usepackage[svgnames]{xcolor}
\usepackage{tikz}
\makeatletter
\usetikzlibrary{arrows,calc,decorations.markings}
\pgfdeclareshape{mark point +}{%
\anchor{center}{\pgfpointorigin}
\inheritsavedanchors[from=mark point |]
\backgroundpath{%
\pgfsetarrows{-}%
\pgfsetlinewidth{.8pt}%
\pgfpathmoveto{\pgfpoint{0}{.8mm}}%
\pgfpathlineto{\pgfpoint{0}{-.8mm}}%
\pgfpathmoveto{\pgfpoint{-.8mm}{0}}%
\pgfpathlineto{\pgfpoint{.8mm}{0}}%
\pgfusepath{stroke}}}
% Light rays
\tikzset{>=stealth}
\pgfarrowsdeclaredouble{doublestealth}{doublestealth}{stealth}{stealth}
\pgfarrowsdeclaretriple{triplestealth}{triplestealth}{stealth}{stealth}
\pgfarrowsdeclaredouble{quadruplestealth}{quadruplestealth}%
{doublestealth}{doublestealth}
\pgfarrowsdeclarealias{<<}{>>}{doublestealth}{doublestealth}
\pgfarrowsdeclarealias{<<<}{>>>}{triplestealth}{triplestealth}
\pgfarrowsdeclarealias{<<<<}{>>>>}{quadruplestealth}{quadruplestealth}
\tikzset{%
LRnoarrow/.style = {thick,gray,nearly opaque},
LR/.style 2 args = {%
decoration={markings,mark=at position #2 with {\arrow{#1};}},
postaction={decorate},
LRnoarrow},
VirtualLR/.style = {LRnoarrow,dashed},
LR>/.style = {LR={>}{#1}},
LR>/.default = {0.5},
LR>>/.style = {LR={>>}{#1}},
LR>>/.default = {0.55},
LR>>>/.style = {LR={>>>}{#1}},
LR>>>/.default = {0.6},
LR>>>>/.style = {LR={>>>>}{#1}},
LR>>>>/.default = {0.65},
ConvergingLens/.style = {ultra thick,<->},
DivergingLens/.style = {ultra thick,>-<},
OpticalAxis/.style = {very thick,->},
Object/.style = {very thick,->},
VirtualObject/.style = {very thick,->,dashed}}
% Annotate an angle
\pgfkeysdef{/tikz/mark angle/start angle}{\tikzset{start angle=#1}}
\pgfkeysdef{/tikz/mark angle/end angle}{\tikzset{end angle=#1}}
\pgfkeysdef{/tikz/mark angle/angle radius}{\tikzset{radius=#1}}
\pgfkeyssetvalue{/tikz/mark angle/label radius}{1cm}
\pgfkeyssetvalue{/tikz/mark angle/label pos}{.5}
\pgfkeyssetvalue{/tikz/mark angle/node options}{}
\pgfkeyssetvalue{/tikz/mark angle/path options}{}
\def\tikzMarkAngle{%
\pgfutil@ifnextchar[{\tikzMarkAngle@i}{\tikzMarkAngle@i[]}}
\def\tikzMarkAngle@i[#1](#2)(#3)(#4)#5{%
% #1 optional parameters
% #2 coordinate of the center
% #3 coordinate giving the start direction
% #4 coordinate giving the end direction
% #5 label
\bgroup
\coordinate (xCJtikz@AngleCenter) at (#2);
\coordinate (xCJtikz@AngleStart) at (#3);
\coordinate (xCJtikz@AngleEnd) at (#4);
\pgfmathanglebetweenpoints{%
\pgfpointanchor{xCJtikz@AngleCenter}{center}}{%
\pgfpointanchor{xCJtikz@AngleStart}{center}}
\edef\AngleStart{\pgfmathresult}%
\pgfmathanglebetweenpoints{%
\pgfpointanchor{xCJtikz@AngleCenter}{center}}{%
\pgfpointanchor{xCJtikz@AngleEnd}{center}}
\edef\AngleEnd{\pgfmathresult}%
\ifdim\AngleEnd pt<\AngleStart pt\relax
\pgfmathsetmacro\AngleEnd{\AngleEnd+360}
\fi
\pgfkeys{%
/tikz/mark angle/.cd,
angle radius=1cm,
label radius=1.2cm,
label pos=.5,
start angle=\AngleStart,
end angle=\AngleEnd,
#1}
\edef\xCJ@temp{%
\noexpand\draw[\pgfkeysvalueof{/tikz/mark angle/path options}]
(\noexpand$(xCJtikz@AngleCenter)!\pgfkeysvalueof{/tikz/x
radius}!(xCJtikz@AngleStart)\noexpand$) arc;
\noexpand\node[\pgfkeysvalueof{/tikz/mark angle/node options}] at
(\noexpand$(xCJtikz@AngleCenter)+(\AngleStart+\pgfkeysvalueof{/tikz/mark
angle/label pos}*\AngleEnd-\pgfkeysvalueof{/tikz/mark
angle/label pos}*\AngleStart:\pgfkeysvalueof{/tikz/mark angle/label radius})\noexpand$)}%
\xCJ@temp{#5};%
\egroup
\ignorespaces}
\makeatother
\begin{document}
\begin{tikzpicture}
\coordinate (OpticalAxisLeft) at (0,0);
\coordinate (OpticalAxisRight) at ($(OpticalAxisLeft)+(13,0)$);
\draw[OpticalAxis] (OpticalAxisLeft) -- (OpticalAxisRight);
%
\def\LensHeight{5cm}%
\def\FocalLengthOne{10cm}%
\def\FocalLengthTwo{-3cm}%
% Lens 1
\coordinate[label=below left:$O_1$] (Center1) at
($(OpticalAxisLeft)!.1!(OpticalAxisRight)$);
\coordinate[label=above:$\mathcal{L}_1$] (Top1) at
($(Center1)!\LensHeight/2!90:(OpticalAxisRight)$);
\coordinate (Bottom1) at ($(Center1)!-1!(Top1)$);
\draw[ConvergingLens] (Bottom1) -- (Top1);
\coordinate%[label=below:$F_1$]
(ObjectFocus1) at
($(Center1)!-\FocalLengthOne!(OpticalAxisRight)$) {};
\node[mark point +,label=above left:$F'_1$] (ImageFocus1) at
($(Center1)!\FocalLengthOne!(OpticalAxisRight)$) {};
\coordinate (ImageFocalPlane1Top) at
($(ImageFocus1)!\LensHeight/2!90:(OpticalAxisRight)$);
\coordinate (ImageFocalPlane1Bottom) at
($(ImageFocus1)!-1!(ImageFocalPlane1Top)$);
% Lens 2
\pgfmathsetlengthmacro\DistanceOneToTwo{%
\FocalLengthOne+\FocalLengthTwo}%
\coordinate[label=below left:$O_2$] (Center2) at
($(Center1)!\DistanceOneToTwo!(OpticalAxisRight)$);
\coordinate[label=above:$\mathcal{L}_2$] (Top2) at
($(Center2)!\LensHeight/2!90:(OpticalAxisRight)$);
\coordinate (Bottom2) at ($(Center2)!-1!(Top2)$);
\draw[DivergingLens] (Bottom2) -- (Top2);
\node[mark point +,label=below:$F_2'$] (ImageFocus2) at
($(Center2)!\FocalLengthTwo!(OpticalAxisRight)$) {};
\coordinate[label=below left:$F_2$] (ObjectFocus2) at
($(Center2)!-\FocalLengthTwo!(OpticalAxisRight)$) {};
\coordinate (ImageFocalPlane2Top) at
($(ImageFocus2)!\LensHeight/2!90:(OpticalAxisRight)$);
\coordinate (ImageFocalPlane2Bottom) at
($(ImageFocus2)!-1!(ImageFocalPlane2Top)$);
% Object at infinity
\def\ObjectAngle{12}%
\coordinate (LRBegin) at
($(OpticalAxisLeft)+(0,.9*\LensHeight/2)$);
\coordinate (temp) at ($(LRBegin)+(-\ObjectAngle:1)$);
\coordinate (IncidencePoint) at (intersection cs: first line =
{(Top1) -- (Bottom1)}, second line = {(LRBegin) -- (temp)});
%
\coordinate (LRThroughCenter1Begin) at
($(Center1)+(LRBegin)-(IncidencePoint)$);
\coordinate (Image1Top) at (intersection cs: first line =
{(LRThroughCenter1Begin) -- (Center1)}, second line =
{(ImageFocalPlane1Top) -- (ImageFocalPlane1Bottom)});
%
\draw[red,dotted,thick] (ImageFocalPlane1Top) --
(ImageFocalPlane1Bottom);
\draw[red,dotted,thick] (LRThroughCenter1Begin) --
($(Image1Top)!-.1!(LRThroughCenter1Begin)$);
\node[coordinate,label=below right:$B_1$] at (Image1Top) {};
\node[coordinate,label=below right:$A_1$] at (ImageFocus1) {};
\draw[Object,semitransparent] (ImageFocus1) -- (Image1Top);
%
\coordinate (LRIntersectionWithLens2) at
(intersection cs: first line = {(Top2) -- (Bottom2)}, second line
= {(IncidencePoint) -- (Image1Top)});
\coordinate (LRThroughCenter2Begin) at
($(Center2)+(IncidencePoint)-(LRIntersectionWithLens2)$);
\coordinate[label=above right:$I$]
(LRThroughCenter2IntersectionWithImageFocalPlane2) at
(intersection cs: first line = {(ImageFocalPlane2Top) --
(ImageFocalPlane2Bottom)}, second line =
{(LRThroughCenter2Begin) -- (Center2)});
%
\coordinate (Image1Bottom) at
($(OpticalAxisLeft)!(Image1Top)!(OpticalAxisRight)$);
\coordinate (Image1TopOnLens2) at
($(Top2)!(Image1Top)!(Bottom2)$);
%
\draw[LR>] (LRBegin) -- node[above,sloped]
{$\leftarrow B_{\infty}$} (IncidencePoint);
\draw[LR>] (IncidencePoint) -- (LRIntersectionWithLens2);
\draw[dotted] (LRIntersectionWithLens2) -- (Image1Top);
%
\draw[blue,dotted,thick] (ImageFocalPlane2Top) --
(ImageFocalPlane2Bottom);
\draw[blue,dotted,thick]
($(LRThroughCenter2IntersectionWithImageFocalPlane2)!-1cm!(Center2)$)
-- (Center2);
%
\draw[VirtualLR]
($(LRThroughCenter2IntersectionWithImageFocalPlane2)!-3cm!
(LRIntersectionWithLens2)$) -- node[above,sloped,very near start]
{$\leftarrow B'_{\infty}$} (LRIntersectionWithLens2);
\draw[LR>] (LRIntersectionWithLens2) --
($(LRIntersectionWithLens2)!-3cm!
(LRThroughCenter2IntersectionWithImageFocalPlane2)$);
%
\coordinate (PictureBottomLeft) at (OpticalAxisLeft |-
Bottom1);
\coordinate (PictureTopRight) at (OpticalAxisRight |- Top2);
\draw[ultra thin,semitransparent] ($(PictureBottomLeft)+(0,-.5)$)
grid[step=1mm] ($(PictureTopRight)+(0,.5)$);
\draw[very thin,semitransparent] ($(PictureBottomLeft)+(0,-.5)$)
grid[step=5mm] ($(PictureTopRight)+(0,.5)$);
\draw[thin,semitransparent] ($(PictureBottomLeft)+(0,-.5)$)
grid[step=1cm] ($(PictureTopRight)+(0,.5)$);
%
\coordinate (Image1TopOnLens1) at ($(Top1)!(Image1Top)!(Bottom1)$);
\draw[LR>>] ($(Image1TopOnLens1)!1cm!(ObjectFocus1)$) --
(Image1TopOnLens1);
\draw[LR>>] (Image1TopOnLens1) -- (Image1TopOnLens2);
\draw[LR>>] (Image1TopOnLens2) -- ($(Image1TopOnLens2)!-.3!(ImageFocus2)$);
\draw[VirtualLR] (Image1TopOnLens2) --
($(Image1TopOnLens2)!2!(ImageFocus2)$);
%
\tikzMarkAngle[path options={<-,DarkOrange}]%
(Center1)(LRThroughCenter1Begin)(OpticalAxisLeft){$\alpha$}
\tikzMarkAngle[path options={<-,DarkOrange}]%
(Center1)(Image1Top)(OpticalAxisRight){$\alpha$}
\tikzMarkAngle[path options={<-,DarkOrange}]%
(ImageFocus2)(Image1TopOnLens2)(OpticalAxisRight){$\alpha'$}
%
\end{tikzpicture}
\end{document}

- 10,032
- 4
- 36
- 126
-
You can get key-dependent anchor names using deferred anchors. I recently came across this and find it pretty interesting. I'll try to have a look soon and see if I can come up with a start to tackling this kind of issue. – Roelof Spijker Nov 02 '11 at 18:59
-
2
-
Thanks for this idea, but I’m looking rather for a library to print the shapes of objects like lenses etc. and not the rays between them. I guess I’ll have to make my own small library … – Tobi Nov 03 '11 at 17:40
A couple of days ago a new package called tikz-optics, written by Michel Fruchart, was added to CTAN, providing a library called optics.
The documentation is thus far only available in French as far as I can see, but there are multiple examples that demonstrates what the library can do.
See also GitHub: https://github.com/fruchart/tikz-optics
- 206,688
This is my solution using TikZ with the calc and intersection libraries.
\documentclass{standalone}% or wathever you want
% load packages
\usepackage{tikz, xcolor}
% load libraries
\usetikzlibrary{intersections,shapes.arrows,calc}
% define light and dark gray
\definecolor{lgray}{cmyk}{0,0,0,0.2}
\definecolor{dgray}{cmyk}{0,0,0,0.7}
% make some settings
\tikzset{%
% style for the intersecting path, which
% are nessesary for the calculation but
% shouldn't be drawn in the final image
ipath/.style={
% draw,% comment this aout after construction
red
},
% style for an arrow used as object
optical arrow/.style={%
fill=dgray,
inner sep=3pt,
shape=single arrow,
minimum width=0.5cm,
minimum height=1.5cm,
outer sep=0pt,
shape border rotate=90,
},
% style for the virtual image
virtual optical arrow/.style={%
fill=lgray,
inner sep=3pt,
shape=single arrow,
minimum width=0.5cm,
minimum height=1.5cm,
outer sep=0pt,
shape border rotate=90,
},
% style for the mirror
mirror/.style={%
line width=2pt,
},
% style for the axis
optical axis/.style={%
thin,
},
% style for light rays
ray/.style={%
thin,
->,
},
% style for imagined rays, which ar not real
% but help by constructin the image
imagined ray/.style={%
ray, dgray, -,
},
% alias
virtual ray/.style={imagined ray},
% style for (focal) points
point/.style={%
fill=black,
radius=0.8pt,
inner sep=1pt,
shape=circle,
minimum size=2pt,
outer sep=2pt
},
}
% set three layers
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
% and define shortcuts to access them
\newcommand{\bglayer}[1]{%
\begin{pgfonlayer}{background}%
#1%
\end{pgfonlayer}%
}
\newcommand{\fglayer}[1]{%
\begin{pgfonlayer}{foreground}%
#1%
\end{pgfonlayer}%
}
\begin{document}
\begin{tikzpicture}
% define the bounding box is nessesarx because the ipaths
% make it bigger than needed
\path [use as bounding box] (-5.2,-5) rectangle (6.2,5);
% define variables, you may vary them a little
%% radius
\def\radius{5}
\def\radiusII{5.05}
%% focal distancs = \radius/2
\def\focal{2.5}
%% object size
\def\size{1.cm}
%% object width
\def\owidth{1.25}
% draw mirror
%% the extra ipath is nessesary to get nicer rays
\path [ipath, name path=M] (\radius,0) ++(90:\radius)
arc (90:270:\radius);
\fglayer{%
\draw [mirror] (\radiusII-0.05,0) ++(130:\radiusII)
arc (130:240:\radiusII);
}
% draw focal point
\node (B) at (\focal,0) [point] {};
% draw object
\node (O) [optical arrow,anchor=tail, minimum height=\size] %
at (\owidth,0) {};
%% description
\node [above right] at (O.tip) {object};
% rays
%% draw axis ray
\draw [ray] (O.tip) -- (0,0) -- ($(0,0)!3!(\owidth,-\size)$);
%% draw parallel ray
\path [ipath, name path=PS] (O.tip) -- ++(-3,0);
\draw [ray, name intersections={of=M and PS, by=M-PS}]
(O.tip) -- (M-PS) -- ($(M-PS)!2!(B)$);
%% caculate virtual axis ray
\path [ipath, name path=AS-V] ($(0,0)!-4!(\owidth,-\size)$) -- (0,0);
%% calculate virtual parallel ray
\path [ipath, name path=PS-V] ($(M-PS)!-4!(B)$) -- (M-PS);
%% draw virtual axis ray
\draw [imagined ray, name intersections={of=AS-V and PS-V, by=Tip-V}]
(Tip-V) -- (0,0);
%% draw virtual axis ray
\draw [imagined ray] (Tip-V) -- (M-PS);
% draw virtual object
\bglayer{\path let \p{1}=(Tip-V) in
(Tip-V) node (V) [minimum height=\size,
scale={\y{1}/\size*0.665},
virtual optical arrow,anchor=tip
] {};}
%% description
\path (V.west) node [left] {virtual image};
% draw optical axis
\fglayer{\draw [optical axis] (-5,0) --++(11,0);}
\end{tikzpicture}
\end{document}


- 56,353
Here is an attempt to use the node/shape mecanism to automate the positionning of images of objects by optical system. It is, at the moment, just a proof of concept. Feel free to comment.

\documentclass{standalone}
\usepackage{tikz}
\makeatletter
\tikzset{%
optics/.is family,
optics/.cd,
% Thin centered optical system
optical system/.is family,
optical system/.cd,
image focal length/.initial = 1.5cm,
object focal length/.initial = -1.5cm,
upper height/.initial = 1.25cm,
lower height/.initial = -1.25cm,
}
\tikzset{%
% Object
optics/.cd,
object/.is family,
object/.cd,
is object for/.initial = a,
height/.initial = 1cm,
}
\pgfdeclareshape{thin centered optical system}{%
\savedmacro\upperheight{%
\edef\upperheight{%
\pgfkeysvalueof{%
/tikz/optics/optical system/upper height}}}
\savedmacro\lowerheight{%
\edef\lowerheight{%
\pgfkeysvalueof{%
/tikz/optics/optical system/lower height}}}
\savedmacro\imagefocallength{%
\edef\imagefocallength{%
\pgfkeysvalueof{%
/tikz/optics/optical system/image focal length}}}
\savedmacro\objectfocallength{%
\edef\objectfocallength{%
\pgfkeysvalueof{%
/tikz/optics/optical system/object focal length}}}
% Center
\savedanchor{\centerpoint}{\pgfpointorigin}
\anchor{center}{\centerpoint}
% Top
\savedanchor{\top}{\pgfpoint{0pt}{\upperheight}}
\anchor{top}{\top}
% Bottom
\savedanchor{\bottom}{\pgfpoint{0pt}{\lowerheight}}
\anchor{bottom}{\bottom}
% Principal image focus
\savedanchor{\principalimagefocus}{\pgfpoint{\imagefocallength}{0pt}}
\anchor{principal image focus}{\principalimagefocus}
% Principal object focus
\savedanchor{\principalobjectfocus}{\pgfpoint{\objectfocallength}{0pt}}
\anchor{principal object focus}{\principalobjectfocus}
%
\backgroundpath{%
\pgfpathmoveto{\bottom}
\pgfpathlineto{\top}
\pgfusepath{stroke}
}
}
\pgfdeclareshape{converging lens}{%
\savedmacro\upperheight{%
\edef\upperheight{%
\pgfkeysvalueof{%
/tikz/optics/optical system/upper height}}}
\savedmacro\lowerheight{%
\edef\lowerheight{%
\pgfkeysvalueof{%
/tikz/optics/optical system/lower height}}}
\savedmacro\imagefocallength{%
\edef\imagefocallength{%
\pgfkeysvalueof{%
/tikz/optics/optical system/image focal length}}}
\savedmacro\objectfocallength{%
\pgfmathsetmacro\objectfocallength{-(\imagefocallength)}}
%
\inheritsavedanchors[from=thin centered optical system]
\inheritanchor[from=thin centered optical system]{center}
\inheritanchor[from=thin centered optical system]{top}
\inheritanchor[from=thin centered optical system]{bottom}
\inheritanchor[from=thin centered optical system]{principal image focus}
\inheritanchor[from=thin centered optical system]{principal object focus}
%
\backgroundpath{%
\pgfsetarrows{stealth-stealth}
\pgfsetlinewidth{2pt}
\pgfpathmoveto{\bottom}
\pgfpathlineto{\top}
}
}
\pgfdeclareshape{object}{%
\savedmacro\height{%
\edef\height{\pgfkeysvalueof{/tikz/optics/object/height}}}
\savedmacro\isobjectfor{%
\edef\isobjectfor{%
\pgfkeysvalueof{/tikz/optics/object/is object for}}}
\savedmacro\imagefocallength{%
\begingroup
\csname pgf@sh@ma@\isobjectfor\endcsname
\edef\pgf@temp{%
\endgroup
\def\noexpand\imagefocallength{\imagefocallength}}%
\pgf@temp}
% Bottom
\savedanchor{\centerpoint}{\pgfpointorigin}
\anchor{center}{\centerpoint}
\anchor{bottom}{\centerpoint}
% Top
\savedanchor{\top}{\pgfpoint{0pt}{\height}}
\anchor{top}{\top}
% Optical system center
\savedanchor{\opticalsystemcenter}{%
\pgfpointanchor{\isobjectfor}{center}}
\anchor{optical system center}{\opticalsystemcenter}
% Top on optical system
\savedanchor{\toponopticalsystem}{%
% This allows to define \savedanchors in terms of other saved anchors.
\pgf@sh@savedpoints
\pgfpointdiff{\top}{\opticalsystemcenter}
\pgf@y=\height}
\anchor{top on optical system}{\toponopticalsystem}
% Image top
\savedanchor{\imagetop}{%
% This allows to define \savedanchors in terms of other saved anchors.
\pgf@sh@savedpoints
\pgfpointintersectionoflines{%
\toponopticalsystem}{%
\pgfpointanchor{\isobjectfor}{principal image focus}}{%
\top}{%
\pgfpointanchor{\isobjectfor}{center}}}
\anchor{image top}{\imagetop}
% Image top on optical system
\savedanchor{\imagetoponopticalsystem}{%
% This allows to define \savedanchors in terms of other saved anchors.
\pgf@sh@savedpoints
\pgfpointanchor{\isobjectfor}{center}
\pgf@xa=\the\pgf@x
\imagetop
\pgf@x=\the\pgf@xa}
\anchor{image top on optical system}{\imagetoponopticalsystem}
%
\backgroundpath{%
\pgfsetarrows{-stealth}
\pgfsetlinewidth{1pt}
\pgfpathmoveto{\centerpoint}
\pgfpathlineto{\top}
}
}
% Light rays
\usetikzlibrary{decorations.markings}
\tikzset{>=stealth}
\pgfarrowsdeclaredouble{doublestealth}{doublestealth}{stealth}{stealth}
\pgfarrowsdeclaretriple{triplestealth}{triplestealth}{stealth}{stealth}
\pgfarrowsdeclarealias{<<}{>>}{doublestealth}{doublestealth}
\pgfarrowsdeclarealias{<<<}{>>>}{triplestealth}{triplestealth}
\tikzset{%
> = stealth,
LRnoarrow/.style = {thick,gray,nearly opaque},
LR/.style 2 args = {%
decoration = {markings,mark=at position #2 with {\arrow{#1};}},
postaction = {decorate},
LRnoarrow},
VirtualLR/.style = {LRnoarrow,dashed},
LR>/.style = {LR={>}{#1}},
LR>/.default = {0.5},
LR>>/.style = {LR={>>}{#1}},
LR>>/.default = {0.55},
LR>>>/.style = {LR={>>>}{#1}},
LR>>>/.default = {0.6},
}
\makeatother
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}%[rotate=45,transform shape]
\node[draw,shape=converging lens,
optics/optical system/image focal length = 1cm,
optics/optical system/upper height = 2cm,
optics/optical system/lower height = -2cm] (L) at (2,0) {};
%
\draw[thick,->,-stealth] ($(L)!5cm!90:(L.top)$) coordinate (OpticalAxisLeft)
-- ($(L)!5cm!-90:(L.top)$) coordinate (OpticalAxisRight);
\node[draw,
shape = object,
optics/object/is object for = L] (O) at (-1,0) {};
%
\fill[red] (L.principal image focus) circle[radius=2pt];
\fill[blue] (O.optical system center) circle[radius=2pt];
\fill[green] (O.top on optical system) circle[radius=2pt];
\fill[yellow] (O.image top) circle[radius=2pt];
\draw[LR>] (O.top) -- (O.top on optical system) -- (O.image top);
\draw[LR>>] (O.top) -- (O.image top);
\draw[LR>>>] (O.top) -- (O.image top on optical system) -- (O.image top);
\end{tikzpicture}
\end{document}
- 10,032
- 4
- 36
- 126
I know I'm a little bit late for answering this question, but only recently I had to draw the notable rays of spherical mirror and lens.
After seeing cjorssen's nice answer (here), I decided to create my own package following some ideas presented in this question.
Therefore, below I present some results from my package named tikz-mirror-lens:
The basic concept is using tikzmath to calculate the coordinates (pp, i) of the image given the mirror or lens focus (f), and the coordinates of the object (p, o), and some extra parameters for configuration. The following commands draw the main parts to have the mirror or lens alongside the notable points and rays, and object and image.
The following MWE uses the package and presents the main results. It is also possible to use each constituent command separately and improve the draw freely.
\documentclass{article}
\usepackage{tikz-mirror-lens}
\usepackage{amsmath}
\begin{document}
\mirrorSphGaussFixedCoord{1}{0.5}{1}{0.4}{2.5}{-2}{2}{(-4,-1)}
\mirrorSphGaussFixedCoord{-1}{0.5}{1}{0.4}{2.5}{-1}{2}{(0.5,-1)}
\lensSphGaussFixedCoord{1}{0.5}{1}{0.4}{2.5}{-2}{2}{(-4,-1)}
\lensSphGaussFixedCoord{-1}{0.5}{1}{0.4}{2.5}{-2}{2}{(2,-1)}
\begin{tikzpicture}[very thick,
arrDec/.style={
decoration={
markings,
mark= between positions 0.1 and 0.99 step #1pt with {\arrow{latex}}
},
postaction={decorate},
},
arrDec/.default=20,
extended line/.style={shorten >=-#1,shorten <=-#1},
extended line/.default=1cm
]
\mirrorMath{1}{1.5}{1}{0.4}{3}
\mirrorBase{\f}{2.5}{-3}{3}
\mirrorPts{\v}{\f}{\c}
\mirrorLensObjIma{\p}{\pp}{\o}{\i}
\mirrorRays{\p}{\pp}{\o}{\i}
\mirrorLensCoord{\p}{\pp}{\o}{\i}{\f}{(-4,-1)}
\end{tikzpicture}
\end{document}
- 3,939

