% pgf-interference.sty % LaTeX package for simulating interference patterns % Author: K. Wehr % Version 0.1 % 9th January 2022 % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % \ProvidesExplPackage {pgf-interference} {2022-01-09} {0.1} {simulating interference patterns} \RequirePackage {tikz} \bool_new:N \g_pgfinterference_draft_bool \int_new:N \l_pgfinterference_slits_int % Anzahl der Spalte \fp_new:N \l_pgfinterference_wavelength_fp % Wellenlänge \fp_new:N \l_pgfinterference_slit_distance_fp % Spaltabstand (in m) \fp_new:N \l_pgfinterference_slit_width_fp % Spaltbreite (in m) \fp_new:N \l_pgfinterference_h_fp % Hilfsgröße (in 1/m) \fp_new:N \l_pgfinterference_hb_fp % Hilfsgröße (dimensionslos) \fp_new:N \l_pgfinterference_hs_fp % Hilfsgröße (dimensionslos) \fp_new:N \l_pgfinterference_x_fp % Position auf dem Schirm (in m) \fp_new:N \l_pgfinterference_screen_distance_fp % Schirmabstand (in m) \fp_new:N \l_pgfinterference_screen_width_fp % Schirmbreite (in m) \fp_new:N \l_pgfinterference_screen_height_fp % Schirmhöhe (in m) \fp_new:N \l_pgfinterference_screen_scale_fp % Skalierung \fp_new:N \l_pgfinterference_i_fp % relative Intensität innerhalb des Musters \fp_new:N \l_pgfinterference_i_scale_fp % Skalierung der Intensität \str_new:N \l_pgfinterference_ruler_type_str \tl_const:Nn \c_pgfinterference_ruler_unity_tl { \fontsize{9}{9} \upshape \sffamily cm } \tl_const:Nn \c_pgfinterference_ruler_tick_format_tl { \fontsize{9}{9} \upshape \sffamily } \dim_new:N \l_pgfinterference_screen_width_dim % Schirmbreite in der Abbildung \dim_new:N \l_pgfinterference_screen_height_dim % Schirmhöhe in der Abbildung \dim_new:N \l_pgfinterference_ruler_height_dim % Höhe des Lineals in der Abbildung \dim_new:N \l_pgfinterference_ruler_ticklength_i_dim % Länge eines langen Skalenstrichs auf dem Lineal \dim_new:N \l_pgfinterference_ruler_ticklength_ii_dim % Länge eines mittleren Skalenstrichs auf dem Lineal \dim_new:N \l_pgfinterference_ruler_ticklength_iii_dim % Länge eines kurzen Skalenstrichs auf dem Lineal \dim_new:N \l_pgfinterference_ruler_linewidth_dim % Strichstärke der Linealskala in der Abbildung \dim_const:Nn \c_pgfinterference_delta_dim {0.2pt} % Größe eines Bildpunkts \msg_new:nnn {pgf-interference} {non-positive number} { The~value~of~#1~must~be~positive~ \msg_line_context: . } \msg_new:nnn {pgf-interference} {wavelength too big} { The~wavelength~is~greater~than~1~metre~ \msg_line_context: .~ Radio~waves~are~not~supported! } \msg_new:nnn {pgf-interference} {slit width too big} { The~slit~width~is~greater~than~the~slit~distance~ \msg_line_context: .~ This~is~not~possible! } \int_set:Nn \l_pgfinterference_slits_int {2} \fp_set:Nn \l_pgfinterference_wavelength_fp {632.8e-9} \fp_set:Nn \l_pgfinterference_slit_width_fp {1e-5} \fp_set:Nn \l_pgfinterference_slit_distance_fp {1e-4} \fp_set:Nn \l_pgfinterference_screen_distance_fp {1} \fp_set:Nn \l_pgfinterference_screen_width_fp {0.1} \fp_set:Nn \l_pgfinterference_screen_height_fp {0.03} \fp_set:Nn \l_pgfinterference_screen_scale_fp {1} \fp_set:Nn \l_pgfinterference_i_scale_fp {1} \str_set:Nn \l_pgfinterference_ruler_type_str {none} \colorlet {pgfinterferencescreencolor} {black} % Paketoption \DeclareOption {draft} { \bool_gset_true:N \g_pgfinterference_draft_bool } \ProcessOptions % Optionen für das Licht \keys_define:nn {pgf-interference} { wavelength .value_required:n = true , wavelength .code:n = { \fp_compare:nNnTF {#1} > {0} { \fp_set:Nn \l_pgfinterference_wavelength_fp {#1} } { \msg_warning:nnn {pgf-interference} {non-positive number} {wavelength} } } , intensity .value_required:n = true , intensity .code:n = { \fp_compare:nNnTF {#1} > {0} { \fp_set:Nn \l_pgfinterference_i_scale_fp {#1} } { \msg_warning:nnn {pgf-interference} {non-positive number} {intensity} } } } % Optionen für das Beugungsobjekt \keys_define:nn {pgf-interference} { slits .value_required:n = true , slits .code:n = { \int_compare:nNnTF {#1} > {0} { \int_set:Nn \l_pgfinterference_slits_int {#1} } { \msg_warning:nnn {pgf-interference} {non-positive number} {slits} } } , slit-distance .value_required:n = true , slit-distance .code:n = { \fp_compare:nNnTF {#1} > {0} { \fp_set:Nn \l_pgfinterference_slit_distance_fp {#1} } { \msg_warning:nnn {pgf-interference} {non-positive number} {slit-distance} } } , slit-width .value_required:n = true , slit-width .code:n = { \fp_compare:nNnTF {#1} > {0} { \fp_set:Nn \l_pgfinterference_slit_width_fp {#1} } { \msg_warning:nnn {pgf-interference} {non-positive number} {slit-width} } } } % Optionen für den Schirm \keys_define:nn {pgf-interference} { screen-distance .value_required:n = true , screen-distance .code:n = { \fp_compare:nNnTF {#1} > {0} { \fp_set:Nn \l_pgfinterference_screen_distance_fp {#1} } { \msg_warning:nnn {pgf-interference} {non-positive number} {screen-distance} } } , screen-width .value_required:n = true , screen-width .code:n = { \fp_compare:nNnTF {#1} > {0} { \fp_set:Nn \l_pgfinterference_screen_width_fp {#1} } { \msg_warning:nnn {pgf-interference} {non-positive number} {screen-width} } } , screen-height .value_required:n = true , screen-height .code:n = { \fp_compare:nNnTF {#1} > {0} { \fp_set:Nn \l_pgfinterference_screen_height_fp {#1} } { \msg_warning:nnn {pgf-interference} {non-positive number} {screen-height} } } , screen-color .value_required:n = true , screen-color .code:n = { \colorlet {pgfinterferencescreencolor} {#1} } , scale .value_required:n = true , scale .code:n = { \fp_compare:nNnTF {#1} > {0} { \fp_set:Nn \l_pgfinterference_screen_scale_fp {#1} } { \msg_warning:nnn {pgf-interference} {non-positive number} {scale} } } } % Optionen für das Lineal \keys_define:nn {pgf-interference} { ruler .choices:nn = { above , below , screen , none } { \str_set:Nn \l_pgfinterference_ruler_type_str {#1} } , ruler .default:n = {below} } \cs_new:Nn \pgfinterference_prepare_ruler: { \dim_set:Nn \l_pgfinterference_ruler_height_dim { \fp_eval:n { \l_pgfinterference_screen_scale_fp * 1.2 } cm } \dim_set:Nn \l_pgfinterference_ruler_ticklength_i_dim { \fp_eval:n { \l_pgfinterference_screen_scale_fp * 5 } mm } \dim_set:Nn \l_pgfinterference_ruler_ticklength_ii_dim { \fp_eval:n { \l_pgfinterference_screen_scale_fp * 4 } mm } \dim_set:Nn \l_pgfinterference_ruler_ticklength_iii_dim { \fp_eval:n { \l_pgfinterference_screen_scale_fp * 3 } mm } \dim_set:Nn \l_pgfinterference_ruler_linewidth_dim { \fp_eval:n { \l_pgfinterference_screen_scale_fp * 0.15 } mm } } \cs_new:Nn \pgfinterference_draw_ruler: { \str_if_eq:VnTF \l_pgfinterference_ruler_type_str {above} { \draw [ line~width = \l_pgfinterference_ruler_linewidth_dim ] ( 0.5 \l_pgfinterference_screen_width_dim , 0.5 \l_pgfinterference_screen_height_dim ) -- ++ ( - \l_pgfinterference_screen_width_dim , 0 ) -- ++ ( 0 , \l_pgfinterference_ruler_height_dim ) node [ below~right , scale = \fp_use:N \l_pgfinterference_screen_scale_fp ] { \c_pgfinterference_ruler_unity_tl } -- ++ ( \l_pgfinterference_screen_width_dim , 0 ) -- cycle ; } { \str_if_eq:VnTF \l_pgfinterference_ruler_type_str {below} { \draw [ line~width = \l_pgfinterference_ruler_linewidth_dim ] ( 0.5 \l_pgfinterference_screen_width_dim , -0.5 \l_pgfinterference_screen_height_dim ) -- ++ ( - \l_pgfinterference_screen_width_dim , 0 ) -- ++ ( 0 , - \l_pgfinterference_ruler_height_dim ) node [ above~right , scale = \fp_use:N \l_pgfinterference_screen_scale_fp ] { \c_pgfinterference_ruler_unity_tl } -- ++ ( \l_pgfinterference_screen_width_dim , 0 ) -- cycle ; } { \draw [ line~width = \l_pgfinterference_ruler_linewidth_dim ] ( 0.5 \l_pgfinterference_screen_width_dim , 0.5 \l_pgfinterference_screen_height_dim ) -- ++ ( - \l_pgfinterference_screen_width_dim , 0 ) -- ++ ( 0 , - \l_pgfinterference_ruler_height_dim ) node [ above~right , scale = \fp_use:N \l_pgfinterference_screen_scale_fp ] { \c_pgfinterference_ruler_unity_tl } -- ++ ( \l_pgfinterference_screen_width_dim , 0 ) -- cycle ; } } \int_set:Nn \l_tmpa_int { \fp_eval:n { floor ( 1000 * \l_pgfinterference_screen_width_fp ) - 1 } } \int_step_inline:nnn {1} { \l_tmpa_int } { \dim_set:Nn \l_tmpa_dim { \fp_eval:n { \l_pgfinterference_screen_scale_fp * ##1 } mm } \dim_sub:Nn \l_tmpa_dim { 0.5 \l_pgfinterference_screen_width_dim } \int_compare:nNnTF { \int_mod:nn {##1} {10} } = {0} { \str_if_eq:VnTF \l_pgfinterference_ruler_type_str {above} { \draw [ line~width = \l_pgfinterference_ruler_linewidth_dim ] ( \l_tmpa_dim , 0.5 \l_pgfinterference_screen_height_dim ) -- ++ ( 0 , \l_pgfinterference_ruler_ticklength_i_dim ) node [ above , scale = \fp_use:N \l_pgfinterference_screen_scale_fp ] { \c_pgfinterference_ruler_tick_format_tl \int_eval:n {##1/10} } ; } { \str_if_eq:VnTF \l_pgfinterference_ruler_type_str {below} { \draw [ line~width = \l_pgfinterference_ruler_linewidth_dim ] ( \l_tmpa_dim , -0.5 \l_pgfinterference_screen_height_dim ) -- ++ ( 0 , - \l_pgfinterference_ruler_ticklength_i_dim ) node [ below , scale = \fp_use:N \l_pgfinterference_screen_scale_fp ] { \c_pgfinterference_ruler_tick_format_tl \int_eval:n {##1/10} } ; } { \draw [ line~width = \l_pgfinterference_ruler_linewidth_dim ] ( \l_tmpa_dim , 0.5 \l_pgfinterference_screen_height_dim ) -- ++ ( 0 , - \l_pgfinterference_ruler_ticklength_i_dim ) node [ below , scale = \fp_use:N \l_pgfinterference_screen_scale_fp ] { \c_pgfinterference_ruler_tick_format_tl \int_eval:n {##1/10} } ; } } } { \int_compare:nNnTF { \int_mod:nn {##1} {5} } = {0} { \str_if_eq:VnTF \l_pgfinterference_ruler_type_str {above} { \draw [ line~width = \l_pgfinterference_ruler_linewidth_dim ] ( \l_tmpa_dim , 0.5 \l_pgfinterference_screen_height_dim ) -- ++ ( 0 , \l_pgfinterference_ruler_ticklength_ii_dim ) ; } { \str_if_eq:VnTF \l_pgfinterference_ruler_type_str {below} { \draw [ line~width = \l_pgfinterference_ruler_linewidth_dim ] ( \l_tmpa_dim , -0.5 \l_pgfinterference_screen_height_dim ) -- ++ ( 0 , - \l_pgfinterference_ruler_ticklength_ii_dim ) ; } { \draw [ line~width = \l_pgfinterference_ruler_linewidth_dim ] ( \l_tmpa_dim , 0.5 \l_pgfinterference_screen_height_dim ) -- ++ ( 0 , - \l_pgfinterference_ruler_ticklength_ii_dim ) ; } } } { \str_if_eq:VnTF \l_pgfinterference_ruler_type_str {above} { \draw [ line~width = \l_pgfinterference_ruler_linewidth_dim ] ( \l_tmpa_dim , 0.5 \l_pgfinterference_screen_height_dim ) -- ++ ( 0 , \l_pgfinterference_ruler_ticklength_iii_dim ) ; } { \str_if_eq:VnTF \l_pgfinterference_ruler_type_str {below} { \draw [ line~width = \l_pgfinterference_ruler_linewidth_dim ] ( \l_tmpa_dim , -0.5 \l_pgfinterference_screen_height_dim ) -- ++ ( 0 , - \l_pgfinterference_ruler_ticklength_iii_dim ) ; } { \draw [ line~width = \l_pgfinterference_ruler_linewidth_dim ] ( \l_tmpa_dim , 0.5 \l_pgfinterference_screen_height_dim ) -- ++ ( 0 , - \l_pgfinterference_ruler_ticklength_iii_dim ) ; } } } } } } \cs_new:Nn \pgfinterference_draw_pattern: { \dim_step_inline:nnnn { -0.5 \l_pgfinterference_screen_width_dim + 0.5 \c_pgfinterference_delta_dim } { \c_pgfinterference_delta_dim } { 0.5 \l_pgfinterference_screen_width_dim } { \fp_set:Nn \l_pgfinterference_x_fp { \dim_ratio:nn {##1} {100cm} / \l_pgfinterference_screen_scale_fp } \fp_set:Nn \l_pgfinterference_h_fp { pi / \l_pgfinterference_wavelength_fp / sqrt ( ( \l_pgfinterference_screen_distance_fp / \l_pgfinterference_x_fp ) ^ 2 + 1 ) } \fp_set:Nn \l_pgfinterference_hb_fp { \l_pgfinterference_slit_width_fp * \l_pgfinterference_h_fp } \fp_set:Nn \l_pgfinterference_hs_fp { \l_pgfinterference_slit_distance_fp * \l_pgfinterference_h_fp } \fp_set:Nn \l_pgfinterference_i_fp { ( sin ( \l_pgfinterference_hb_fp ) / \l_pgfinterference_hb_fp * sin ( \l_pgfinterference_slits_int * \l_pgfinterference_hs_fp ) / sin ( \l_pgfinterference_hs_fp ) / \l_pgfinterference_slits_int ) ^ 2 } \int_set:Nn \l_tmpa_int { \fp_eval:n { round ( 100 * \l_pgfinterference_i_fp * \l_pgfinterference_i_scale_fp ) } } \int_compare:nNnTF { \l_tmpa_int } < {100} { \colorlet {pgfinterferencecolor} { pgfinterferencelasercolor ! \int_use:N \l_tmpa_int ! pgfinterferencescreencolor } } { \colorlet {pgfinterferencecolor} {pgfinterferencelasercolor} } \dim_set:Nn \l_tmpa_dim { ##1 - 0.5 \c_pgfinterference_delta_dim } \fill [ pgfinterferencecolor ] ( \l_tmpa_dim , -0.5 \l_pgfinterference_screen_height_dim ) rectangle ++ ( \c_pgfinterference_delta_dim , \l_pgfinterference_screen_height_dim ) ; } } \NewDocumentCommand \pgfinterferenceoptions {m} { \keys_set:nn {pgf-interference} {#1} } \NewDocumentCommand \pgfinterferencepattern {m} { \group_begin: \keys_set:nn {pgf-interference} {#1} \selectcolormodel {rgb} \fp_compare:nNnTF { \l_pgfinterference_wavelength_fp * 1e9 } < {1000} { \definecolor {pgfinterferencelasercolor} {wave} { \fp_eval:n { \l_pgfinterference_wavelength_fp * 1e9 } } } { \colorlet {pgfinterferencelasercolor} {black} } \dim_set:Nn \l_pgfinterference_screen_width_dim { \fp_eval:n { 100 * \l_pgfinterference_screen_scale_fp * \l_pgfinterference_screen_width_fp } cm } \str_if_eq:VnF \l_pgfinterference_ruler_type_str {none} { \pgfinterference_prepare_ruler: } \str_if_eq:VnTF \l_pgfinterference_ruler_type_str {screen} { \colorlet {pgfinterferencescreencolor} {white} \dim_set_eq:NN \l_pgfinterference_screen_height_dim \l_pgfinterference_ruler_height_dim } { \dim_set:Nn \l_pgfinterference_screen_height_dim { \fp_eval:n { 100 * \l_pgfinterference_screen_scale_fp * \l_pgfinterference_screen_height_fp } cm } } \begin {tikzpicture} \extractcolorspec {pgfinterferencescreencolor} \pgfinterference_tmpa: \extractcolorspec {white} \pgfinterference_tmpb: \bool_lazy_and:nnTF { ! \str_if_eq_p:Vn \l_pgfinterference_ruler_type_str {screen} } { \cs_if_eq_p:NN \pgfinterference_tmpa: \pgfinterference_tmpb: } { \draw [ fill = pgfinterferencescreencolor ] ( -0.5 \l_pgfinterference_screen_width_dim , -0.5 \l_pgfinterference_screen_height_dim ) rectangle ( 0.5 \l_pgfinterference_screen_width_dim , 0.5 \l_pgfinterference_screen_height_dim ) ; } { \fill [ pgfinterferencescreencolor ] ( -0.5 \l_pgfinterference_screen_width_dim , -0.5 \l_pgfinterference_screen_height_dim ) rectangle ( 0.5 \l_pgfinterference_screen_width_dim , 0.5 \l_pgfinterference_screen_height_dim ) ; } \fp_compare:nNnTF { \l_pgfinterference_wavelength_fp } > {1} { \msg_warning:nn {pgf-interference} {wavelength too big} } { \fp_compare:nNnTF { \l_pgfinterference_slit_width_fp } > { \l_pgfinterference_slit_distance_fp } { \msg_warning:nn {pgf-interference} {slit width too big} } { \bool_if:NF \g_pgfinterference_draft_bool { \pgfinterference_draw_pattern: } } } \str_if_eq:VnF \l_pgfinterference_ruler_type_str {none} { \pgfinterference_draw_ruler: } \end {tikzpicture} \group_end: }