Here's an attempt in Metapost. Using the direction x of y
macro to find the required angle of reflection.
Here's what you get with r=0
:

And with 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.
If you want to do something fancier with the reflected ray, then you can save it
as a path instead of just drawing it. This lets you draw parts of it in different colours, or draw arrows part of the way along it. Like this:

To get this effect, you can change the inner loop like this:
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
So instead of just drawing the reflected ray, this time I have stored it back in ray[i]
(notice that I've used the assignment operator :=
to overwrite the previous value of the variable), and then drawn it afterwards in three segments to get the arrow heads in nice places.
Note:
Since this solution depends on Metapost's normaldeviate
function to generate random numbers, I recommend that you stick to the default number system. There is currently (MP version 1.902) a horrible bug in the way that the new number systems double
and decimal
implement the constants required for normaldeviate
. As a result you will get rather wild results if you use either of these new number systems. I have raised an issue for this on the MP bug tracker.