# Volume of Revolution Maplet # Copyright 2002 Waterloo Maple Inc. # # This maplet plots and computes the volume of the solid of revolution generated by rotating a function f(x) around either horizontal or vertical axis. # # Instructions # # The user enters a function f(x), a range [a, b] on the x-axis, and the axis of revolution. When you press the 'Plot' button, the surface of revolution is plotted. When you press the 'Volume' button, the volume of the solid is computed and displayed in a pop-up window. # # To run this maplet, click the !!! button in the tool bar. # restart; RevolutionMaplet := module() ############################################################ export iniMathML, addMathML, exportMathML, getLastMath, getRevolution, getVolume, runRevolutionMaplet: local helpStr, mlStr, save_string: ############################################################ ############################################################ mlStr := "": helpStr := "This maplet plots and computes the volume of the solid of revolution generated by rotating a function f(x) around the horizontal or the vertical axis. Instructions The user enters a function f(x), a range [a, b] on the x-axis, and the axis of revolution. When you press the 'Plot' button, the surface of revolution is plotted. When you press the 'Volume' button, the volume of the solid is computed and displayed in a pop-up window.": ############################################################ getLastMath:=proc() save_string; end proc: ############################################################ # pre: iniEqn :: algebraic expression # post: returns the Presentation MathML of iniEqn iniMathML := proc(iniEqn) MathML:-ExportPresentation(iniEqn); end proc: ############################################################ ############################################################ # pre: mathMLStr :: string, in form of Presentation MathML # addEqn :: algebraic expression addMathML := proc(mathMLStr, addEqn) local tree, cmc, child, children, nl, eqnSign; use XMLTools in tree := FromString(mathMLStr); cmc := ContentModelCount(tree); child := FromString(MathML:-ExportPresentation(addEqn)); children := ContentModel(child); nl := FromString(" "); eqnSign := Element("mo","="); tree := AddChild(tree,nl,cmc); tree := AddChild(tree,eqnSign,cmc+1); for child in children do cmc := ContentModelCount(tree); tree := AddChild(tree,child,cmc); end do: tree := MakeElement("mrow", [], ContentModel(tree) ): tree := Element("math", tree): ToString(tree): end use: end proc: ############################################################ ############################################################ getVolume := proc(boo1, p_func, p_a, p_b) local temp, temp2, str, view, value: use Maplets:-Tools, Student:-Calculus1 in str:=p_func: if str="" then return plots[textplot]([1,1,"No function input"], 'font'=[HELVETICA,18]): end if: temp:=p_a: if temp="" then return plots[textplot]([1,1,"Lower limit is missing"], 'font'=[HELVETICA,18]): end if: temp2:=p_b: if temp2="" then return plots[textplot]([1,1,"Upper limit is missing"], 'font'=[HELVETICA,18]): end if: str := cat(str, ", ", temp, "..", temp2): if not boo1 then str := cat(str, ", axis=vertical") end if: mlStr := iniMathML( VolumeOfRevolution(parse(str), output=integral) ): value := VolumeOfRevolution(parse(str)): mlStr := addMathML(mlStr, value): mlStr := addMathML(mlStr, evalf(value)): end use: end proc: ############################################################ getRevolution := proc(boo1, boo2, boo3, p_func, p_a, p_b, p_x1, p_x2, p_y1, p_y2, p_z1, p_z2) local temp, temp2, str, view, value: use Maplets:-Tools, Student:-Calculus1, StringTools in save_string:=""; str:=Trim(p_func): if str="" then return plots[textplot]([1,1,"No function entered"]): end if: temp:=Trim(p_a): if temp="" then return plots[textplot]([1,1,"Lower limit is missing"]): end if: temp2:=Trim(p_b): if temp2="" then return plots[textplot]([1,1,"Upper limit is missing"]): end if: str := cat(str, ", ", temp, "..", temp2): if not boo1 then str := cat(str, ", axis=vertical") end if: if not(boo2 or boo3) then return plots[textplot]( [1,1,"Select function or surface from Display Options"]): end if: if not boo2 then str := cat(str, ", showfunction=false") end if: if not boo3 then str := cat(str, ", showvolume=false") end if: view := ["DEFAULT","DEFAULT","DEFAULT"]: temp:=Trim(p_x1): temp2:=Trim(p_x2): if temp <> "" and temp2 <> "" then view[1]:=cat(temp, "..", temp2): end if: temp:=Trim(p_y1): temp2:=Trim(p_y2): if temp <> "" and temp2 <> "" then view[2]:=cat(temp, "..", temp2): end if: temp:=Trim(p_z1): temp2:=Trim(p_z2): if temp <> "" and temp2 <> "" then view[3]:=cat(temp, "..", temp2): end if: temp:=cat(", view=[", view[1], ", ", view[2], ", ", view[3], "]"): str := cat(str, temp): return VolumeOfRevolution(parse(str), output=plot): end use: end proc: ############################################################ ############################################################ runRevolutionMaplet := proc() local maplet, ML_opts, b, s, c, dc, lc: b := 'border'=true: s := 'inset'=0, 'spacing'=0: c := 'background'="#DDFFFF": dc := 'background'="#CCFFFF": lc := 'background'="#EEFFFF": use Maplets:-Elements in ############################################################ maplet := Maplet( 'onstartup'=RunWindow('mainWin'), ############################################################ Font['F1']('family'="Default", 'bold'='true', 'italic'='true'), Font['F2']('family'="Default", 'bold'='true', 'size'=14), ############################################################ MenuBar['MB']( Menu("File", MenuItem("Plot", 'onclick'='A1'), MenuSeparator(), MenuItem("Close", 'onclick'=Shutdown()) ), # end Menu/File Menu("Help", MenuItem("About this maplet", 'onclick'=RunWindow('helpWin')) ) # end menu/Help ), # end MenuBar ############################################################ Window['mainWin']('resizable'='false', 'title'="Calculus 1 - Volume of Revolution", 'menubar'='MB', BoxColumn(s, c, BoxRow(s, c, b, BoxRow(s, c, b, 'caption'="Enter a function and interval", Label("Function: ", 'font'='F2', c), TextField['TF_func'](16, lc, 'value'=1+cos(x), 'tooltip'="Enter a function"), Label(" a ", 'font'='F2', c), Label(" = ", 'font'='F1', c), TextField['TF_a']('value'=0, 3, lc, 'tooltip'="Lower limit"), Label(" b ", 'font'='F2', c), Label(" = ", 'font'='F1', c), TextField['TF_b']('value'="4*Pi", 3, lc, 'tooltip'="upper limit") ), # end BoxRow BoxRow('inset'=0, 'spacing'=3, c, b, 'caption'="Axis of revolution", RadioButton['RB']('caption'="horizontal axis", 'group'='BG_axis', 'value'=true, c), RadioButton('caption'="vertical axis", 'group'='BG_axis', c) ) # end BoxColumn ), # end BoxRow BoxRow(s, c, b, BoxColumn(s, c, b, 'caption'="Plot Window", Plotter['P'](lc) ), BoxColumn(s,c,b, 'inset'=0, 'spacing'=6, 'caption'="Volume of the solid", MathMLViewer['ML']('height'=370, 'width'=240, lc) ) # end BoxRow ), # end BoxRow BoxRow(c, s, BoxColumn(s, c, b, 'caption'="Display Options", BoxRow(s, c, CheckBox['CB2']('caption'="Show function", c, 'value'=true), CheckBox['CB3']('caption'="Show volume", c, 'value'=true) ), # end BoxRow BoxRow(s, c, Label("x", 'font'='F2', c), Label(" = ", 'font'='F1', c), TextField['x1']('width'=2, lc, 'value'=" "), Label(" .. ", 'font'='F2', c), TextField['x2']('width'=2, lc, 'value'=" "), Label(" y", 'font'='F2', c), Label(" = ", 'font'='F1', c), TextField['y1']('width'=2, lc, 'value'=" "), Label(" .. ", 'font'='F2', c), TextField['y2']('width'=2, lc, 'value'=" "), Label(" z", 'font'='F2', c), Label(" = ", 'font'='F1', c), TextField['z1']('width'=2, lc, 'value'=" "), Label(" .. ", 'font'='F2', c), TextField['z2']('width'=2, lc, 'value'=" ") ) # end BoxRow ), # end BoxColumn BoxColumn('inset'=10, 'spacing'=10, c, BoxRow('inset'=10, 'spacing'=10, c, Button(" Plot ", dc, 'onclick'='A1'), Button("Volume", dc, 'onclick'=Evaluate('target'='ML', 'function'='getVolume', Argument('RB'), Argument('TF_func', quotedtext='true'), Argument('TF_a', quotedtext='true'), Argument('TF_b', quotedtext='true'), 'waitforresult'='false') ), Button("Close", dc, Shutdown()) ) # end BoxRow ) # end BoxColumn ) # end BoxColumn ) ), # end Window ############################################################ Window['helpWin']( 'resizable'='false', 'title'="About the Volume of Revolution Maplet", BoxColumn(b, c, 'inset'=0, 'spacing'=10, BoxCell( TextBox('height'=15, 'width'=28, lc, 'foreground'="#333399", 'editable'='false', 'font'='F2', 'value'=helpStr ) # end TextBox ), # end BoxCell BoxRow(s, c, Button("Close", CloseWindow('helpWin'), dc) ) # end BoxRow ) # end BoxColumn ), # end helpWin ############################################################ ButtonGroup['BG_axis'](), ############################################################ Action['A1'](Evaluate('target'='P', 'function'='getRevolution', Argument('RB'), Argument('CB2'), Argument('CB3'), Argument('TF_func', quotedtext='true'), Argument('TF_a', quotedtext='true'), Argument('TF_b', quotedtext='true'), Argument('x1', quotedtext='true'), Argument('x2', quotedtext='true'), Argument('y1', quotedtext='true'), Argument('y2', quotedtext='true'), Argument('z1', quotedtext='true'), Argument('z2', quotedtext='true'), 'waitforresult'='false')) ): # end Maplet ############################################################ Maplets:-Display(maplet): end use: # end use end proc: # end proc ############################################################ end module: # end module RevolutionMaplet:-runRevolutionMaplet();