The Skier's Path
Adapted from the Maple 8 Getting Started Guide
A skier is close to the top of a mountain. She wants to take the steepest path down. This worksheet investigates finding this path.
The height at a point on the mountain as a function of (x,y) is given by
, in thousands of feet.
Picture of the Mountain
> | x:='x'; |
> | y:='y'; |
> | with(plots):plot3d(3/((1+x^2+y^2)*(1/4+((x+1)^2)/2+((y+2)^2)/2)),x=-4..3,y=-4..3,numpoints=2500,axes=boxed,orientation=[35,60],contours=20); |
> | f:=3/((1+x^2+y^2)*(1/4+((x+1)^2)/2+((y+2)^2)/2)); |
> | fx:=diff(f,x); |
> | fy:=diff(f,y); |
Approximating the Peak of the Mountain
> | HighPt:=fsolve({fx=0,fy=0},{x,y},{x=-2..0,y=-2..0}); |
> | assign(%); |
Identifying a Point Near the Peak of the Mountain (Starting Point)
> | x1:=x+0.05; |
> | y1:=y+0.05; |
> | x:='x'; |
> | y:='y'; |
> | z1:=eval(f,{x=x1,y=y1}); |
Contour Plot
> | contourplot(f,x=-3..2,y=-4..2,contours=8,filled=true); |
The Mountain with a Starting Point
> | start1:=pointplot3d([x1,y1,z1],symbol=cross,symbolsize=50,color=yellow): |
> | Mountain:=plot3d(3/((1+x^2+y^2)*(1/4+((x+1)^2)/2+((y+2)^2)/2)),x=-3..2,y=-4..2,numpoints=2500,axes=boxed,orientation=[35,60],contours=20): |
> | display(Mountain,start1); |
Approximating a Vector at the Starting Point in the Direction of Steepest Descent
(Note: The x and y Components Are in the Direction of the Negative Gradient and the z Component Is Computed to Put the Endpoint of the Vector on the Surface of the Mountain.)
> | xx1:=eval(-fx,{x=x1,y=y1}); |
> | yy1:=eval(-fy,{x=x1,y=y1}); |
> | zz1:=eval(f,{x=x1+xx1,y=y1+yy1})-z1; |
> | DirVec1:=arrow(<x1,y1,z1>,<xx1,yy1,zz1>,color=red,width=0.06): |
> | display(Mountain,start1,DirVec1); |
Approximating a Vector in the Direction of Steepest Descent at the Endpoint of the Previous "Steepest Descent" Vector
> | xx2:=eval(-fx,{x=x1+xx1,y=y1+yy1})/4; |
> | yy2:=eval(-fy,{x=x1+xx1,y=y1+yy1})/4; |
> | zz2:=eval(f,{x=x1+xx1+xx2,y=y1+yy1+yy2})-z1-zz1; |
> | DirVec2:=arrow(<x1+xx1,y1+yy1,z1+zz1>,<xx2,yy2,zz2>,color=red,width=0.06): |
> | display(Mountain,start1,DirVec1,DirVec2); |
Approximating the Path the Skier Would Take Down the Mountain
> | g:=eval(f,{x=P[1],y=P[2]}); |
> | gx:=eval(fx,{x=P[1],y=P[2]}); |
> | gy:=eval(fy,{x=P[1],y=P[2]}); |
> | point3d:=Array(1..25); |
> | route3d:=Array(1..25); |
> | timestep:=0.1; |
> | point3d[1]:=<x1,y1,z1>; |
> | for i from 1 to 24 do route3d[i]:=LinearAlgebra[Normalize](eval(<-gx,-gy,0>,P=point3d[i])); point3d[i+1]:=eval(<P[1],P[2],g>,P=point3d[i]+timestep*route3d[i]); end do: |
> | listpoints3d:=[seq(convert(point3d[i],list),i=1..25)]: |
> | path3d1:=pointplot3d(listpoints3d,style=line,color=red,thickness=3): |
> | display(Mountain,start1,path3d1); |
The Path of the Skier Projected onto the Contour Plot
> | LevelContour:=contourplot(f,x=-3..2,y=-4..2,contours=8,filled=true): |
> | gx:=eval(fx,{x=P[1],y=P[2]}); |
> | gy:=eval(fy,{x=P[1],y=P[2]}); |
> | point2d1:=Array(1..25); |
> | route2d1:=Array(1..25); |
> | timestep:=0.1; |
> | point2d1[1]:=<x1,y1>; |
> | for i from 1 to 24 do route2d1[i]:=LinearAlgebra[Normalize](eval(<-gx,-gy>,P=point2d1[i])); point2d1[i+1]:=eval(<P[1],P[2]>,P=point2d1[i]+timestep*route2d1[i]); end do: |
> | listpoints2d1:=[seq(convert(point2d1[i],list),i=1..25)]: |
> | path2d1:=pointplot(listpoints2d1,style=line,color=blue,thickness=3): |
> | display(LevelContour,path2d1); |
The Path of the Skier Projected onto the Contour Plot Starting Just Slightly on the Other Side of the Peak
> | x:='x'; |
> | y:='y'; |
> | HighPt:=fsolve({fx=0,fy=0},{x,y},{x=-2..0,y=-2..0}); |
> | assign(%); |
> | x1:=x-0.01; |
> | y1:=y-0.01; |
> | x:='x'; |
> | y:='y'; |
> | gx:=eval(fx,{x=P[1],y=P[2]}); |
> | gy:=eval(fy,{x=P[1],y=P[2]}); |
> | point2d2:=Array(1..25); |
> | route2d2:=Array(1..25); |
> | timestep:=0.1; |
> | point2d2[1]:=<x1,y1>; |
> | for i from 1 to 24 do route2d2[i]:=LinearAlgebra[Normalize](eval(<-gx,-gy>,P=point2d2[i])); point2d2[i+1]:=eval(<P[1],P[2]>,P=point2d2[i]+timestep*route2d2[i]); end do: |
> | listpoints2d2:=[seq(convert(point2d2[i],list),i=1..25)]: |
> | path2d2:=pointplot(listpoints2d2,style=line,color=blue,thickness=3): |
> | display(LevelContour,path2d2); |
Approximating the Peak of the Mountain Again
> | HighPt:=fsolve({fx=0,fy=0},{x,y},{x=-2..0,y=-2..0}); |
> | assign(%); |
Identifying the Point Again Near the Peak of the Mountain Used in the Contour Plot Above (Starting Point)
> | x1:=x-0.01; |
> | y1:=y-0.01; |
> | x:='x'; |
> | y:='y'; |
> | z1:=eval(f,{x=x1,y=y1}); |
> | start2:=pointplot3d([x1,y1,z1],symbol=cross,symbolsize=50,color=green): |
> | g:=eval(f,{x=P[1],y=P[2]}); |
> | gx:=eval(fx,{x=P[1],y=P[2]}); |
> | gy:=eval(fy,{x=P[1],y=P[2]}); |
> | point3d:=Array(1..25); |
> | route3d:=Array(1..25); |
> | timestep:=0.1; |
> | point3d[1]:=<x1,y1,z1>; |
> | for i from 1 to 24 do route3d[i]:=LinearAlgebra[Normalize](eval(<-gx,-gy,0>,P=point3d[i])); point3d[i+1]:=eval(<P[1],P[2],g>,P=point3d[i]+timestep*route3d[i]); end do: |
> | listpoints3d:=[seq(convert(point3d[i],list),i=1..25)]: |
> | path3d2:=pointplot3d(listpoints3d,style=line,color=red,thickness=3): |
Change the View of the Mountain
> | Mountain:=plot3d(3/((1+x^2+y^2)*(1/4+((x+1)^2)/2+((y+2)^2)/2)),x=-3.3..2,y=-4..2,numpoints=2500,axes=boxed,orientation=[-100,60],contours=20): |
> | display(Mountain,start2,path3d2); |
> | display(Mountain,start1,start2,path3d1,path3d2); |
> | display(LevelContour,path2d1,path2d2); |
> |