13

I wanted to draw a prism compressor with the respective beamlines. The general setup works, but the exact control of the beam alignment within the prisms fails.

Here is the code that I have so far:

\begin{pspicture}
\pnode(0,0){S1}
\pnode(2,2){S2}

\definecolor[ps]{bl}{rgb}{%
tx@addDict begin Red Green Blue end}% 

\optprism[prismangle=30,compname=P1](0,0)(2,2)(3,1)
\optprism[prismangle=30](3,1)(4,0)(4.5,0.5)
 \mirror[mirrortype=extended](4.5,0.5)(5,1)(4.5,0.5){M1}

\drawbeam[linecolor=orange](S1){P1}
 \addtopsstyle{Beam}{linecolor=bl,linewidth=0.1\pslinewidth} 
\multido{\i=0+1}{60}{%
\pstVerb{%
\i\space 620 590 sub 59 div mul 590 add tx@addDict begin wavelengthToRGB end }%
\drawbeam[beamangle=\i\space 0.1 mul 3 sub]{1}{2-}
 %\drawbeam[loadbeampoints]{2}{3}
}%

\end{pspicture}

enter image description here

"Prism compressor"

Two problems:

  • how to get the ray drawn within the first prism
  • how to align the rays horizontally within the second prism

If someone could help me on that I would be really grateful :). Thanks in advance

1

4 Answers 4

12

Not my solution, it's from Christoph, the package author

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{pst-optexp}

\begin{document}

\begin{pspicture}[showgrid](6,3)
% uncomment for debugging
% \psset[optexp]{pswarning, useNA=false}
\pnode(0,0){S1}
\pnode(2,2){S2}

\definecolor[ps]{bl}{rgb}{tx@addDict begin Red Green Blue end}%

\begin{optexp}
\optprism[prismangle=30,compname=P1](0,0)(2,2)(3,1)
\optprism[prismangle=30](3,1)(4,0)(4.5,0.5)
\mirror[mirrortype=extended](4.5,0.5)(5,1)(4.5,0.5){M1}

\drawbeam[linecolor=orange](S1){P1}
\addtopsstyle{Beam}{linecolor=bl,linewidth=0.3\pslinewidth, beampathskip=1}
\multido{\r=0+0.5}{120}{%
  \pstVerb{%
     \r\space 620 590 sub 59 div mul 590 add tx@addDict begin wavelengthToRGB end }%
  \drawbeam[n=3.3 0.002 \r\space mul add, beampos=\r\space -0.0002 mul](S1){1-3}
}
\end{optexp}
\end{pspicture}

\end{document} 

enter image description here

4
  • That looks great - thank you. Am I right in the assumption that to find the right n to hit the second prism is just a matter of trial and error?
    – spookyfw
    Commented Jul 11, 2013 at 9:14
  • yes, that's true
    – user2478
    Commented Jul 11, 2013 at 11:11
  • actually the search for n can be completely circumvented by disabling raytracing and using the loadbeampoints again...maybe useful for systems that involve more components...
    – spookyfw
    Commented Jul 11, 2013 at 11:26
  • setting \psset[optexp]{pswarning, useNA=false} makes sense
    – user2478
    Commented Jul 11, 2013 at 20:43
16

Slightly off-topic and probably useless for an answer, but after seeing this question I couldn't resist but write a LaTeX document that produces the following picture:

enter image description here

See the code below. I have only a limited understanding of physics (got a bit rusty on refraction indices), but I hope that it actually computes the refraction angles correctly. The exact values of the refraction indices were chosen just for the dramatic effect. :)

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{intersections}

\begin{document}

\begin{tikzpicture}

% Define rainbow colors
\def\colors{{"red", "orange", "yellow", "green", "blue", "purple"}}

\definecolor{red}{RGB}{202,14,46}
\definecolor{orange}{RGB}{231,137,24}
\definecolor{yellow}{RGB}{253,253,37}
\definecolor{green}{RGB}{129,195,43}
\definecolor{blue}{RGB}{110,201,223}
\definecolor{purple}{RGB}{102,78,133}

\newlength\rayWidth
\rayWidth=1pt
\def\refractionIndexRed{1.3}
\def\refractionIndexPurple{1.60}

\coordinate (O1) at (-3, -3);         % Bottom left corner of picture
\coordinate (O2) at ( 3,  3);         % Top right corner of picture
\coordinate (A)  at (-4, -0.2);       % Start point of incoming ray
\coordinate (B)  at ( 4, 2.2);        % End point of incoming ray if prism weren't there
\coordinate (BL) at (-1, 0);          % Bottom left corner of the prism
\coordinate (BR) at (1, 0);           % Bottom right corner of the prism
\coordinate (T)  at (0, {sqrt(3)});   % Top corner of the prism
\coordinate (C)  at (0, {sqrt(3)/2}); % Center of the prism

% Clip and draw black background
\clip (O1) rectangle (O2);
\fill[black] (O1) rectangle (O2);

% Define top and bottom coordinates of ray
\coordinate (A1)  at ($(A)+(0,0.5\rayWidth)$);
\coordinate (A2)  at ($(A)+(0,-0.5\rayWidth)$);
\coordinate (B1)  at ($(B)+(0,0.5\rayWidth)$);
\coordinate (B2)  at ($(B)+(0,-0.5\rayWidth)$);

% Draw prism
\foreach \z in {0, 0.5, ..., 10} {
   \pgfmathsetmacro\d{0.5*\z}
   \pgfmathsetmacro\s{10*\z}
   \fill[rounded corners=\d pt, black!\s] ($(T)!\d pt!(C)$) -- ($(BR)!\d pt!(C)$) -- ($(BL)!\d pt!(C)$) -- cycle;
}

% Draw incoming ray
\path[name path=left side]  (T) -- (BL);
\path[name path=right side] (T) -- (BR);
\path[name path=mid line] (T) -- ($(BR)!.5!(BL)$);
\path[name path=ray top] (A1) -- (B1);
\path[name intersections={of=left side and ray top,by=P1}];
\path[name path=ray bottom] (A2) -- (B2);
\path[name intersections={of=left side and ray bottom,by=P2}];
\fill [white, thick] (A1) -- (P1) -- (P2) -- (A2) -- cycle;

% Calculate angle of incidence
\pgfmathanglebetweenpoints{\pgfpointanchor{BL}{center}}{\pgfpointanchor{T}{center}}
\let\leftSideAngle\pgfmathresult
\pgfmathanglebetweenpoints{\pgfpointanchor{A}{center}}{\pgfpointanchor{B}{center}}
\pgfmathsetmacro\sinIncidenceAngle{sin(90-\leftSideAngle+\pgfmathresult)}

% Calculate refraction angles
\pgfmathsetmacro\deltaAngleTopL{asin(\sinIncidenceAngle)-asin(\sinIncidenceAngle/\refractionIndexRed)}
\pgfmathsetmacro\deltaAngleBottomL{asin(\sinIncidenceAngle)-asin(\sinIncidenceAngle/\refractionIndexPurple)}

% Draw shaded "triangle" inside the prism
\path[name path=path1] (P1) -- ($(P1)!1!-\deltaAngleTopL:(B1)$);
\path[name intersections={of=mid line and path1,by=Q1}];
\path[name intersections={of=right side and path1,by=R1}];
\path[name path=path2] (P2) -- ($(P2)!1!-\deltaAngleBottomL:(B2)$);
\path[name intersections={of=mid line and path2,by=Q2}];
\path[name intersections={of=right side and path2,by=R2}];
\shade[shading=axis, left color=white, right color=black] 
  (P1) -- (Q1) -- (Q2) -- (P2) -- cycle;

% Calculate incidence angles
\pgfmathanglebetweenpoints{\pgfpointanchor{BR}{center}}{\pgfpointanchor{T}{center}}
\let\rightSideAngle\pgfmathresult
\pgfmathanglebetweenpoints{\pgfpointanchor{P1}{center}}{\pgfpointanchor{R1}{center}}
\pgfmathsetmacro\sinTopIncidenceAngle{sin(\rightSideAngle-90-\pgfmathresult)}
\pgfmathanglebetweenpoints{\pgfpointanchor{P2}{center}}{\pgfpointanchor{R2}{center}}
\pgfmathsetmacro\sinBottomIncidenceAngle{sin(\rightSideAngle-90-\pgfmathresult)}

\pgfmathsetmacro\deltaAngleTopR{asin(\sinTopIncidenceAngle)-asin(\sinTopIncidenceAngle/\refractionIndexRed)}
\pgfmathsetmacro\deltaAngleBottomR{asin(\sinBottomIncidenceAngle)-asin(\sinBottomIncidenceAngle/\refractionIndexPurple)}

% Draw rainbow
\coordinate (T1) at ($(P1)!12!-\deltaAngleTopR:(Q1)$);
\coordinate (T2) at ($(P2)!15!-\deltaAngleBottomR:(Q2)$);

\foreach \i in {0, ..., 5} {
   \pgfmathparse{\colors[\i]}
   \edef\color{\pgfmathresult}
   \pgfmathsetmacro\a{\i/6}
   \pgfmathsetmacro\b{(\i+1)/6}
   \fill[fill=\color] ($(R1)!\a!(R2)$) -- ($(T1)!\a!(T2)$) -- ($(T1)!\b!(T2)$) -- ($(R1)!\b!(R2)$) -- cycle;
}
\end{tikzpicture}
\end{document}

And here is an animated version: I am on fire! :)

enter image description here

Homework exercise: Write a LaTeX code that produces an image of a famous building in London with a pig flying above it.

3
  • 6
    \usepackage[dsotm]{pinkfloyd} :) Commented Jul 11, 2013 at 1:00
  • 1
    haha...looks great..I will include that in my Master-thesis instead of the compressor...
    – spookyfw
    Commented Jul 11, 2013 at 9:15
  • Whoah that animation renders great!! Brain damage!
    – percusse
    Commented Jul 21, 2013 at 15:14
9
+100

Inspired by the other answers, I added a new line style fade to the pst-optexp package version 4.5.

\documentclass{article}
\usepackage{pst-optexp}
\begin{document}
\begin{pspicture}(3,1.7)
\pnode(-1,0){A}\pnode(1,1){B}\pnode(3,0){C}
\psframe*(0,0)(3,1.7)
\begin{optexp}
  \optplane(0,0.7)
  \optprism[prismalign=center, linecolor=white](A)(B)(C)
  \optplane(C)
  \addtopsstyle{Beam}{linecolor=white}
  \drawbeam[ArrowInside=->]{1-2}
  \definecolor[ps]{bl}{rgb}{%
    tx@addDict begin Red Green Blue end}%
  \addtopsstyle{Beam}{linestyle=fade, beaminsidelast, fadeto=black}
  \multido{\i=0+1}{60}{%
    \drawbeam[n=1.5 \i\space 0.003 mul add, linecolor=white, beampathskip=1]{1-2}
    \pstVerb{\i\space 650 400 sub 59 div mul 400 add 
      tx@addDict begin wavelengthToRGB end }%
    \drawbeam[n=1.5 \i\space 0.003 mul add, linecolor=bl, beampathskip=2, fadefuncname=linear, linewidth=0.3\pslinewidth]{-}%
  }%
\end{optexp}   
\end{pspicture}
\end{document}
2
  • Your drawing is very nice, but not correct, unfortunately; the colours need to be reversed since the violet light will bend the most and the red the least. I would love to use a correct version of your drawing so how I can do the reversal of the colours? Commented Aug 16, 2023 at 18:54
  • 1
    @SvendTveskæg argh, yes, you are right. Try n=1.68 \i\space 0.003 mul sub for the drawbeam calls. That reverses the drawing of the colors
    – Christoph
    Commented Aug 24, 2023 at 17:37
6

and another dsotm with colors defined by its wavelength

enter image description here

\documentclass{article}
\usepackage{pst-node,pst-slpe,pst-grad,pst-math}
\usepackage{multido} \SpecialCoor
\pagestyle{empty}
\begin{document}
\psframebox[fillcolor=black,fillstyle=solid]{%
\begin{pspicture*}(-7,-2)(7,8)
\pnode(0,0){O}
\pnode(! /AnglePrisme 30 def /AnglePlan1 19 def /AnglePlan2 54 def
    /C1x -8 def  /C1y 7 def  /C2x 11 def  /C2y 5 def
    /u 1.5 def
    /g1x AnglePrisme sin neg def % -sin(A/2)
    /g1y AnglePrisme cos def     %  cos(A/2)
    /u1x AnglePlan1 sin neg def  /u1y AnglePlan1 cos neg def
    /E1x C1x u u1x mul add def   /E1y C1y u u1y mul add def
    /n1x AnglePlan1 cos def     /n1y AnglePlan1 sin neg def
    /Lambda {E1x g1y mul E1y g1x mul neg add n1y g1x mul neg n1x g1y mul add div neg} bind def
    /i1x {E1x Lambda n1x mul add} bind def /i1y {E1y Lambda n1y mul add} bind def
    0 0){Stockage_parametres_prisme}
\pspolygon[fillstyle=gradient,gradbegin=cyan,gradend=white,gradangle=60,gradmidpoint=0.5]%
     (O)(! 7 90 AnglePrisme add cos mul 7 90 AnglePrisme add sin mul)%
        (! 7 90 AnglePrisme sub cos mul 7 90 AnglePrisme sub sin mul)
\multido{\iLAMBDA=400+5}{80}{\pstVerb{ /lambda \iLAMBDA\space def }%
\definecolor{prisme}{wave}{\iLAMBDA}%
\pnode(! /L2 {lambda 1e-3 mul dup mul} bind def
    /N {1 1.539259 L2 mul L2 0.011931 sub div add
          0.247621 L2 mul L2 0.055608 sub div add
          1.038164 L2 mul L2 116.416755 sub div add sqrt} bind def
    /alpha1 AnglePlan1 AnglePrisme add def /sinB1 alpha1 sin N div def
    /B1 sinB1 asin def /Delta1 AnglePrisme B1 sub def
    /g2x AnglePrisme sin def  /g2y AnglePrisme cos def
    /d12x Delta1 cos def % d12x
    /d12y Delta1 sin def % d12y
    /Lambda2 {i1x g2y mul i1y g2x mul sub d12y g2x mul d12x g2y mul sub div} bind def
    /i2x {i1x Lambda2 d12x mul add} bind def /i2y {i1y Lambda2 d12y mul add} bind def
    /B2  AnglePrisme 2 mul B1 sub def /sinA2 N B2 sin mul def
    /alpha2 sinA2 asin def
    /u2x AnglePlan2 sin def /u2y AnglePlan2 cos neg def
    /Delta2 alpha2 AnglePrisme sub def
    /d2x Delta2 cos def /d2y Delta2 sin def /s2x i2x C2x sub def /s2y i2y C2y sub def
    /dA d2x u2y mul d2y u2x mul sub def  /dM d2x s2y mul d2y s2x mul sub def
    /r2x C2x dM dA div u2x mul add def  /r2y C2y dM dA div u2y mul add def
0 0){factice}
\pnodes(! C1x C1y){C1}(! C2x C2y){C2}(! E1x E1y){E1}(! i1x i1y){I1}(! i2x i2y){I2}(! r2x r2y){R2}
\psline[linecolor=prisme](I1)(I2)(R2)} \psline[linecolor=white,linewidth=0.5mm](E1)(I1)
\psline[linecolor=white,linewidth=0.5mm,arrowscale=2]{->}(E1)(!i1x E1x add 2 div i1y E1y add 2 div)
\end{pspicture*}%
}

\end{document}
1
  • 1
    Great answer, Herbert! :) Commented Jul 19, 2013 at 11:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .