# Multiple Level Curves Maplet # Joanna Ellis-Monaghan, Colin Kriwox, Laura McLane # 1 January 2003 # # Click Edit/Execute/Worksheet or the !!! button to initiate the Maplet. # Objective # This Maplet plots a surface given by a function of two variables together with one or many of its level curves. A 2D plot of the level curve(s) appears below the surface plot. restart; with(plots): # Plot Options axesType:=proc(norm,box,fram,none) if norm then NORMAL elif box then BOXED elif fram then FRAMED else NONE end if end: scaleType:=proc(unc,con) if con then CONSTRAINED else UNCONSTRAINED end if end proc: projType:=proc(orth,fish,norm) if orth then ORTHOGONAL elif fish then FISHEYE else NORMAL end if end proc: shadeType:=proc(xyz,xy,z,zgray,zhue,none) if xyz then XYZ elif xy then XY elif z then Z elif zgray then ZGRAYSCALE elif zhue then ZHUE else NONE end if end proc: lightType:=proc(l1,l2,l3,l4,none) if l1 then light1 elif l2 then light2 elif l3 then light3 elif l4 then light4 else NONE end if end proc: styleType:=proc(pt,hide,wire,cont,png,pcon,ln,pat) if pt then POINT elif hide then HIDDEN elif wire then WIREFRAME elif cont then CONTOUR elif png then PATCHNOGRID elif pcon then PATCHCONTOUR elif ln then LINE else PATCH end if end proc: # Function to get the max and min of plot getT1:=proc(fxy, xl, xh, yl, yh,zoomfactor, t) local returnVal, a, A, B, myMax, myMin, f: f:=(x,y)->fxy: a:=plot3d(f(x,y), x=xl*10^(zoomfactor/10)..xh*10^(zoomfactor/10), y=yl*10^(zoomfactor/10)..yh*10^(zoomfactor/10)): A:=op(1,eval(a)): B:=op(3,eval(A)): myMax:=max(seq(seq(B[i,j],i=ArrayDims(B[1])),j=ArrayDims(B[2]))): myMin:=min(seq(seq(B[i,j],i=ArrayDims(B[1])),j=ArrayDims(B[1]))): returnVal:= myMin + ((t/100) * (myMax - myMin)); end proc: # Function for surface plot plotsurfacecontours1 := proc (f, lowerX, upperX, lowerY, upperY,zoomfactor, vView, hView,c, AXES, SCALE, PROJ, SHADE, LIGHT, STYLE) local funcPlot,contplot, F,returnVal: F:=(x,y)->f: funcPlot := plot3d(F(x,y), x=lowerX*10^(zoomfactor/10)..upperX*10^(zoomfactor/10), y=lowerY*10^(zoomfactor/10)..upperY*10^(zoomfactor/10)): contplot:= contourplot3d(F(x,y), x=lowerX*10^(zoomfactor/10)..upperX*10^(zoomfactor/10), y=lowerY*10^(zoomfactor/10)..upperY*10^(zoomfactor/10), contours=c, thickness=3, color=black): returnVal := display ([funcPlot,contplot], axes=AXES, orientation=[hView, vView],scaling=SCALE, projection=PROJ, shading=SHADE, lightmodel=LIGHT, style=STYLE): returnVal; end: # Function for level curves levelcurves1 := proc (f, lowerX, upperX, lowerY, upperY,zoomfactor, c, SCALE) local curvesPlot, F,returnVal: F:=(x,y)->f: curvesPlot := contourplot(F(x,y), x=lowerX*10^(zoomfactor/10)..upperX*10^(zoomfactor/10), y=lowerY*10^(zoomfactor/10)..upperY*10^(zoomfactor/10), contours=c): returnVal := display (curvesPlot, axes=NORMAL, scaling=SCALE): returnVal; end: # Error Handler getT:=proc(fxy, xl, xh, yl, yh,zoomfactor, t) local failGetT: try getT1(fxy, xl, xh, yl, yh,zoomfactor, t): catch: failGetT := 0: end try; end: plotsurfacecontours := proc (f, lowerX, upperX, lowerY, upperY, zoomfactor,vView, hView,conts, AXES, SCALE, PROJ, SHADE, LIGHT, STYLE) local failPlot: try plotsurfacecontours1(f, lowerX, upperX, lowerY, upperY, zoomfactor,vView, hView,conts, AXES, SCALE, PROJ, SHADE, LIGHT, STYLE): catch: failPlot := textplot3d([4,4,3,"Please check the parameters and Maple syntax."]): end try; end: levelcurves := proc (f, lowerX, upperX, lowerY, upperY,zoomfactor, c, SCALE) local failPlot: try levelcurves1(f, lowerX, upperX, lowerY, upperY,zoomfactor, c, SCALE): catch: failPlot := textplot3d([4,4,3,"Please check the parameters and Maple syntax."]): end try; end: # Maplet with(Maplets[Elements]): b:= 'border'=true: s:= 'inset'=0, 'spacing'=0: c := 'background'="#EEFFFF": dc := 'background'="#0000FF": lc := 'background'="#EEFFFF": assignradio:=(b1,b2)->Action(Evaluate(b1=b2)): assignGraph:=()->Action( Evaluate(graph='plotsurfacecontours(Fxy, xlow, xhigh, ylow, yhigh,zoomfactor, sliderright, sliderbottom, ncurves,axesType(RB1,RB2,RB3,RB4), scaleType(RB1c,RB2c), projType(RB1p,RB2p,RB3p), shadeType(RB1s,RB2s,RB3s,RB4s,RB5s,RB6s), lightType(RB1l,RB2l,RB3l,RB4l,RB5l), styleType(RB1t,RB2t,RB3t,RB4t,RB5t,RB6t,RB7t,RB8t))') ,Evaluate(graph2='levelcurves(Fxy, xlow, xhigh, ylow, yhigh,zoomfactor, ncurves, scaleType(RB1lc,RB2lc))')): LevelCurveMaplet:= Maplet( 'onstartup' =RunWindow('MainWin'), Font['F1']('family'="Comic Sans MS", 'bold'='false', 'italic'='false', size=12), Font['F2']('family'="Comic Sans MS", 'bold'='true', 'italic'='false', size=14), ButtonGroup['RG0'](), ButtonGroup['RG1'](), ButtonGroup['RG2a'](), # for MenuRadioButtons SCALE surface ButtonGroup['RG2b'](), # for MenuRadioButtons SCALE level curves ButtonGroup['RG3'](), ButtonGroup['RG4'](), ButtonGroup['RG5'](), ButtonGroup['RG6'](), Window['MainWin']('title'="Multiple Level Curves", menubar='Menu','layout'='MainBody', 'width'=800, 'height'=700), Window['DescriptionWin']('title' = "Description", 'layout' = 'DescriptionBody', width=400, height=250), Window['SyntaxWin']('title' = "Maple Syntax", 'layout' = 'SyntaxBody', width=400, height=430), Window['NotesWin']('title' = "Notes", 'layout' = 'NotesBody', width=400, height=300), Window['PrintingWin']('title' = "Printing", 'layout' = 'PrintingBody', width=400, height=250), Window['AboutWin']('title' = "About", 'layout' = 'AboutBody', width=400, height=300), Window['ExploreWin']('title' = "Multiple Level Curves", 'layout' = 'ExploreBody', width=400, height=300), BoxLayout['DescriptionBody']( BoxColumn(b, 'inset'=0, 'spacing'=4, BoxRow(s, TextBox('wrapped'=true, 'width'=80, 'height'=15, ck, 'font'='F1', 'editable'='false', 'value'= ############################ DESCRIPTION TEXT (BELOW) ################## "This Maplet plots a surface given by a function of two variables, together with a choice of level curves. A 2D plot of the level curves appears below the surface plot. There are three choices (the radio buttons) of ways to input the level curves: \n 1. A single value which must be enclosed in square brackets, e.g. [13.5]. This plots a single level curve at this height.\n 2. An integer N, without brackets, e.g. 10. This plots N level curves at heights evenly spaced between the min and max of the function on the chosen domain. \n 3. A list of values enclosed in square brackets, e.g. [5, 10, 17, 30]. This plots a level curve at each of the listed heights. \nAfter choosing the radio button, enter the value(s), and then either hit enter while the cursor is in the Level Curves textbox or click the \"plot surface and level curves\" button. \n\n To adjust the x and y range of the graph, change the values on the right hand side of the Maplet that say \"x domain\" and \"y domain\". The zoom factor lets you quickly zoom in and out of the selected view. Slider bars on the plot window adjust the viewing angle. Sliders may be moved with the mouse or changed incrementally by selecting with the mouse and then using the arrow keys. Various buttons on the menu bar change the appearance of the plot." ############################ DESCRIPTION TEXT (ABOVE) ################## ) ), BoxRow(s, Button("Close", 'font'='F1', CloseWindow('DescriptionWin') ) ) ) ), BoxLayout['SyntaxBody']( BoxColumn(b, 'inset'=0, 'spacing'=4, BoxRow(s, TextBox('wrapped'=true, 'width'=80, 'height'=15, ck, 'font'='F1', 'editable'='false', 'value'= ############################ SYNTAX TEXT (BELOW) ################## "Maple Syntax: Entries in textboxes must use Maple Syntax. For example: \n Addition: a+b \n Subtraction: a-b \n Multiplication: a*b \n Division: a/b \n Powers: a^b \n Exponents of e: exp(a), use exp(1) for e = 2.718... \n Square root: sqrt(a) \n Log base 10: log10(a) \n Natural log: ln(a) \n Trigonometric functions: sin(a) \n Pi (3.14...): Pi \n Lists: [a,b,c] \n \n Use parentheses to clearly indicate order of operation." ############################ SYNTAX TEXT (ABOVE) ################## ) ), BoxRow(s, Button("Close", 'font'='F1', CloseWindow('SyntaxWin') ) ) ) ), BoxLayout['NotesBody']( BoxColumn(b, 'inset'=0, 'spacing'=4, BoxRow(s, TextBox('wrapped'=true, 'width'=80, 'height'=15, ck, 'font'='F1', 'editable'='false', 'value'= ############################ NOTES TEXT (BELOW) ################## " The 'Zoom Factor' slider will let you quickly zoom in or out by multiplying the xmax, xmin, ymax and ymin values by 10^(zoomfactor/10). This means that it only zooms around the center of the view window if 0 is in the interval (eg [-1..2] becomes [-1/10..2/10] with zoom factor -10), but it shifts the center of the view window if 0 is not in the interval (eg [1..2] becomes [1/10..2/10] with zoom factor -10). \n\nWarnings! \n 1. On complicated functions, the level curve may look 'wigglier' than it should--try different viewing windows if you suspect this. \n 2. The graphs will be distorted (e.g. circles will appear as ellipses) unless 'constrained' is selected under the 'scale' option on the menu bar. Also, if 'constrained' is selected, and circles still appear elliptical , it may be necessary to resize the entire Maplet window itself (by clicking on a corner and dragging). Try F(x,y) = x^2 + y^2--the level curves should be circles. Adjust the main window by dragging until the level curve in the 2D plot looks like a circle." ############################ NOTES TEXT (ABOVE) ################## ) ), BoxRow(s, Button("Close", 'font'='F1', CloseWindow('NotesWin') ) ) ) ), BoxLayout['PrintingBody']( BoxColumn(b, 'inset'=0, 'spacing'=4, BoxRow(s, TextBox('wrapped'=true, 'width'=80, 'height'=15, ck, 'font'='F1', 'editable'='false', 'value'= ############################ PRINTING TEXT (BELOW) ################## "Currently the best way to get a printout of this Maplet (on a PC at least) is to press Alt PrntScrn while the Maplet is the active window. This puts a copy of the window image on the clipboard. You can then paste this image into another application, such as Word, and then print it from there. Please check the Maple website at www.maplesoft.com for future developments!" ############################ PRINTING TEXT (ABOVE) ################## ) ), BoxRow(s, Button("Close", 'font'='F1', CloseWindow('PrintingWin') ) ) ) ), BoxLayout['AboutBody']( BoxColumn(b, 'inset'=0, 'spacing'=6, background="#990099", BoxColumn(s, background="#990099", Label(font=F2, "Saint Michael\'s College", foreground="#FFFF00", background="#990099"), Label(font=F1, "Colchester, VT", foreground="#FFFF00", background="#990099"), Label("blank space",background="#990099", foreground="#990099"), Label(ck, font=F1, "Development Team:", foreground="#FFFF00", background="#990099"), Label(ck, font=F1, "\t\tJoanna Ellis-Monaghan", foreground="#FFFFFF", background="#990099"), Label(ck, font=F1, "\t\tColin Kriwox", foreground="#FFFFFF", background="#990099"), Label(ck, font=F1, "\t\tLaura McLane", foreground="#FFFFFF", background="#990099"), Label(ck, font=F1, "\t\twith George Ashline and Zsuzsanna Kadas", foreground="#FFFFFF", background="#990099"), Label("blank space",background="#990099", foreground="#990099"), Button("Close", 'font'='F1', CloseWindow('AboutWin')) ) ) ), BoxLayout['ExploreBody']( BoxColumn(b, 'inset'=0, 'spacing'=4, BoxRow(s, TextBox('wrapped'=true, 'width'=80, 'height'=15, ck, 'font'='F1', 'editable'='false', 'value'= ############################ Explore TEXT (BELOW) ################## "Here are a few suggested activities to begin exploring the concepts illustrated by this Maplet.\n\n To begin with, try various level curves and viewing windows for the following functions:\n\nF(x,y)=x+y F(x,y)=sin(x)+sin(y) F(x,y)=sin(x)+cos(y) F(x,y)=sin(x+y)+cos(x+y) F(x,y)=x^y+y^x F(x,y)=1 \nF(x,y)=sin(x)+sin(y) F(x,y)=x^4+1 F(x,y)=(1)/(x^4) F(x,y)=sin(2*y) F(x,y)=(2^(1/2))*cos(2*x) F(x,y)=exp(sin(x)) \n \na. What is the general shape(s) of the level curves for your surface? If the general shape changes, describe which heights yield which type of curve.\nb. For each general shape, choose a representitive height and write the equation of the level curve. Does the 2D plot agree with your equation?\nc. For which parameter value(s), if any, are there no level curves for your surface? For which values are there " "transition" " curves, e.g. a single point, or a straight line, while the nearby heights give a different family of curves?\nd. Cover the surface plot window with your hand and try to imagine the surface just from the level curves (choose 10 or so level curves). Remove your hand. Do this until you can imagine the surface fairly accurately from the level curves. \ne. On the menu bar, select shading: z, and light model: none. Then put both the horizontal and vertical orientation sliders at 180. Compare the 3D plot with the 2D plot. How do they correspond and why? " ############################ Explore TEXT (ABOVE) ################## ) ), BoxRow(s, Button("Close", 'font'='F1', CloseWindow('ExploreWin') ) ) ) ), BoxLayout['MainBody']( BoxRow(c, BoxColumn(s, c, b, 'caption'="Multiple Level Curves", BoxRow(s,c, Plotter[graph](width=300,height=300), Slider[sliderright](c,lower=0,filled=true,majorticks=30,minorticks=10, orientation=vertical,snapticks=false,upper=360,value=70, onchange=assignGraph()) ), Slider[sliderbottom](c,lower=0,filled=true,majorticks=30,minorticks=10, orientation=horizontal,snapticks=false,upper=360,value=70, onchange=assignGraph()), TextBox('wrapped'=true, 'width'=35, 'height'=1, c, 'font'='F1', 'editable'='false','value'="Level curves of F(x,y)") , Plotter[graph2](width=300,height=300) ), BoxColumn(s, c, 'inset'=1, 'spacing'=1, BoxRow(c, b, 'caption'="Enter Function Below", inset=1, spacing=1, Label("F(x,y) = ", font='F1', c), TextField[Fxy](20, value="x^2+y^2", tooltip="Enter a function") ), BoxColumn(s, c, b, caption="View", BoxRow(s, c, Label("x domain:", font='F1', c), TextField[xlow](2, value=-5), Label(" .. ", font='F1', c), TextField[xhigh](2, value=5) ), BoxRow(s, c, Label("y domain:", font='F1', c), TextField[ylow](2, value=-5), Label(" .. ", font='F1', c), TextField[yhigh](2, value=5) ), Label("Zoom Factor", font='F1', c), Slider[zoomfactor](c,lower=-10,filled=true,upper=10, value=0, showlabels=true, minorticks=1, majorticks=10, onchange="", orientation = horizontal, snapticks=false, onchange=assignGraph()) ), BoxColumn(c, b, caption="Level Curves", inset=1, spacing=1, BoxColumn(s, c, background="#FFFF00", # ButtonGroup placed at top of page ['bg1'], RadioButton[opt1]("Single curve: e.g. [13.5]", group='RG0', value=true, font='F1', onclick=assignradio(ncurves,[13.5]),background="#FFFF00", tooltip="Enter a value for a single curve in the box below" ), RadioButton[opt2]("N curves: e.g. 10", group='RG0', font='F1', onclick=Evaluate(ncurves=10), background="#FFFF00", tooltip="Enter a value for the number of level curves in box below"), RadioButton[opt3]("Several curves: e.g. [5,10,17,30]", group='RG0', font='F1', onclick=Evaluate(ncurves="[5, 10, 17, 30]"),background="#FFFF00", tooltip="Enter a list of values for level curves in box below") ), BoxColumn(s, c, Label[lbl1]("Multiple Level Curves:", font='F1', c), TextField[ncurves](2, value=[13.5]) ) ), BoxRow(c, b, caption="commands", inset=1, spacing=1, Button("Plot surface and level curves", tooltip="click to plot function", onclick=assignGraph()), Button("Close", Shutdown()) ) ) # end column ) # end boxrow ), # end BoxLayout MenuBar['Menu']( Menu("Explore", MenuItem("Multiple Level Curves", onclick=RunWindow('ExploreWin')) ), Menu("Axes", RadioButtonMenuItem['RB1']("Normal",'value'=true,'group'='RG1', onclick=assignGraph()), RadioButtonMenuItem['RB2']("Boxed",'group'='RG1', onclick=assignGraph()), RadioButtonMenuItem['RB3']("Framed",'group'='RG1', onclick=assignGraph()), RadioButtonMenuItem['RB4']("None",'group'='RG1', onclick=assignGraph()) ), Menu("Scale", Menu("Surface", RadioButtonMenuItem['RB1c']("Unconstrained",'value'=true,'group'='RG2a', onclick=assignGraph()), RadioButtonMenuItem['RB2c']("Constrained",'group'='RG2a', onclick=assignGraph()) ), Menu("Multiple Level Curves", RadioButtonMenuItem['RB1lc']("Unconstrained",'value'=true,'group'='RG2b', onclick=assignGraph()), RadioButtonMenuItem['RB2lc']("Constrained",'group'='RG2b', onclick=assignGraph()) ) ), Menu("Projection", RadioButtonMenuItem['RB1p']("Orthogonal",'value'=true,'group'='RG3', onclick=assignGraph()), RadioButtonMenuItem['RB2p']("Fisheye",'group'='RG3', onclick=assignGraph()), RadioButtonMenuItem['RB3p']("Normal",'group'='RG3', onclick=assignGraph()) ), Menu("Shading", RadioButtonMenuItem['RB1s']("XYZ",'value'=true,'group'='RG4', onclick=assignGraph()), RadioButtonMenuItem['RB2s']("XY",'group'='RG4', onclick=assignGraph()), RadioButtonMenuItem['RB3s']("Z",'group'='RG4', onclick=assignGraph()), RadioButtonMenuItem['RB4s']("ZGRAYSCALE",'group'='RG4', onclick=assignGraph()), RadioButtonMenuItem['RB5s']("ZHUE",'group'='RG4', onclick=assignGraph()), RadioButtonMenuItem['RB6s']("None",'group'='RG4', onclick=assignGraph()) ), Menu("Lightmodel", RadioButtonMenuItem['RB1l']("Light1",'group'='RG5', onclick=assignGraph()), RadioButtonMenuItem['RB2l']("Light2",'value'=true, 'group'='RG5', onclick=assignGraph()), RadioButtonMenuItem['RB3l']("Light3",'group'='RG5', onclick=assignGraph()), RadioButtonMenuItem['RB4l']("Light4",'group'='RG5', onclick=assignGraph()), RadioButtonMenuItem['RB5l']("None",'group'='RG5', onclick=assignGraph()) ), Menu("Style", RadioButtonMenuItem['RB8t']("Patch",'group'='RG6', onclick=assignGraph()), RadioButtonMenuItem['RB2t']("Hidden",'group'='RG6', onclick=assignGraph()), RadioButtonMenuItem['RB3t']("WireFrame",'group'='RG6', onclick=assignGraph()), RadioButtonMenuItem['RB4t']("Contour",'group'='RG6', onclick=assignGraph()), RadioButtonMenuItem['RB5t']("PNG", value=true, 'group'='RG6', onclick=assignGraph()), RadioButtonMenuItem['RB6t']("PatchContour",'group'='RG6', onclick=assignGraph()), RadioButtonMenuItem['RB7t']("Line",'group'='RG6', onclick=assignGraph()), RadioButtonMenuItem['RB1t']("Point",'group'='RG6', onclick=assignGraph()) ), Menu("Help", MenuItem("Description", onclick=RunWindow('DescriptionWin')), MenuItem("Notes", onclick=RunWindow('NotesWin')), MenuItem("Maple Syntax", onclick=RunWindow('SyntaxWin')), MenuItem("Printing", onclick=RunWindow('PrintingWin')), MenuItem("About", onclick=RunWindow('AboutWin')) ) ) ): Maplets[Display] (LevelCurveMaplet);#