Genere automáticamente gráficos que muestren la difusión de la luz sobre una superficie rugosa.

Genere automáticamente gráficos que muestren la difusión de la luz sobre una superficie rugosa.

Solo quiero hacer una imagen como esta (usando tikzo pstricks) de reflexión y difusión de la luz:

Difusión de luz

Lo que me interesa es cómo se puede hacer esto (semi) automáticamente a través de tikzo pstricks:

  • especificar el número (y el espaciado) de los rayos de luz entrantes equidistantes y su ángulo
  • dibujar la superficie con un parámetro r que controla la "rugosidad" r=0 es como en la imagen de arriba, para r más grandes la superficie de la superficie se vuelve cada vez más rugosa (como la gráfica de una función continua lineal por partes con más y más partes si r se convierte en más grande)
  • dibuje la parte reflejada de manera que la ley de reflexión (ángulos iguales) se cumpla "localmente"

Respuesta1

Aquí hay un intento enMetapost. Usando la direction x of ymacro para encontrar el ángulo de reflexión requerido.

Esto es lo que obtienes con r=0:

ingrese la descripción de la imagen aquí

Y con r=0.33:

ingrese la descripción de la imagen aquí

prologues := 3;
outputtemplate := "%j%c.eps";

beginfig(1);

path base, ray[]; u = 5mm;  

r=0.33;

base = (-6u,0) for x=-5.8u step 0.2u until 5.8u: -- (x,r*normaldeviate) endfor -- (6u,0);
draw base 
     -- point infinity of base shifted (0,-u)
     -- point 0        of base shifted (0,-u) -- cycle
     withcolor .67 red;

theta = -45;

for i=-2 upto 2:
  ray[i] = (left--right) scaled 6u rotated theta shifted (i*u,0);
  b := ypart(ray[i] intersectiontimes base);
  drawarrow point 0 of ray[i] 
         -- point b of base 
         -- point 0 of ray[i] reflectedabout(point b of base, direction b of base 
                                                              shifted point b of base 
                                                              rotatedabout(point b of base, 90));
endfor   

label.urt("r=" & decimal r, point 0 of base);

endfig;
end.

Si quieres hacer algo más elegante con el rayo reflejado, puedes guardarlo como un camino en lugar de simplemente dibujarlo. Esto le permite dibujar partes del mismo en diferentes colores o dibujar flechas en parte a lo largo del mismo. Como esto:

ingrese la descripción de la imagen aquí

Para obtener este efecto, puedes cambiar el bucle interno de esta manera:

for i=-2 upto 2:
  ray[i] = (left--right) scaled 6u rotated theta shifted (i*u,0);
  b := ypart(ray[i] intersectiontimes base);
  ray[i] := point 0 of ray[i] 
         -- point b of base 
         -- point 0 of ray[i] reflectedabout(point b of base, direction b of base 
                                                              shifted point b of base 
                                                              rotatedabout(point b of base, 90));
  drawarrow subpath(0,0.3) of ray[i];
  drawarrow subpath(0.3,1.7) of ray[i];
  draw      subpath(1.7,infinity) of ray[i];
endfor   

Entonces, en lugar de simplemente dibujar el rayo reflejado, esta vez lo almacené nuevamente ray[i](observe que usé el operador de asignación :=para sobrescribir el valor anterior de la variable) y luego lo dibujé en tres segmentos para obtener las puntas de flecha. en lugares bonitos.

Nota: Dado que esta solución depende de la función de Metapost normaldeviatepara generar números aleatorios, le recomiendo que se ciña al sistema numérico predeterminado. Actualmente (MP versión 1.902) existe un error horrible en la forma en que los nuevos sistemas numéricos doubleimplementan decimallas constantes requeridas para normaldeviate. Como resultado, obtendrás resultados bastante sorprendentes si utilizas cualquiera de estos nuevos sistemas numéricos. he levantado unproblema para esto en el rastreador de errores MP.

Respuesta2

Supongo que nuestros TikZers se están volviendo perezosos. Esto no puede salirse con la suya sin una respuesta de TikZ :P La misma idea pero usando decoraciones (una y otra vez).

\documentclass[tikz]{standalone}
\usetikzlibrary{decorations.pathmorphing,decorations.markings,calc}
\begin{document}
\begin{tikzpicture}
\shadedraw[thick,top color=gray!10,bottom color=gray,
  postaction=decorate,
  decoration={markings,
      mark= between positions 1cm and 3cm step 5mm with {% Places five of them
        \node[transform shape,inner sep=1pt] 
        (mark-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) {};
      }
  }
  ]{
    decorate[decoration={random steps,segment length=1.5mm,amplitude=1pt}]%Roughness is amplitude
    {
      (0,0) -- ++(4,0)
    }
  } -- ++(0,-5mm) -- ++(-4cm,0) -- cycle;
\foreach \x in {1,2,...,5}{
  \draw[postaction=decorate,
        decoration={markings,
                    mark=between positions 0.25 and 0.75 step 0.5 with{\arrow{latex}}
        }] 
  (mark-\x.center)+(135:2cm)  --(mark-\x.center)
       --($(mark-\x.north west)!2cm!45:(mark-\x.north east)$);
}
\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

Respuesta3

Acabo de ver que todavía falta una solución de PSTricks;)

Utilizando al menos la versión 5.0 delpst-optexpEl paquete permite utilizar trayectorias arbitrarias como superficies refractivas o reflectantes.

Así es como se puede simular una superficie rugosa. Básicamente debes usar \pssavepath(from pst-intersect) para guardar algún camino para usarlo más tarde como superficie reflectante:

ingrese la descripción de la imagen aquí

\documentclass[margin=5pt, pstricks]{standalone}
\usepackage{pst-optexp}
\makeatletter
\newOptexpTripole{roughsurface}
\def\roughsurface@nodes{%
  \pssavepath[linestyle=none, arrows=-,ArrowInside=-]{\oenode@Path{A}}{%
    \code{0 srand}% provides reproducable results
    \moveto(!-3 Rand 0.5 sub 0.1 mul)
    \multido{\r=-2.7+0.3}{20}{%
      \lineto(!\r\space Rand 0.5 sub 0.1 mul)}%
  }%
  \newOptexpComp{%
    {0 0} tx@IntersectDict /\PIT@name{\oenode@Path{A}} get 0 0 refl {PathIfc}
    1 }%
}%
\def\roughsurface@comp{%
  \pstracecurve{\oenode@Path{A}}
}%
\makeatother
\begin{document}
\begin{pspicture}(10,3)
\optplane[angle=90](1,3)
\roughsurface(0,3)(5,0)(10,3)
\addtopsstyle{Beam}{beamalign=abs, beamangle=-45, arrows=->, arrowscale=2}
\multido{\r=0+0.3}{6}{%
\drawbeam[beampos=\r]{1}{2}{1}}
\end{pspicture}
\end{document}

información relacionada