Gere automaticamente gráficos que mostram a difusão da luz em uma superfície áspera

Gere automaticamente gráficos que mostram a difusão da luz em uma superfície áspera

Só quero fazer uma imagem assim (usando tikzou pstricks) de reflexão e difusão de luz:

Difusão de luz

O que me interessa é como isso pode ser feito (semi) automaticamente via tikzou pstricks:

  • especifique o número (e espaçamento) de raios de luz incidentes equidistantes e seu ângulo
  • desenhar a superfície com um parâmetro r que controla a "rugosidade" r = 0 é como na imagem acima, para r's maiores a superfície da fonte se torna cada vez mais áspera (como o gráfico de uma função contínua linear por partes com mais e mais partes se r se tornar maior)
  • desenhe a parte refletida de modo que a reflexão da lei (ângulos iguais) seja satisfeita "localmente"

Responder1

Aqui está uma tentativa deMetapost. Usando a direction x of ymacro para encontrar o ângulo de reflexão necessário.

Aqui está o que você ganha r=0:

insira a descrição da imagem aqui

E com r=0.33:

insira a descrição da imagem aqui

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.

Se quiser fazer algo mais sofisticado com o raio refletido, você pode salvá-lo como um caminho em vez de apenas desenhá-lo. Isso permite que você desenhe partes dele em cores diferentes ou desenhe setas ao longo dele. Assim:

insira a descrição da imagem aqui

Para obter esse efeito, você pode alterar o loop interno assim:

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   

Então, em vez de apenas desenhar o raio refletido, desta vez eu o armazenei de volta ray[i](observe que usei o operador de atribuição :=para substituir o valor anterior da variável) e depois desenhei-o em três segmentos para obter as pontas das setas em lugares legais.

Observação: Como esta solução depende da função do Metapost normaldeviatepara gerar números aleatórios, recomendo que você siga o sistema numérico padrão. Existe atualmente (MP versão 1.902) um bug horrível na forma como os novos sistemas numéricos doublee decimalimplementam as constantes necessárias para normaldeviate. Como resultado, você obterá resultados bastante selvagens se usar qualquer um desses novos sistemas numéricos. Eu levantei umproblema para isso no rastreador de bugs do MP.

Responder2

Nossos TikZers estão ficando preguiçosos, eu acho. Isso não pode acontecer sem uma resposta do TikZ: P Mesma ideia, mas usando decorações (repetidas vezes).

\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}

insira a descrição da imagem aqui

Responder3

Acabei de ver que ainda falta uma solução PSTricks;)

Usando pelo menos a versão 5.0 dopst-optexpO pacote permite usar caminhos arbitrários como superfícies refrativas ou reflexivas.

Veja como você pode simular uma superfície áspera. Basicamente você deve usar \pssavepath(from pst-intersect) para salvar algum caminho para ser usado posteriormente como superfície reflexiva:

insira a descrição da imagem aqui

\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}

informação relacionada