自動產生在粗糙表面上顯示光漫射的圖形

自動產生在粗糙表面上顯示光漫射的圖形

我只想製作這樣的影像(使用tikzpstricks)光反射和擴散:

光擴散

tikz我感興趣的是,如何通過或(半)自動完成此操作pstricks

  • 指定等距入射光線的數量(和間距)及其角度
  • 使用控制「粗糙度」的參數r 繪製表面r=0 就像上圖一樣,對於較大的r ,源面變得越來越粗糙(就像分段線性連續函數的圖形,如果r 變得越來得越多)更大)
  • 繪製反射部分,使得「局部」滿足定律反射(等角)

答案1

這是一個嘗試梅塔普斯特。使用direction x of y巨集找到所需的反射角度。

這是你得到的r=0

在此輸入影像描述

r=0.33

在此輸入影像描述

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.

如果您想對反射光線做一些更奇特的事情,那麼您可以將其另存為路徑,而不僅僅是繪製它。這使您可以用不同的顏色繪製它的一部分,或沿著它的一部分繪製箭頭。像這樣:

在此輸入影像描述

要獲得這種效果,您可以像這樣更改內部循環:

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   

因此,這次我不只是繪製反射光線,而是將其存儲回ray[i](請注意,我使用了賦值運算符:=來覆蓋變量的先前值),然後將其分成三段繪製以獲取箭頭在好的地方。

筆記:由於此解決方案依賴 Metapost 的normaldeviate函數來產生隨機數,因此我建議您堅持使用預設的數字系統。目前(MP 版本 1.902)新數位系統doubledecimal實作normaldeviate.因此,如果您使用這些新數字系統中的任何一個,您將得到相當瘋狂的結果。我已經提出了MP bug tracker 上的這個問題

答案2

我猜我們的 TikZers 正在變得懶惰。如果沒有 TikZ 的回答,這將無法逃脫:P 同樣的想法,但使用裝飾(一遍又一遍)。

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

在此輸入影像描述

答案3

我剛剛發現仍然缺少 PSTricks 解決方案;)

至少使用 5.0 版本pst-optexp封裝允許使用任意路徑作為折射或反射表面。

以下是模擬粗糙表面的方法。基本上,您必須使用\pssavepath(from pst-intersect) 來保存一些路徑,以便稍後用作反射表面:

在此輸入影像描述

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

相關內容