2.10.11 Plotting ThreeDimensional Surfaces
By giving an appropriate list of graphics primitives, you can represent essentially any threedimensional object in Mathematica with Graphics3D. You can represent threedimensional surfaces with Graphics3D by giving explicit lists of polygons with adjacent edges.
If you need to represent arbitrary surfaces which can fold over and perhaps intersect themselves, there is no choice but to use explicit lists of polygons with Graphics3D, as ParametricPlot3D does.
However, there are many cases in which you get simpler surfaces. For example, Plot3D and ListPlot3D yield surfaces which never fold over, and have a definite height at every , point. You can represent simple surfaces like these in Mathematica without giving an explicit list of polygons. Instead, all you need do is to give an array which specifies the height at every point in an , grid. The graphics object SurfaceGraphics[array] represents a surface constructed in this way.
Threedimensional graphics objects.
Here is a array of values.
In[1]:= moda = Table[Mod[i, j], {i, 4}, {j, 4}]
Out[1]=
This uses the array to give the height of each point on the surface.
In[2]:= Show[SurfaceGraphics[moda]]
Out[2]=
Both Plot3D and ListPlot3D work by creating SurfaceGraphics objects.
Converting between representations of surfaces.
If you apply Graphics3D to a SurfaceGraphics object, Mathematica will generate a Graphics3D object containing an explicit list of polygons representing the surface in the SurfaceGraphics object. Whenever you ask Mathematica to combine two SurfaceGraphics objects together, it automatically converts them both to Graphics3D objects.
Here is a surface represented by a SurfaceGraphics object.
In[3]:= Plot3D[(1  Sin[x]) (2  Cos[2 y]), {x, 2, 2}, {y, 2, 2}]
Out[3]=
Here is another surface.
In[4]:= Plot3D[(2 + Sin[x]) (1 + Cos[2 y]), {x, 2, 2}, {y, 2, 2}]
Out[4]=
Mathematica shows the two surfaces together by converting each of them to a Graphics3D object containing an explicit list of polygons.
In[5]:= Show[%, %%]
Out[5]=
Mesh options in SurfaceGraphics.
When you create a surface using SurfaceGraphics, the default is to draw a rectangular mesh on the surface. As discussed in Section 1.9.6, including this mesh typically makes it easier for one to see the shape of the surface. You can nevertheless get rid of the mesh by setting the option Mesh > False. You can also set the option MeshStyle to a list of graphics directives which specify thickness, color or other properties of the mesh lines.
A SurfaceGraphics object contains an array of values which specify the height of a surface at points in an , grid. By setting the option MeshRange, you can give the range of original and coordinates that correspond to the points in this grid. When you use Plot3D[f, x, xmin, xmax, y, ymin, ymax] to generate a SurfaceGraphics object, the setting MeshRange > xmin, xmax, ymin, ymax is automatically generated. The setting for MeshRange is used in labeling the and axes in surface plots, and in working out polygon coordinates if you convert a SurfaceGraphics object to an explicit list of polygons in a Graphics3D object.
Settings for the ClipFill option.
The option PlotRange works for SurfaceGraphics as it does for other Mathematica graphics objects. Any parts of a surface that lie outside the range of coordinates defined by PlotRange will be "clipped". The option ClipFill allows you to specify what should happen to the parts of a surface that are clipped.
Here is a threedimensional plot in which the top and bottom of the surface are clipped. With the default setting for ClipFill, the clipped parts are shown as they would be if they were part of the actual surface.
In[6]:= Plot3D[Sin[x y], {x, 0, 3}, {y, 0, 3}, PlotRange > {.5, .5}]
Out[6]=
With ClipFill>None, parts of the surface which are clipped are left out, so that you can "see through" the surface there. Mathematica always leaves out parts of the surface that correspond to places where the value of the function you are plotting is not a real number.
In[7]:= Show[%, ClipFill > None]
Out[7]=
This makes the bottom clipped face white (gray level 1), and the top one black.
In[8]:= Show[%, ClipFill > {GrayLevel[1], GrayLevel[0]}]
Out[8]=
Whenever Mathematica draws a surface, it has to know not only the height, but also the color of the surface at each point. With the default setting Lighting > True, Mathematica colors the surface using a simulated lighted model. However, with Lighting > False, Mathematica uses a "color function" to determine how to color the surface.
The default color function takes the height of the surface, normalized to run from 0 to 1, and colors each part of the surface with a gray level corresponding to this height. There are two ways to change the default.
First, if you set the option ColorFunction > c, then Mathematica will apply the function c to each height value to determine the color to use at that point. With ColorFunction > Hue, Mathematica will for example color the surface with a range of hues.
Specifying functions for coloring surfaces.
With Lighting > False, the default is to color surfaces with gray scales determined by height.
In[9]:= exp = Plot3D[Exp[Sqrt[x^2 + y^2]], {x, 2, 2}, {y, 2, 2}, Lighting > False]
Out[9]=
This defines a function which maps alternating ranges of values into black and white.
In[10]:= stripes[f_] := If[Mod[f, 1] > 0.5, GrayLevel[1], GrayLevel[0]]
This shows the surface colored with black and white stripes.
In[11]:= Show[exp, ColorFunction > (stripes[5 #]&)]
Out[11]=
The second way to change the default coloring of surfaces is to supply an explicit second array along with the array of heights. ColorFunction is then applied to the elements of this second array, rather than the array of heights, to find the color directives to use. In the second array, you can effectively specify the value of another coordinate for each point on the surface. This coordinate will be plotted using color, rather than position.
You can generate an array of color values automatically using Plot3D[f, s, ... ]. If you give the array explicitly in ListPlot3D or SurfaceGraphics, you should realize that with an array of heights, you need an array to specify colors. The reason is that the heights are specified for points on a grid, whereas the colors are specified for squares on the grid.
When you supply a second function or array to Plot3D, ListPlot3D, and so on, the default setting for the ColorFunction option is Automatic. This means that the function or array should contain explicit Mathematica color directives, such as GrayLevel or RGBColor. However, if you give another setting, such as ColorFunction > Hue, then the function or array can yield pure numbers or other data which are converted to color directives when the function specified by ColorFunction is applied.
Specifying arrays of colors for surfaces.
This plots a surface with gray level determined by the coordinate.
In[12]:= Plot3D[{Sin[x] Sin[y]^2, GrayLevel[y/3]}, {x, 0, 3}, {y, 0, 3}]
Out[12]=
This puts a random gray level in each grid square. Notice that the array of grid squares is , whereas the array of grid points is .
In[13]:= ListPlot3D[ Table[i/j, {i, 10}, {j, 10}], Table[GrayLevel[Random[ ]], {i, 9}, {j, 9}] ]
Out[13]=
