Shadows: Problems from Nature
How do you draw the shadows that you see on a sunny day? What happens to a shadow as the day wears on? What happens to a shadow as the object it is a shadow of moves?
You could answer the second and third questions without having an answer to the first, of course. You would just play a movie in your mind of the sun moving in an arc and the shadows lengthening. Or you could imagine the shadow of a person walking under a streetlight at night. But after getting an answer to the first question in a Maple worksheet, we can model the two motions of a shadow (one when the light source is moving, the other when the object is moving) pretty easily, as we shall see.
Analysis .
Shadows are very complex things in nature. You can see this by watching them. They don't always behave as you would predict. For the sake of simplicity, assume that we are drawing the shadow cast by a box sitting on the ground.
ch8box
So, our box will be the unit cube. We can give names to the vertices and faces,
as before.
>
v1:=[1,0,0]: v2:=[1,1,0]: v3:=[1,1,1]:
v4:=[1,0,1]: v5:=[0,0,0]: v6:=[0,1,0]: v7:=[0,1,1]: v8:=[0,0,1]:
>
front := [v1,v2,v3,v4]: back := [v5,v6,v7,v8]:
left := [v1,v5,v8,v4]: right := [v2,v6,v7,v3]:
top := [v4,v3,v7,v8]: bottom := [v1,v2,v6,v5]:
> box := plots[polygonplot3d]([front,back,left,right,top,bottom],style=patch,color=tan):
Also, we will assume that the light is coming from a single point and the shadow is being cast onto the xy-plane
.
ch8shad
Clearly, we need to find the shadows p1, p2, of the corners v1, v2, ... of the box on the xy plane. From the picture, we can see that
for some number s. In the z-coordinate (that is the third coordinate), we know the left hand side of the equation is 0, and the right hand side is
, so we can solve for t to get
. This works for any point
vi
, as long as p is above the top of the box. Let's try it on one vertex first. Take some arbitrary point p with
greater than 1 (why this restriction?).
> p :=[10,7,3];
> s := p[3]/(p[3]-v4[3]);
> p4 := p+s*(v4-p);
So the corner
projects onto the point
. Draw the line segment connecting the light source to the shadow point. It will pass through the vertex v4.
> ray := plots[polygonplot3d]([p,p4] ):
> plots[display]([ray,box],scaling=constrained,axes=boxed);
>
Actually what we want to do is draw the projection of each face of the box onto the xy-plane. So let's define a word to do just that. Let's start with a particular face, say the front face.
> face := front;
> shad := NULL;
>
for pt in face do
t := p[3]/(p[3]-pt[3]);
newpt := p + t*(pt-p);
shad := shad,newpt;
od:
> shad;
Now to see the shadow, use plots[polygonplot3d].
> plots[polygonplot3d]([[shad],front],style=patch,scaling=constrained);
Notice the bottom two corners of the front project onto themselves, since they are on the xy-plane already. The word shadow defined below takes two inputs: a light source p and a polygon face=[v1,v2,v3, ..., vn] and outputs the polygon shad=[p1, p2,...,pn] which is the shadow of face on the xy-plane cast by the light source at p.
>
Test this word out by looking at the shadow of the front of the box
> q := [-5,21,8];
> plots[display]([box,shadow(q,front)]);
It seems to do what we want. Now put together the shadow of each face of the box (except the bottom).
>
shadowbox := p -> plots[display]([box,shadow(p,front),
shadow(p,top),shadow(p,left),shadow(p,right), shadow(p,back)] );
> shadowbox(q+q);
Problems:
Problem: Find the area of the shadow shown above, not counting the base of the box. Hint: Redraw with axes = boxed and notice the shadow 'sits' in a rectangle.
Problem: Modify the definition for shadowbox so that box could be any collection of faces, not just the faces of the box. Use the newly defined word to draw the shadow of a box that is raised off of the xy-plane.
3. Shadows cast by the light of the sun or some far off light source are traced out by parallel light rays, rather than rays coming from a point p. Develop a word pshadow which draws such a shadow and use it to draw a shadowbox.
Solution to 3.
>
pshadow := proc(dir,face)
local shad, pt, t, newpt;
shad := NULL;
for pt in face do
t := pt[3]/(-dir[3]);
newpt := pt + t*dir;
shad := shad,newpt;
od;
plots[polygonplot3d]([shad],style=patch, scaling
=constrained,color=grey);
end:
>
pshadowbox := p -> plots[display]([box,pshadow(p,front),
pshadow(p,top),pshadow(p,left),pshadow(p,right),
pshadow(p,back)] );
> dir := [1,1,3];
> pshadowbox([1,4,3]);
Moving shadows
Now to make the shadows move, all we need to do is move the light source, taking pictures as it moves. While we're at it, we can provide a tabletop for the shadow to move on.
>
tabletop := plots[polygonplot3d]([[-2,-4,-.01],[2,-4,-.01],
[2,2,-.01],[-2,2,-.01]],color=magenta,style=patch);
>
movie := [seq(plots[display]([tabletop,
shadowbox(q+[ i,i/2,0])]),i=0..20)]:
> plots[display](movie,insequence=true);
>