>    restart;
with(plots):

Checking set-up of iterated integrals

About this worksheet

Author and Date

Shannon Holland and Matthias Kawski

kawski@asu.edu

http://math.asu.edu/~kawski

original version MAPLE V, release 3, about 1995.

The original version is introduced and discussed in detail to the journal article

" 3D-graphics for iterated integrals" , MAPLE-Tech, 4 no.1, (1997) pp. 92-98.
http://math.asu.edu/~kawski/preprints/97mapletech.pdf

Supported in part by the National Science Foundation through EEC 92-21460 : The Foundation Coalition.
All rights reserved.

>   

Content, Purpose and Use

This code does NOT use computer algebra -- but it is convenient to be in the same language
in which iterated integrals may be evaluated.

The procedures intdraw and intdraw3d were originally introduced as the MAPLE  V release 4
package "asu". Long ago that package structure vecome defunct, and the worksheet now defines
the requisite functions in the first section -- just execute it in toto by hitting ENTER a few times.

The procedures intdraw and intdraw3d serve to visualize two- and three dimensional regions

{ (u,v,w) : u0 < u < u1, v0(u) < v < v1(u), w0(u,v) < w < w1(u,v) } defined by inequalities of

the form encountered in iterated integrals. The regions are sliced or represented by columns,
as indicated by the user, in a way that helps conceptualize the mental images behind iterated
integrals. The procedures recognize Cartesian, polar, cylindrical, and spherical coordinates
from the standard names x, y, z, r, theta, rho,  phi, and they provide detailed feedback for
common mistakes (e.g. ui not being constant).

The main purpose is to give immediate feedback to students, with enough detail to help them
identify and correct the wrong limits. Unlike a popular package written at TX A&M package,
these procedures "slice" the regions, and thus  give much more precise feeback.
Ultimately, students are expected to "work until the puicture is right", i.e. no grading is

required. To make this work, it is important that regions are defined for which the user
has a mental image (or an outline of the shape should be given).  


Note that the order of arguments is the same one as the usual order from left to right (outside to
inside) in an iterated integral. To evaluate the iterated integral using nested calls to int(...) the order
of the limits must be reversed! int(int(int(f(u,v,w),w=w0(u,v)..w1(u,v)),v=v0(u)..v1(u)),u=u0..u1);  

Updates and log of modifications.

The original package held up extremely well and was still running in release 7. In 2010, we

removed all references to the original "package" structure, and it is still running like a charm.
Also in March 2010, we added some sectioning, this intro section, and we reformatted the
input with usual indentations. However, the code itself is virtually unchanged from 1995.
We welcome any proficient MAPLE user to modernize notation, and suggest more
efficient coding. Also, we welcome more examples.

For a description of optional paramters such as grid, spacing, and preferences such as
slices see the original help section -- still in the old "package" format.

The examples are largely the original ones chosen by Shannon, although we updated
some choices for finer partitons as today's compouers are a little faster.
Eventually, the default grid sizes in the programs should be increased, too.

Mar 7, 2010: Updated examples.

>   

Execute this section to define intdraw/intdraw3d

MakeGrid2D  creates centerpoints for columns and is called from intdraw

>    MakeGrid2D:=proc(a,a0,a1,b,b0,b1,CountA,CountB,SpaceA,
                 SpaceB,Coords,g,CountBArg,SpaceBArg,
                 NASpaceing,NBSpaceing)

>    local i, j, k, aTable, bTable, b0Table, b1Table,
      bMin, bMax, CenterGrid, DeltaA, DeltaB:

>    if evalf(a0)>evalf(a1)
   then ERROR(`lower limit exceeds upper limit`)
   fi:

>    if evalf(a0)=evalf(a1)
   then ERROR(`lower limit equal to upper limit`)
   fi:

>    if NASpacing = true or CountA = 1
   then
   DeltaA:=evalf((a1-a0)/(CountA))
   else
   DeltaA:=evalf((a1-a0)/(CountA-SpaceA))
   fi:

>    for k to (CountA) do
    aTable[k]:=evalf(a0+(k-SpaceA/2)*DeltaA-DeltaA/2):
    od:

>    if type(evalf(subs(a=aTable[1],b0)),constant)<>true
   or
   type(evalf(subs(a=aTable[1],b1)),constant)<>true
   then
   ERROR(`invalid boundaries`)
   fi:

>    for k to (CountA) do
    b0Table[k]:=evalf(subs(a=aTable[k],b0)):
    b1Table[k]:=evalf(subs(a=aTable[k],b1)):
    od:

>    bMax:=max(seq(op(op(k,[entries(b1Table)])),
              k=1..nops([entries(b1Table)])),

>    evalf(subs(a=a0,b1)),evalf(subs(a=a1,b1))):

>    bMin:=min(seq(op(op(k,[entries(b0Table)])),
              k=1..nops([entries(b0Table)])),

>    evalf(subs(a=a0,b0)),evalf(subs(a=a1,b0))):

>    if bMin>bMax
   then ERROR(`lower limit exceeds upper limit`)
   fi:

>    if NBSpacing = true or CountB=1
   then
   DeltaB:=evalf((bMax-bMin)/(CountB))
   else
   DeltaB:=evalf((bMax-bMin)/(CountB-SpaceB))
   fi:

>    for j to (CountB)
    do
    bTable[j]:=evalf(bMin+(j-SpaceB/2)*DeltaB-DeltaB/2)
    od:

>    if op(2,g) = theta or SpaceBArg = true or CountBArg = true
   then
   for k to (CountA) do
       for j to (CountB) do
           if (b0Table[k]<bTable[j])and(bTable[j]<b1Table[k])
              then
              CenterGrid[k,j]:=aTable[k],bTable[j]
              fi
           od
       od:
   else
   for k to (CountA) do
         CenterGrid[k]:=aTable[k]
       od
   fi:

>    if eval(CenterGrid)= CenterGrid
   then ERROR(`invalid boundaries`)
   fi:

>    eval(CenterGrid),DeltaA,DeltaB:

>    end:

MakeCorners2D  takes centerpoints and creates corners of boxes. It is called from intdraw.

>    MakeCorners2D:=proc(CentersTable, a, b, b0, b1, SpaceA, SpaceB,
      DeltaA, DeltaB, xPlace, yPlace, g, CountBArg, SpaceBArg)
local f,i,ctr,u0,u1,w0,w1,CornersTemp:
for i from 1 to nops([entries(CentersTable)])
    do
    ctr:=op(i,[entries(CentersTable)]):
    u0:=evalf(op(1, ctr)-(1-SpaceA)*DeltaA/2):
    u1:=evalf(op(1, ctr)+(1-SpaceA)*DeltaA/2):
    if op(2,g)<>theta and CountBArg <> true
       and SpaceBArg <> true
       then
       w0:=subs(a=((u1+u0)/2),b0):
       w1:=subs(a=((u1+u0)/2),b1):
       if type(w0,constant)<> true or type(w1,constant)<> true
          then
          ERROR(`Second/third boundary error`)
          fi:
       else
       w0:=eval(op(2,ctr)-(1-SpaceB)*DeltaB/2):
       w1:=eval(op(2,ctr)+(1-SpaceB)*DeltaB/2):
       fi:
    f:=[[u0,u1],[w0,w1]]:
    CornersTemp[i]:=[[op(1,op(xPlace,f)),op(2,op(yPlace,f))],
                     [op(2,op(xPlace,f)),op(2,op(yPlace,f))],
                     [op(1,op(xPlace,f)),op(1,op(yPlace,f))],
                     [op(2,op(xPlace,f)),op(1,op(yPlace,f))]]
    od:
eval(CornersTemp)
end:

MakePoly2D  takes corners and creates the 6 sides of the boxes. called from intdraw.

>    MakePoly2D:=proc(Corners)
local TempPolys,i:
for i to nops([entries(Corners)]) do
    TempPolys[i]:=[op(1, Corners[i]),op(2,Corners[i]),
                   op(4,Corners[i]),op(3,Corners[i])]:
   od:
eval(TempPolys)
end:

ChangeCoords2D changes coordinates from Cartesian to Coords called by `intdraw`

>    ChangeCoords2D:=proc(Corners,Coords)
local j,k,CornersTemp:
if Coords=cylindrical
   then
   for k to nops([entries(Corners)]) do
       CornersTemp[k]:=[seq(
           [op(1,op(j,Corners[k]))*cos(op(2,op(j,Corners[k]))),
            op(1,op(j,Corners[k]))*sin(op(2,op(j,Corners[k])))],
       j = 1..4)]
       od:
   elif Coords=Cartesian
      then
      CornersTemp:=eval(Corners)
   fi:
eval(CornersTemp)
end:

intdraw :  Main Program, draws the sliced 2-D regions.

>    intdraw:=proc()
local a ,a0, a1,b ,b0,b1, CountA,CountB,SpaceA, SpaceB,TempArgs,
   CentersTable,CornersTable,Coords,TempTable,PolygonsTable,
   PlotTitle,i,j,gg,DeltaA,DeltaB,xPlace,yPlace,Axes,Scaling,Style,
   xTick,yTick,CountArgs,SpaceArgs,SpaceBArg, CountBArg,TitleArgs,
   ScalingArgs,kk,Options,ggg,NASpacing, NBSpacing:

>    ScalingArgs:=false: CountArgs:=false:SpaceArgs:=false:TitleArgs:=false:

>    SpaceBArg:=false: CountBArg:Options:=[]:NASpacing:=false:

>    NBSpacing :=false:

>    if nargs < 2
   then
   ERROR(`Boundaries must be entered as first 2 arguments`)
   fi:

>    if type(args[1],`=`)=false or
   type(args[2],`=`)=false or    
   type(op(2,args[1]),range)=false or
   type(op(2,args[2]),range)=false or
   type(op(2,args[2]),range)=false
   then
   ERROR(`Boundaries must be written as var=lower limit..upper limit`)
   fi:
a:=op(1,args[1]):
a0:=evalf(op(1, op(2,args[1]))):
a1:=evalf(op(2, op(2,args[1]))):
b:=op(1,args[2]):
b0:=evalf(op(1, op(2,args[2]))):
b1:=evalf(op(2, op(2,args[2]))):
if nargs>2
   then
   for kk from 3 to nargs do
       if op(1,args[kk]) = grid
          then
          CountArgs:=true:
          CountA:=round(evalf(op(1, op(2,args[kk])))):
          if nops(op(2,args[kk]))>1
             then
             CountBArg := true:
             CountB:=round(evalf(op(2, op(2,args[kk])))):
             else CountB:=15
             fi:
          elif op(1,args[kk]) = spaces
             then
             SpaceArgs:=true:
             SpaceA:=evalf(op(1, op(2,args[kk]))):
             if nops(op(2,args[kk]))>1
                then
                SpaceBArg:=true:
                SpaceB:=evalf(op(2, op(2,args[kk]))):
                else SpaceB:=.3
                fi:
             elif op(1,args[kk])=title
                  then
                  TitleArgs:=true:
                  PlotTitle :=op(2,args[kk])
             elif op(1,args[kk])=scaling
                 then
                 ScalingArgs:=true:
                 Scaling:=op(2,args[kk])
                 else
                 Options:=[op(Options),args[kk]]
           fi
       od
   fi:
if TitleArgs=false
   then PlotTitle:=cat(a,` `,b)
   fi:
if ScalingArgs=false
   then Scaling :=CONSTRAINED
   fi:
if CountArgs=false
   then
   CountA:=15:
   CountB:=15
   fi:
if SpaceArgs=false
   then
   SpaceA:=.3:
   SpaceB:=0 fi:
if SpaceA<0 or SpaceA>1 or SpaceB<0 or SpaceB>1  
   then
   ERROR(`spaces arguments must be between or equal to 0 and 1`) fi:
ggg:=[a,b,c]:
if member(x,ggg)=true and member(y,ggg)=true
   then
   Coords:=Cartesian:
   if x <> 'x'or  y <>'y'  
      then
      ERROR(`x, and y  are key variables and must be`,
            `cleared before running program, (ex x:='x')`)
      fi:
   member(x,ggg,'xPlace'):
   member(y,ggg,'yPlace')
   elif member(r,ggg)=true and member(theta,ggg)=true
      then
      Coords:=cylindrical:
      member(r,ggg,'xPlace'):
      member(theta,ggg,'yPlace'):
      if r <> 'r' or theta <>'theta'
         then
         ERROR(`r, and theta  are key variables and must be`,
               `cleared before running program, (ex r:='r')`)
         fi:
      if yPlace = 1 and evalf(a1-a0)=evalf(2*Pi)
         then NASpacing :=true
         fi:
      if yPlace = 2 and evalf(b1-b0)=evalf(2*Pi)
         then NBSpacing :=true
         fi:
      else ERROR(`Cartesian coords accepts only x, and y variables`,
                 `polar coords accepts only r, and theta variables`)
      fi:
TempTable:=MakeGrid2D(a,a0,a1,b,b0,b1,CountA,CountB,SpaceA,
                      SpaceB,Coords,ggg, CountBArg, SpaceBArg):
CentersTable:=TempTable[1]:DeltaA:=TempTable[2]:
DeltaB:=TempTable[3]:
CornersTable:=MakeCorners2D(CentersTable,a,b,b0,b1,SpaceA,
                            SpaceB,DeltaA,DeltaB,xPlace,yPlace,
                            ggg, CountBArg, SpaceBArg):
CornersTable:=ChangeCoords2D(CornersTable,Coords):
PolygonsTable:=MakePoly2D(CornersTable,CentersTable):
polygonplot({(seq(PolygonsTable[i],
                  i=1 .. nops([entries(CentersTable)])))},
                  title=PlotTitle,scaling = Scaling, op(Options))
end:

MakeGrid creates centerpoints for columns. called from `intdraw3d`

>    MakeGrid:=proc(a, a0, a1, b, b0, b1, c, c0, c1, CountA,
               CountB, CountC, SpaceA, SpaceB, SpaceC, Coords,  
               g, NASpacing, NBSpacing, NCSpacing,CSArg)
local i, j, k, aTable, bTable, b0Table, b1Table, cTable,
      c0Table, c1Table, bMin, bMax, cMax, cMin, CenterGrid,
      DeltaA, DeltaB, DeltaC:
if evalf(a0)>evalf(a1)
   then
   ERROR(`lower limit exceeds upper`)
   fi:
if evalf(a0)=evalf(a1)
   then
   ERROR(`lower equal to upper`)
   fi:
if NASpacing = true  
   then
   DeltaA:=evalf((a1-a0)/(CountA))
   else
   DeltaA:=evalf((a1-a0)/(CountA-SpaceA))
   fi:
for k to (CountA) do
   aTable[k]:=evalf(a0+(k-SpaceA/2)*DeltaA-DeltaA/2):
   od:
if type(evalf(subs(a=aTable[1],b0)),constant)<>true or
   type(evalf(subs(a=aTable[1],b1)),constant)<>true
   then
   ERROR(`invalid first or second boundary`)
   fi:
for k to (CountA) do
   b0Table[k]:=evalf(subs(a=aTable[k],b0)):
   b1Table[k]:=evalf(subs(a=aTable[k],b1)):
   od:
bMax:=max(seq(op(op(k,[entries(b1Table)])),
              k=1..nops([entries(b1Table)])),
          evalf(subs(a=a0,b1)),
          evalf(subs(a=a1,b1))):
bMin:=min(seq(op(op(k,[entries(b0Table)])),
              k=1..nops([entries(b0Table)])),
          evalf(subs(a=a0,b0)),
          evalf(subs(a=a1,b0))):
if bMin>bMax
   then
   ERROR(`lower limit exceeds upper`)
   fi:
if NBSpacing = true  
   then
   DeltaB:=evalf((bMax-bMin)/(CountB))
   else
   DeltaB:=evalf((bMax-bMin)/(CountB-SpaceB))
   fi:
for j to (CountB) do
    bTable[j]:=evalf(bMin+(j-SpaceB/2)*DeltaB-DeltaB/2)
    od:
if op(3,g)<>theta and op(3,g)<>phi and CSArg = false
   then
   DeltaC:=0:
   for k to (CountA) do
       for j to (CountB) do
          if (b0Table[k]<bTable[j])and(bTable[j]<b1Table[k])
              then
              CenterGrid[k,j]:=aTable[k],bTable[j]
              fi
          od
       od:
   else
   if type(evalf(subs(a=aTable[1], b=bTable[1],c0)),constant)<>true or
      type(evalf(subs(a=aTable[1], b=bTable[1],c1)) ,constant) <> true
      then
      ERROR(`invalid boundaries`)
      fi:
   for k to (CountA) do
      for j to (CountB) do
         if (b0Table[k]<bTable[j])and(bTable[j]<b1Table[k])
            then
            c0Table[j,k]:=evalf(subs(a=aTable[k], b=bTable[j],c0)):
            c1Table[j,k]:=evalf(subs(a=aTable[k], b=bTable[j],c1)):
            fi
         od
      od:
   cMax:=max(seq(op(op(k,[entries(c1Table)])),
                 k=1..nops([entries(c1Table)])),
             evalf(subs(a=a0,subs(b=b0,c1))),
             evalf(subs(a=a0,subs(b=b1,c1))),
             evalf(subs(a=a1,subs(b=b0,c1))),
             evalf(subs(a=a1,subs(b=b1,c1)))):
   cMin:=min(seq(op(op(k,[entries(c0Table)])),
                 k=1..nops([entries(c0Table)])),
             evalf(subs(a=a0,subs(b=b0,c0))),
             evalf(subs(a=a1,subs(b=b1,c0))),
             evalf(subs(a=a1,subs(b=b0,c0))),
             evalf(subs(a=a1,subs(b=b1,c0)))):
   if cMin>cMax
      then
      ERROR(`lower limit exceeds upper`)
      fi:
   if NCSpacing = true
      then
      DeltaC:=(cMax-cMin)/(CountC)
      else
      DeltaC:=evalf((cMax-cMin)/(CountC-SpaceC))
      fi:
for k to CountC do
   cTable[k]:=evalf(cMin+(k-SpaceC/2)*DeltaC-DeltaC/2):
   od:
for i to (CountA) do
   for j to (CountB) do
      for k to (CountC) do
         if (b0Table[i]<bTable[j]) and
            (bTable[j]<b1Table[i]) and
            (evalf(subs(a=aTable[i],b=bTable[j],c0))<cTable[k]) and
            (cTable[k]<evalf(subs(a=aTable[i],b=bTable[j],c1)))
            then
            CenterGrid[i,j,k]:=aTable[i],bTable[j],cTable[k]
            fi
         od
      od
   od
fi:
if eval(CenterGrid)= CenterGrid
   then
   ERROR(`invalid boundaries`)
   fi:
eval(CenterGrid),DeltaA,DeltaB,DeltaC:
end:

MakeCorners  takes centerpoints and creates the corners of  the boxes called from `intdraw3d`

>    MakeCorners:=proc(CentersTable, a, b, c, c0, c1,
                  SpaceA, SpaceB, SpaceC,
                  DeltaA, DeltaB, DeltaC,
                  xPlace, yPlace, zPlace, g, CSArg)
local f, i, ctr, u0, u1, v0, v1, w0, w1,CornersTemp:
for i from 1 to nops([entries(CentersTable)]) do
    ctr:=op(i,[entries(CentersTable)]):
    u0:=evalf(op(1, ctr)-(1-SpaceA)*DeltaA/2):
    u1:=evalf(op(1, ctr)+(1-SpaceA)*DeltaA/2):
    v0:=evalf(op(2, ctr)-(1-SpaceB)*DeltaB/2):
    v1:=evalf(op(2, ctr)+(1-SpaceB)*DeltaB/2):
    if op(3,g)<>theta and op(3,g)<>phi  and CSArg = false
       then
       w0:=subs(a=((u1+u0)/2),b=((v1+v0)/2),c0):
       w1:=subs(a=((u1+u0)/2),b=((v1+v0)/2),c1):
       if type(w0,constant)<> true or type(w1,constant)<> true
          then
          ERROR(`Second/third boundry error`)
          fi:
          else
       w0:=eval(op(3,ctr)-(1-SpaceC)*DeltaC/2):
       w1:=eval(op(3,ctr)+(1-SpaceC)*DeltaC/2):
       fi:
     f:=[[u0,u1],[v0,v1],[w0,w1]]:
     CornersTemp[i]:=[
        [op(1,op(xPlace,f)),op(1,op(yPlace,f)),op(1,op(zPlace,f))],
        [op(1,op(xPlace,f)),op(1,op(yPlace,f)),op(2,op(zPlace,f))],
        [op(1,op(xPlace,f)),op(2,op(yPlace,f)),op(1,op(zPlace,f))],
        [op(1,op(xPlace,f)),op(2,op(yPlace,f)),op(2,op(zPlace,f))],
        [op(2,op(xPlace,f)),op(1,op(yPlace,f)),op(1,op(zPlace,f))],
        [op(2,op(xPlace,f)),op(1,op(yPlace,f)),op(2,op(zPlace,f))],
        [op(2,op(xPlace,f)),op(2,op(yPlace,f)),op(1,op(zPlace,f))],
        [op(2,op(xPlace,f)),op(2,op(yPlace,f)),op(2,op(zPlace,f))]]
     od:

>    eval(CornersTemp)

>   

>    end:

MakePoly  takes corners and creates the 6 sides of the boxes. called from `intdraw3d`

>    MakePoly:=proc(Corners)
local i, TempPolys:
for i to nops([entries(Corners)]) do
   TempPolys[i,1]:=[op(1, Corners[i]),op(2,Corners[i]),
                    op(4,Corners[i]),op(3,Corners[i])]:
   TempPolys[i,2]:=[op(5, Corners[i]),op(6,Corners[i]),
                    op(8,Corners[i]),op(7,Corners[i])]:
   TempPolys[i,3]:=[op(2, Corners[i]),op(4,Corners[i]),
                    op(8,Corners[i]),op(6,Corners[i])]:
   TempPolys[i,4]:=[op(4, Corners[i]),op(3,Corners[i]),
                    op(7,Corners[i]),op(8,Corners[i])]:
   TempPolys[i,5]:=[op(3, Corners[i]),op(1,Corners[i]),
                    op(5,Corners[i]),op(7,Corners[i])]:
   TempPolys[i,6]:=[op(1, Corners[i]),op(2,Corners[i]),
                    op(6,Corners[i]),op(5,Corners[i])]:
   od:
eval(TempPolys)
end:

ChangeCoords  changes coordinates from Cartesian to Coords called by `intdraw3d`

>    ChangeCoords:=proc(Corners,Coords)
local j, k, CornersTemp:
if Coords=cylindrical
   then
   for k to nops([entries(Corners)]) do
       CornersTemp[k]:=[seq([
           op(1,op(j,Corners[k]))*cos(op(2,op(j,Corners[k]))),
           op(1,op(j,Corners[k]))*sin(op(2,op(j,Corners[k]))),
           op(3,op(j,Corners[k]))],j = 1..8)]
       od:
elif Coords=spherical
   then
   for k to nops([entries(Corners)]) do
       CornersTemp[k]:=[seq([
           op(1,op(j,Corners[k]))*sin(op(2,op(j,Corners[k])))*cos(op(3,op(j,Corners[k]))),
           op(1,op(j,Corners[k]))*sin(op(2,op(j,Corners[k])))*sin(op(3,op(j,Corners[k]))),
           op(1,op(j,Corners[k]))*cos(op(2,op(j,Corners[k])))],j = 1..8)]
       od:
elif Coords=Cartesian
   then
   CornersTemp:=eval(Corners)
   fi:
eval(CornersTemp)
end:

intdraw3d  Main Program, draws region of 3-D integral

>    intdraw3d:=proc()

>    local a ,a0, a1,b ,b0,b1, c, c0, c1, CountA, CountB, CountC,
      SpaceA, SpaceB, SpaceC, TempArgs, CentersTable,
      CornersTable, Coords, TempTable, PolygonsTable,
      PlotTitle, i, j, gg, DeltaA, DeltaB, DeltaC,
      xPlace, yPlace, zPlace, Scaling, Style,
      xTick, yTick, zTick, aTemp, bTemp, cTemp,
      CountArgs, SpaceArgs, TitleArgs, ScalingArgs,
      kk, Options, ggg, NASpacing, NBSpacing, NCSpacing,
      CSArg, Labels, LabelsArgs, Axes, AxesArgs:
ScalingArgs:= false:
CountArgs  := false:
SpaceArgs  := false:
AxesArgs   := false:
TitleArgs  := false:
Options    := []:
NASpacing  := false:
NBSpacing  := false:
NCSpacing  := false:
CSArg      := false:
LabelsArgs := false:
if nargs < 3
   then
   ERROR(`Boundaries must be entered as first 3 arguments`)
   fi:
if type(args[1],`=`)=false or
   type(args[2],`=`)=false or
   type(args[3],`=`)=false or
   type(op(2,args[1]),range)=false or
   type(op(2,args[2]),range)=false or  
   type(op(2,args[2]),range)=false
   then
   ERROR(`Boundaries must be written as var=range`)
   fi:
a:=op(1,args[1]):
a0:=evalf(op(1, op(2,args[1]))):
a1:=evalf(op(2, op(2,args[1]))):
b:=op(1,args[2]):
b0:=evalf(op(1, op(2,args[2]))):
b1:=evalf(op(2, op(2,args[2]))):
c:=op(1,args[3]):
c0:=evalf(op(1, op(2,args[3]))):
c1:=evalf(op(2, op(2,args[3]))):
if nargs>3
   then
   for kk from 4 to nargs do
       if op(1,args[kk]) = grid
          then
          CountArgs:=true:
          CountA:=evalf(op(1, op(2,args[kk]))):
          if nops(op(2,args[kk]))>1
             then
             CountB:=evalf(op(2, op(2,args[kk]))):
             else
             CountB:=5:
             fi:
          if nops(op(2,args[kk]))>2
             then
             CountC:=evalf(op(3,op(2,args[kk]))):
             CSArg := true
             else
             CountC:=5:
             fi:
        elif op(1,args[kk]) = spaces
             then
             SpaceArgs:=true:
             if op(1,op(2,args[kk]))= slices
                then
                SpaceA:=.8:
                SpaceB:=.1:
                SpaceC:=0:
                else
                SpaceA:=evalf(op(1, op(2,args[kk]))):
                if nops(op(2,args[kk]))>1
                   then
                   SpaceB:=evalf(op(2, op(2,args[kk]))):
                   else SpaceB:=.3
                   fi:
                if nops(op(2,args[kk]))>2
                   then
                   SpaceC:=evalf(op(3,op(2,args[kk]))):
                   CSArg:=true
                   else
                   SpaceC:=0
                   fi:
                fi:
             elif op(1,args[kk])=title
                then
                TitleArgs:=true:
                PlotTitle :=op(2,args[kk])
             elif op(1,args[kk])=scaling
                then
                ScalingArgs:=true:
                Scaling:=op(2,args[kk])
             elif op(1,args[kk])= axes
                then
                AxesArgs:=true:
                Axes := op(2,args[kk])
             elif op(1,args[kk])= labels
                then
                LabelsArgs := true:
                Labels :=op(2,args[kk])
                else
                Options:=[op(Options),args[kk]]
                fi
             od
          fi:
       if LabelsArgs=false
          then
          Labels:=[`x`,`y`,`z`]
          fi:
if AxesArgs=false
   then
   Axes:=FRAME
   fi:
if TitleArgs=false
   then
   PlotTitle:=cat(a,` `,b,` `,c)
   fi:
if ScalingArgs=false
   then
   Scaling :=CONSTRAINED
   fi:
if CountArgs=false
   then
   CountA:=5:
   CountB:=5:
   CountC:=5
   fi:
if SpaceArgs=false
   then
   SpaceA:=.3:
   SpaceB:=.3:
   SpaceC:=0
   fi:
if SpaceA<0 or SpaceA>1 or SpaceB<0 or
   SpaceB>1 or SpaceC<0 or SpaceC>1
   then
   ERROR(`spaces arguments must range from 0 and 1`)
   fi:
if CountA<=0 or CountB<=0 or CountC<=0
   then
   ERROR(`grid arguments must be integers that are greater than 0`)
   fi:
ggg:=[a,b,c]:
if member(x,ggg)=true and
   member(y,ggg)=true and
   member(z,ggg)=true
   then
   Coords:=Cartesian:
   if x <> 'x'or  y <>'y' or z <> 'z'
      then
      ERROR(`x, y, and z  are key variables and must be`,
            `cleared before running program, (ex x:='x')`)
      fi:
   member(x,ggg,'xPlace'):
   member(y,ggg,'yPlace'):
   member(z,ggg,'zPlace'):
elif member(r,ggg)=true and
     member(theta,ggg)=true and
     member(z,ggg)= true
   then
   Coords:=cylindrical:
   if theta <> 'theta' or z <> 'z' or r<>'r'  
      then
      ERROR(`z, theta, and r are key variables and must be`,
            `cleared before running program, (ex r:='r')`)
      fi:
   member(r,ggg,'xPlace'):
   member(theta,ggg,'yPlace'):
   member(z,ggg,'zPlace'):
if yPlace = 1 and evalf(a1-a0)=evalf(2*Pi)
   then
   NASpacing :=true fi:
if yPlace = 2 and evalf(b1-b0)=evalf(2*Pi)
   then NBSpacing :=true
   fi:
if yPlace = 3 and evalf(c1-c0)=evalf(2*Pi)
   then NCSpacing :=true
   fi:
elif member(rho,ggg)=true and
     member(phi,ggg)=true and
     member(theta,ggg)=true
   then
   Coords:=spherical:
   member(rho,ggg,'xPlace'):
   member(phi,ggg,'yPlace'):
   member(theta,ggg,'zPlace'):
   if theta <> 'theta' or rho <>'rho' or phi <> 'phi'
       then
       ERROR(`theta, rho, and phi are key variables and must be`,
             `cleared before running program, (ex rho:='rho')`)
       fi:
   if (yPlace = 1 or zPlace = 1) and evalf(a1-a0) = evalf(2*Pi)
      then
      NASpacing :=true
      fi:
   if (yPlace = 2 or zPlace = 2) and evalf(b1-b0) =evalf(2*Pi)
      then
      NBSpacing:=true
      fi:
   if (yPlace = 3 or zPlace = 3) and evalf(c1-c0) = evalf(2*Pi)
      then NCSpacing :=true
      fi:
   else ERROR(`Cartesian coords accepts only x, y, and z variables`,
              `cylindrical coords accepts only r, theta, and z variables`,
              `spherical coords accepts only rho, theta, and phi variables`)
   fi:
TempTable:=MakeGrid(
      a,a0,a1,b,b0,b1,c,c0,c1,CountA,CountB,CountC,
      SpaceA,SpaceB,SpaceC,Coords,ggg,
      NASpacing,NBSpacing, NCSpacing, CSArg):
CentersTable:=TempTable[1]:
DeltaA:=TempTable[2]:
DeltaB:=TempTable[3]:DeltaC:=TempTable[4]:
CornersTable:=MakeCorners(
      CentersTable,a,b,c,c0,c1,
      SpaceA,SpaceB,SpaceC,DeltaA,DeltaB,DeltaC,
      xPlace,yPlace,zPlace,ggg,CSArg):
CornersTable:=ChangeCoords(CornersTable,Coords):
PolygonsTable:=MakePoly(CornersTable,CentersTable):
polygonplot3d({(seq(seq(PolygonsTable[i,j],
                        j=1..6),
                    i=1 .. nops([entries(CentersTable)])))},
               title=PlotTitle,scaling=Scaling,
               axes=Axes,labels=Labels,op(Options))

>    end:

>   

Old help pages for the MAPLE V release 4 "package" asu

>    `help/text/intdraw3d`:=TEXT(

>    `FUNCTION: intdraw3d   -creates a picture of a parameterized `,

>    `                           three-dimensional region that is sliced according to`,

>    `                           the selected parameterization`,

>    ` `,

>    `CALLING SEQUENCE:`,

>    `    intdraw3d(boundaries);`,

>    `    intdraw3d(boundaries, intdraw3d options, plot3d options);`,

>    ` `,

>    `PARAMETERS:`,

>    `boundaries     -  three ranges in the form u=u0..u1,v=v0..v1,w=w0..w1`,

>    `                u0 and u1 must be constants, v0 and v1 must be  expressions `,

>    `                depending on the variable u only, w0 and w1 are expressions`,

>    `                that may depend on the variables u and v. `,

>    `                The variables u,v,w may represent either rectangular, cylindrical`,

>    `                or spherical coordinates, see below. `,

>    `  `,

>    `INTDRAW3D OPTIONS:`,

>    `grid   -  determines the numbers of boxes to be drawn. The call grid=[m,n]`,

>   

>    `             is interpreted as grid=[m,n,1], i.e. drawing columns, unless the `,

>    `             variable w is either theta or phi, in which case it is interpreted as `,

>    `             grid=[m,n,5]. The default is grid=[5,5,5]. `,

>    ` `,

>    `spaces - determines the spacing between the boxes (columns). `,

>    `               Its argument is a list of three constants between 0 and 1. `,

>    `              Default is spaces=[.3,.3,0]. The option  spaces = slices  is `,

>    `              equivalent to spaces= [.8,.1,0]. `,

>    ` `,

>    `SYNOPSIS:`,

>    `-these defaults were choosen because they produced the nicest and `,

>    ` most informative pictures, they may be changed easily in the plot3d `,

>    ` window or in the intdraw3d calling statement (see examples bellow)`,

>    `-for Cartesian coordinates, variables used must be x, y, and z.`,

>    `-for cylindrical coordinates, variables used must be r, theta and z.`,

>    `-for spherical coordinates, variables used must be rho, phi, and theta.`,

>    `-scaling (plot3d option) default in intdraw3d is CONSTRAINED`,

>    `-labels (plot3d option) default in intdraw3d is [x,y,z]`,

>    `-axes (plot3d option) default in intdraw3d is FRAME`,

>    ` `,

>    `#if you run all examples at once your computer will be working for a while`,

>    `#Cartesian coordinates examples (wedges)`,

>    `intdraw3d(x= -1..0 , y= -sqrt(1-x^2) ..sqrt(1-x^2) , z= -x..0 );`,

>    `intdraw3d(z= -1..0 , y= -sqrt(1-z^2) ..sqrt(1-z^2) , x= -z..0 , spaces=[.5,0],`,

>    `axes=BOX);`,

>    `intdraw3d(z= -1..1,x= -sqrt(1-z^2)..sqrt(1-z^2),y= -sqrt(1-x^2-z^2)..`,

>    `sqrt(1-z^2-x^2),spaces=[0,0], style = PATCHNOGRID);`,

>    ` `,

>    `#cylindrical coordinates examples`,

>    `intdraw3d(theta = 0..2*Pi, r=0..1/sqrt(2), z=r..sqrt(1-r^2), spaces=[0,0]);`,

>    `intdraw3d(z= 0..Pi, r=0..Pi, theta=0..Pi, grid=[3,2], orientation = [-70,60], `,

>    `spaces=[.4,.4]);`,

>    `intdraw3d(r=3..5, theta = 0..2*Pi, z=-sqrt(1-(4-r)^2).. sqrt(1-(4-r)^2), `,

>    `grid = [5,10 ], axes = BOX );`,

>    ` `,

>    `I1:= intdraw3d(r=0..3, theta = 0..3*Pi/4, z=-1..1, spaces=[.4,.4],grid = 4,`,

>    `color = green, style = patchnogrid, light = [0,50 , .9,.9,.9], `,

>    `light = [50,0,.6,.6,.6], ambientlight= [.4,.4,.4]):`,

>    `I2:= intdraw3d(r=3..3*sqrt(2), z=-1..1, theta = arccos(3/r)..arcsin(3/r),`,

>    `grid=[5,3,8],spaces=[.4,.4],color = blue, style = patchnogrid):`,

>    `I3:= intdraw3d(r=3..3*sqrt(2),z=-1..1, theta=Pi-arcsin(3/r)..3/4*Pi,`,

>    `spaces=[.4,.4],grid = [5,3,6], color = red, style = patchnogrid):`,

>    `display3d({I1,I2,I3}, orientation = [-70,50]);`,

>    ` `,

>    `#spherical coordinates examples`,

>    `intdraw3d(rho=0..1, phi = 0..Pi, theta=0..2*Pi,grid=[1],spaces=[.5,.5]);`,

>    `intdraw3d(rho=0..1,theta= -Pi/2..Pi/2,phi=arctan(1/cos(theta))..Pi/2,`,

>    `grid=[4,6,12]);`,

>    `# changing the spacing`,

>    `intdraw3d(rho=0..1,theta= -Pi/2..Pi/2,phi=arctan(1/cos(theta))..Pi/2,`,

>    `grid=[4,6,12],spaces=[.9,0]);`,

>    `intdraw3d(rho=0..1, theta = 0..2*Pi, phi=0..Pi,grid=[1,8,8], spaces=[0,0]);`,

>    ` `,

>    `#movie examples     (may take a while)`,

>    `with(plots):display([seq(intdraw3d(x=-1..1,y=-sqrt(1-x^2)..sqrt(1-x^2), `,

>    `z=-sqrt(1-x^2-y^2)..sqrt(1-x^2-y^2),grid=[k,k],spaces =[0,0] ),k=1..10)],`,

>    `insequence = true);`,

>    ` `,

>    `#this one takes 45 seconds on a Pentium60`,

>    `int1:=display3d([seq(intdraw3d(x=0..1 , y=-sqrt(1-x^2) ..sqrt(1-x^2) , `,

>    `z=0..x , grid = [5,5], spaces=[k/10,0]), k=0..9)], insequence = true):`,

>    `int2:=display3d([seq(intdraw3d(x=0..1 , y=-sqrt(1-x^2) ..sqrt(1-x^2) ,`,

>    ` z=0..x , grid = [5,5], spaces=[1,k/10]), k=0..9)], insequence = true):`,

>    `int3:=display3d([seq(intdraw3d(x=0..1 , y=-sqrt(1-x^2) ..sqrt(1-x^2) ,`,

>    ` z=0..x , grid = [5,5], spaces=[1-k/10,1]), k=0..9)], insequence = true):`,

>    `int4:=display3d([seq(intdraw3d(x=0..1 , y=-sqrt(1-x^2) ..sqrt(1-x^2) , `,

>    `z=0..x , grid = [5,5], spaces=[0,1-k/10]), k=0.10)], insequence = true):`,

>    `display3d([int1, int2, int3, int4],insequence = true, orientation = [-134,62]);` ):

>    `help/text/intdraw`:=TEXT(

>    `FUNCTION: asu[intdraw]   -creates a picture of the region of a`,

>    `                          two-dimentional integral`,

>    ` `,

>    `CALLING SEQUENCE:`,

>    `     intdraw(boundaries);`,

>    `     intdraw(boundaries, intdraw options, plot options);`,

>    ` `,

>    `PARAMETERS:`,

>    `boundaries     -two 2D integral boundaries written as `,

>    `                var = Lower Limit..Upper Limit.`,

>    `                Outer integral must be the first `,

>    `                argument, then inner integral.`,

>    `  `,

>    `INTDRAW OPTIONS:`,

>    `grid   -used to vary number of columns; for polar `,

>    `        coordinates, grid's second argument is used `,

>    `        to vary curvature of columns as well. Numbers `,

>    `        entered into grid may not always correlated to number `,

>    `        of columns shown on graph. Default is grid=[15,15].`,

>    ` `,

>    `spaces -used to vary spacing between columns or boxes. `,

>    `        Spaces arguments must range from 0 to 1. Default is `,

>    `        spaces=[.3,0]. `,

>    `SYNOPSIS:`,

>    `-for Cartesian coordinates, variables used must be x, and y.`,

>    `-for polar coordinates, variables used must be r, and theta.`,

>    `-scaling (plot option) default in intdraw is CONSTRAINED`,

>    `-labels (plot option) default in intdraw is [x,y]`,

>    `-these defaults were choosen because they produced the nicest and `,

>    ` most informative pictures, they may be changed easily in the plot `,

>    ` window or in the intdraw calling statement (see examples bellow)`,

>    ` `,

>    `#examples`,

>    `intdraw(x=-1..1, y=-sqrt(1-x^2)..sqrt(1-x^2),spaces =[.5], color = blue, `,

>    `axes = BOX);`,

>    `intdraw(x=-1..1, y=-sqrt(1-x^2)..sqrt(1-x^2),spaces =[.3,.3],color = yellow);`,

>    `intdraw(r= 0..1, theta=0..2*Pi,grid = [3,25]); `,

>    ` `,

>    `region:=plot([3,t,t=0..3]),plot([t,3,t=-3..3]),plot([t,-t,t=-3..-sqrt(2)]),`,

>    `plot([2*cos(t),2*sin(t),t=0..3*Pi/4]):`,

>    ` `,

>    `region:=plot([3,t,t=0..3]),plot([t,3,t=-3..3]),plot([t,-t,t=-3..-sqrt(2)]),`,

>    `plot([2*cos(t),2*sin(t),t=0..3*Pi/4]):`,

>    ` `,

>    `int1:=intdraw(theta= 0..Pi/4,r=2..3/cos(theta), color = blue):`,

>    `int2:=intdraw(theta= Pi/4..3*Pi/4,r=2..3/sin(theta), color = green):`,

>    `display([int1,int2,region]);`,

>    ` `,

>    `inta:=intdraw(r=2..3, theta = 0..3/4*Pi, grid = 4,color = green):`,

>    `intb:=intdraw(r=3..3*sqrt(2), theta = arccos(3/r)..arcsin(3/r),`,

>    `grid = [10,25], color = blue):`,

>    `intc:=intdraw(r=3..3*sqrt(2), theta = Pi-arcsin(3/r)..3/4*Pi, grid = 6,`,

>    `color = red): `,

>    `display([inta,intb,intc,region]);`):

>   

Examples in two dimensions

Minimal syntax

>    intdraw(x=0..1,y=x^2..x);

[Maple Plot]

Overlaying the outline of the region, more slices, using color

>    region0:=plot([x,x^2],x=0..1,thickness=3):
display(region0,
        intdraw(x=0..1,y=x^2..x,grid=23,color=blue));

[Maple Plot]

Matt's orignal favorite region, leading to common mistake, featured in the article
"
3D-graphics for iterated integrals" , MAPLE-Tech, 4 no.1, (1997) pp. 92-98.
http://math.asu.edu/~kawski/preprints/97mapletech.pdf

>    region:=display(
        pointplot([[2,0],[3,0],[3,3],[-3,3],[-sqrt(2),sqrt(2)]],
                  style=line),
        plot([t,3,t=-3..3]),
        plot([t,-t,t=-3..-sqrt(2)]),
        plot([2*cos(t),2*sin(t),t=0..3*Pi/4]),
        thickness=3,scaling=constrained):
region;

[Maple Plot]

>    int1:=intdraw(theta= 0..Pi/4,r=2..3/cos(theta), color = blue):
int2:=intdraw(theta= Pi/4..3*Pi/4,r=2..3/sin(theta), color = green):
display([int1,int2,region]);

[Maple Plot]

>    inta:=intdraw(r=2..3, theta = 0..3/4*Pi,
              grid = 4,color = green):
intb:=intdraw(r=3..3*sqrt(2), theta = arccos(3/r)..arcsin(3/r),
              grid = [10,25], color = blue):
intc:=intdraw(r=3..3*sqrt(2), theta = arcsin(3/r)..3/4*Pi,
              grid = 6, color = red):
display([inta,intb,intc,region]);

[Maple Plot]

>    inta:=intdraw(r=2..3, theta = 0..3/4*Pi, grid = 4,color = green):
intb:=intdraw(r=3..3*sqrt(2), theta = arccos(3/r)..arcsin(3/r),
              grid = [10,25], color = blue):
intc:=intdraw(r=3..3*sqrt(2), theta = Pi-arcsin(3/r)..3/4*Pi,
              grid = 6, color = red):
display([inta,intb,intc,region]);

[Maple Plot]

>   

Examples in three dimensions

It is not always triangles in this triangular pyramid

>    pyra:=pointplot3d([
   [0,0,0],[0,1,0],[1,1,0],[1,0,0],[0,0,0],[0,0,1],
   [0,1,1],[1,1,1],[1,0,1],[0,0,1],[0,0,0],[0,1,0],
   [0,1,1],[1,1,1],[1,1,0],[1,0,0],[1,0,1]],
       style=line,color=black,thickness=1),
   pointplot3d([
   [0,1,1],[1,0,1],[1,1,1],[0,1,1],[1,0,0],[1,1,1],
   [1,0,1],[1,0,0]],
       style=line,color=black,thickness=3):
display([pyra],orientation=[-125,70]);

[Maple Plot]

>    display([pyra,
        intdraw3d(x=0..1,y=1-x..1,z=y..1,
          grid=[7,31,31],spaces=[0.95,0,0],
          shading=ZHUE,orientation=[-125,70],
          axes=frame,tickmarks=[2,2,2])]);

[Maple Plot]

>    display([pyra,
        intdraw3d(x=0..1,y=1-x..1,z=y..1,
          grid=[31,7,31],spaces=[0,0.95,0],
          shading=ZHUE,orientation=[-125,70],
          axes=frame,tickmarks=[2,2,2])]);

[Maple Plot]

>    intdraw3d(rho=0..2,theta=0..2*Pi,phi=0..Pi/6,
          grid=[12,12,12],spaces=[0.1,0.3,0.7],
          shading=ZHUE,orientation=[80,75]);

[Maple Plot]

>    intdraw3d(x=-1..0,y=-sqrt(1-x^2)..sqrt(1-x^2),z=-x..0,
          grid=[10,20]);

[Maple Plot]

>    intdraw3d(z=-1..1,x=-sqrt(1-z^2)..sqrt(1-z^2),
          y=-sqrt(1-x^2-z^2)..sqrt(1-z^2-x^2),
          spaces=[0.1,0.1], style = PATCHNOGRID,grid=[20,20]);

[Maple Plot]

cylindrical coordinates examples

>    intdraw3d(theta=0..2*Pi,r=0..1,z=sqrt(3)*r..sqrt(4-r^2),
          grid=[24,9,13],spaces=[0,0,0.95],
          axes=none,orientation=[-50,70]);

[Maple Plot]

>    intdraw3d(r=3..5,theta=0..2*Pi,z=-sqrt(1-(4-r)^2).. sqrt(1-(4-r)^2),
          grid = [7,12 ], axes = none,orientation=[-140,60] );

[Maple Plot]

spherical coordinates examples

>    intdraw3d(rho=0..1,phi=0..Pi,theta=0..2*Pi,
          grid=[1],spaces=[.5,.5]);

[Maple Plot]

>    intdraw3d(rho=0..1,theta=0..2*Pi,phi=0..Pi,
          grid=[1,13,13],spaces=[0,0.4,0.4]);

[Maple Plot]

movie examples     (may take a while)

>    display([seq(
    intdraw3d(x=-1..1,y=-sqrt(1-x^2)..sqrt(1-x^2),
              z=-sqrt(1-x^2-y^2)..sqrt(1-x^2-y^2),
              grid=[k,k,k],spaces =[0,0],axes=none),
       k=1..13)],insequence = true,
       title=`This is an animation. Play it.`,
       titlefont=[TIMES,BOLD,16]);

[Maple Plot]

>    display3d([
     seq(intdraw3d(rho=0..2,theta=0..2*Pi,phi=0..Pi/6,
              grid=[9,24,5],spaces=[k/10,0],axes=NONE,title=` `),k=0..9),
     seq(intdraw3d(rho=0..2,theta=0..2*Pi,phi=0..Pi/6,
              grid=[9,24,5],spaces=[0,0,1-k/10],axes=NONE,title=` `),k=0..9)
     ],insequence = true,orientation=[60,75],shading=ZHUE,
       title=`This is an animation. Play it.`,
       titlefont=[TIMES,BOLD,16]);

[Maple Plot]

1994: "this one takes 45 seconds on a Pentium60"

>    display([
    seq(intdraw3d(x=0..1,y=-sqrt(1-x^2) ..sqrt(1-x^2),z=0..x,
           grid=[11,11],spaces=[k/10,0],axes=none),k=0..9),
    seq(intdraw3d(x=0..1,y=-sqrt(1-x^2)..sqrt(1-x^2),z=0..x,
           grid=[11,11],spaces=[1,k/10],axes=none),k=0..9),
    seq(intdraw3d(x=0..1,y=-sqrt(1-x^2)..sqrt(1-x^2),z=0..x,
           grid = [11,11], spaces=[1-k/10,1],axes=none),k=0..9),
    seq(intdraw3d(x=0..1,y=-sqrt(1-x^2)..sqrt(1-x^2),z=0..x,
           grid = [11,11], spaces=[0,1-k/10],axes=none),k=0..10)
    ],insequence = true,orientation = [-134,62],
       title=`This is an animation. Play it.`,
       titlefont=[TIMES,BOLD,16]);

[Maple Plot]

>   

>   

start working here (after executing the second to top section)

>    intdraw(x=2..3,y=1/x..sqrt(x));

[Maple Plot]

>   

>   

>   

>