Drawing Mathematical Solids

Programs are described which draw solids whose bounding surfaces are defined by equations.

Each face of a solid we wish to draw is a surface bounded by curves which are the intersection of the surface with other faces of the solid. In order to draw the solid, we will need parametric descriptions for these faces. The method we use [TaFr94] gives natural coordinates for a region by interpolating linearly between opposite bounding curves. Parametric equations for the region bounded by y = f1(x) below, y = f2(x) above, over the interval a ≤ x ≤ b are
		x = s					a ≤ s ≤ b
		y = t f2(s) + (1 - t)f1(s)	0 ≤ t ≤ 1.

Clear[x,y,picture1]
x := s
y := t Sin[.8s]^2 + (1-t)(Abs[Cos[2.2x]] - 1 + x/4)
picture1 = ParametricPlot3D[{x,y,0}, {s,0,3Pi/4}, {t,0,1}, 
PlotPoints->{24,10},
	ViewPoint->{0,0,1000}, Axes->{True,True,False}, 
	AxesLabel->{FontForm[X,{"Times-Bold",12}], 
		FontForm[Y,{"Times-Bold",12}],""},
		PlotRange->{{-.1,3.3},{-.9,1.1},{0,1}},
		Ticks->None, DisplayFunction->Identity];
Show[picture1, Graphics3D[Text["y = f (x)",{2.8,.1,0}]],
	Graphics3D[Text[Subscript[1],{2.91,.04,0}]],
	Graphics3D[Text["y = f (x)",{2.8,.9,0}]],
	Graphics3D[Text[Subscript[2],{2.91,.84,0}]],
DisplayFunction->$DisplayFunction];

The solids we wish to draw are those typically used as regions of integration for triple integrals. Suppose the solid is described by the inequalities a ≤ x ≤ b, g1(x) ≤ y ≤ g2(x), and h1(x,y) ≤ z ≤ h2(x,y). The following program draws this region.

Clear[a,b,g1,g2,h1,h2,px,py,pz]
(*left*)		a := 0
(*right*)		b := 2Pi
(*front*)		g1[x_] := 2Abs[Sin[x]]
(*back*)		g2[x_] := 2Pi - 2Abs[Sin[x]]
(*bottom*)		h1[x_,y_] := 3Abs[Sin[x/2]] Abs[Sin[y]]
(*top*)			h2[x_,y_] := 5 - 2Sin[x]^2 Cos[y]
					px := 37
(*PlotPoints*)		py := 11
					pz := 15

Show[
(*bottom*)  ParametricPlot3D[
	{x,y g2[x]+(1-y)g1[x],h1[x,y g2[x]+(1-y)g1[x]]},
	{x,a,b}, {y,0,1}, PlotPoints->{px,py}, 
	DisplayFunction->Identity],
(*top*)  ParametricPlot3D[
	{x,y g2[x]+(1-y)g1[x],h2[x,y g2[x]+(1-y)g1[x]]},
	{x,a,b}, {y,0,1}, PlotPoints->{px,py}, 
	DisplayFunction->Identity],
(*front*)  ParametricPlot3D[
	{x,g1[x],z h2[x,g1[x]]+(1-z)h1[x,g1[x]]},
	{x,a,b}, {z,0,1}, PlotPoints->{px,pz}, 
	DisplayFunction->Identity],
(*back*)  ParametricPlot3D[
	{x,g2[x],z h2[x,g2[x]]+(1-z)h1[x,g2[x]]},
	{x,a,b}, {z,0,1}, PlotPoints->{px,pz}, 
	DisplayFunction->Identity],
(*left*)  ParametricPlot3D[
	{a,y,z h2[a,y]+(1-z)h1[a,y]},
	{y,g1[a],g2[a]+10^-9}, {z,0,1}, PlotPoints->{py,pz}, 
	DisplayFunction->Identity],
(*right*)  ParametricPlot3D[
	{b,y,z h2[b,y]+(1-z)h1[b,y]},
	{y,g1[b],g2[b]+10^-9}, {z,0,1}, PlotPoints->{py,pz}, 
	DisplayFunction->Identity],
DisplayFunction->$DisplayFunction];

Let us look at how this program works. There are six faces which the Show command pastes together at their edges. To illustrate the description of a face of the solid, consider the two-parameter set of equations for the front surface. Its top bounding curve is the intersection of the front surface y = g1(x) with the top surface z = h2(x,y). Eliminating y we obtain the set of parametric equations {x = x, y = g1(x), z = h2(x,g1(x))} for the top curve. Likewise for its bottom curve {x = x, y = g1(x), z = h1(x,g1(x))}. Thus the parametric equations for the front face using the previously mentioned technique for describing surfaces parametrically are
		x = x
		y = g1(x)					a ≤ x ≤ b
		z = z h2(x,g1(x)) + (1 - z) h1(x,g1(x))		0 ≤ z ≤ 1.
The parameters were mnemonically called x,y,z and the corresponding PlotPoints settings px,py,pz. Care was taken to link the PlotPoints settings so that the surface grids line up at the edge of adjoining surfaces. The program is quite robust; it works even if, for example, the top and bottom surfaces intersect or are accidently interchanged. However, Mathematica does not allow degenerate parameter intervals; hence the 10^-9 terms in the program for the (*left*) and (*right*) faces in case g1(a) = g2(a) or g1(b) = g2(b). Another solid can be drawn by changing the assignments (definitions) at the beginning of the program.

Exercises
1.  Modify the program to leave off the front surface. This is sometimes useful to view hidden surfaces.
2.  Modify the program to leave off the right half of the top surface without changing the grid spacing. 
3.  Modify the program to draw only the (p/q)th left part of the top surface without affecting the grid spacing. How should px be chosen?
4.  Use the program to plot some regions of integration for triple integrals in rectangular coordinates found in your favorite calculus textbook.
5.  Experiment with some (nearly) random choices for a, b, g1, g2, h1, and h2.
6.  Write a Mathematica package for the program with the option to skip faces.

SOLIDS INSIDE A CYLINDER DESCRIBED PARAMETRICALLY

The procedure is similar, but shorter, for a solid inside a cylinder described parametrically. The parametric equations for a radially simple region bounded by x = f1(t), y = f2(t) for           t1 ≤ t ≤ t2 are
		x = s f1(t)		0 ≤ s ≤ 1			
		y = s f2(t) 		t1 ≤ t ≤ t2.

Clear[x,y,picture3]
x := s (3 + Cos[4t]) Cos[t]
y := s 2Sin[t]^3
picture3 = ParametricPlot3D[{x,y,0}, {s,0,1}, {t,0,2Pi},
	ViewPoint->{0,0,1000}, Axes->{True,True,False}, 
	PlotPoints->{8,49}, AxesLabel->{FontForm[X,{"Times-Bold",12}],
	FontForm[Y,{"Times-Bold",12}],""}, Ticks->None,
	PlotRange->{{-4.5,4.5},{-2.2,2.2},{0,1}},
		DisplayFunction->Identity];
Show[picture3, Graphics3D[Text["x = f (t)",{3.1,1.55,0}]],
	Graphics3D[Text[Subscript[1],{3.4,1.43,0}]],
	Graphics3D[Text["y = f (t)",{3.1,.9,0}]],
	Graphics3D[Text[Subscript[2],{3.4,.78,0}]],
DisplayFunction->$DisplayFunction];

The next program shows a solid inside the cylinder
		x = f1(t)		
		y = f2(t)  	a ≤ t ≤ b
for h1(x,y) ≤ z ≤ h2(x,y). The top edge is emphasized with an additional one-parameter plot.

Clear[x,y,a,b,h1,h2,pt,pr,pz]
(*sides*)		x := (2 + Cos[4t]) Cos[t]	
				y := (2 + Cos[4t]) Sin[t]
(*top*)			h2[x_,y_] := 12 + x^2/2 + y^3/4	
(*bottom*)		h1[x_,y_] := 0
				a := 0
				b := 2Pi
					pt := 65
(*PlotPoints*)		pr := 15	
					pz := 20

Show[
(*top*) ParametricPlot3D[
	{r x,r y,h2[r x,r y]}, {t,a,b}, {r,0,1},
	PlotPoints->{pt,pr}, DisplayFunction->Identity],
(*bottom*) ParametricPlot3D[
	{r x,r y,h1[r x,r y]}, {t,a,b}, {r,0,1},
	PlotPoints->{pt,pr}, DisplayFunction->Identity],
(*sides*) ParametricPlot3D[
	{x,y,z h1[x,y]+(1-z) h2[x,y]}, {t,a,b}, {z,0,1},
	PlotPoints->{pt,pz}, DisplayFunction->Identity],
(*edge*) ParametricPlot3D[	
	{x,y,h2[x,y],Thickness[.005]}, {t,a,b}, 
	PlotPoints->pt, DisplayFunction->Identity],
DisplayFunction->$DisplayFunction];

Exercises
1.  Modify the previous program to add the cone z = 3Sqrt[x^2 + y^2]  - 5 to the bottom of the solid.
2.  The edge curve was obtained by taking r = 1 in the parametric equations for the top surface. Obtain the edge curve by taking z = 1 in the equations for the lateral surface.
3.  Modify the program to emphasize the bottom edge also.  
4.  Draw the rectangular solid -4 ≤ x ≤ 4, -4 ≤ y ≤ 4, -6 ≤ z ≤ -2  and attach it as the base for the solid of exercise 1.
5.  Modify the program to allow for an inner bounding cylinder. Test it with an example.